BOOL CNTService::RemoveService(int nWaitSecond)
{
SC_HANDLE schSCManager; //打开SCM用的句柄
SC_HANDLE schService; //建立SERVICE用的句柄
schSCManager = OpenSCManager( //调用打开SERVICE管理器API
NULL, //机器名称,设置NULL为本地机器
NULL, //数据库名称,NULL为缺省数据库
SC_MANAGER_ALL_ACCESS //希望打开的操作权限,详见MSDN
);
if(schSCManager) //如果打开SERVICE管理器成功
{
schService = OpenService( //获取SERVICE控制句柄的API
schSCManager, //SCM管理器句柄
m_lpServiceName, //SERVICE内部名称,控制名称
SERVICE_ALL_ACCESS); //打开的权限,删除就要全部权限
if(schService) //如果获取SERVICE句柄成功
{
if(ControlService(schService, SERVICE_CONTROL_STOP, &m_ssServiceStatus))
{
//直接向SERVICE发STOP命令,如果能够执行到这里,说明SERVICE正运行
//那就需要停止程序执行后才能删除
Sleep(3000); //等3秒使系统有时间执行STOP命令
while(QueryServiceStatus(schService,&m_ssServiceStatus))
{
//循环检查SERVICE状态
if(m_ssServiceStatus.dwCurrentState == SERVICE_STOP_PENDING)
{
if(nWaitSecond == 0)
break;
nWaitSecond--;
//如果SERVICE还正在执行(PENDING)停止任务
Sleep(1000); //那就等1秒钟后再检查SERVICE是否停止OK
}
else
break; //STOP命令处理完毕,跳出循环
}//循环检查SERVICE状态结束
if(m_ssServiceStatus.dwCurrentState != SERVICE_STOPPED)
{
//如果SERVICE接受STOP命令后还没有STOPPED
CloseServiceHandle(schService); //释放SERVICE控制句柄
CloseServiceHandle(schSCManager); //释放SCM管理器句柄
return FALSE; //那就返回FALSE报错,用GetLastError取错误代码
}
}
//删除指令在这里
if(!DeleteService(schService)) //删除这个SERVICE
{
CloseServiceHandle(schService); //释放SERVICE控制句柄
CloseServiceHandle(schSCManager); //释放SCM管理器句柄
return FALSE; //如果删除失败返回
}
else
CloseServiceHandle(schService); //释放SERVICE控制句柄
}
else
{
//取SERVICE句柄不成功
CloseServiceHandle(schSCManager); //释放SCM管理器句柄
return FALSE; //获取SERVICE句柄失败,或没有找到SERVICE名字返回
}
CloseServiceHandle(schSCManager); //释放SCM管理器句柄
}
else
{
//打开管理器不成功
return FALSE; //打开管理器失败返回
}
return TRUE; //正常删除返回
}
LPTSTR CNTService::GetLastErrorText(LPTSTR lpszBuf, DWORD dwSize)
{
DWORD dwRet;
LPTSTR lpszTemp = NULL;
dwRet = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_ARGUMENT_ARRAY,
NULL,
GetLastError(),
LANG_NEUTRAL,
(LPTSTR)&lpszTemp,
0,
NULL);
//supplied buffer is not long enough
if(!dwRet||((long)dwSize<(long)dwRet+14))
lpszBuf[0] = TEXT('\0');
else
{
lpszTemp[lstrlen(lpszTemp)-2] = TEXT('\0'); //remove cr and newline character
_stprintf(lpszBuf, TEXT("%s (%ld)"), lpszTemp, GetLastError());
}
if(lpszTemp)
LocalFree((HLOCAL)lpszTemp);
return lpszBuf;
}
BOOL CNTService::StartDispatch()
{
SERVICE_TABLE_ENTRY DispatchTable[] =
{
{m_lpServiceName,ServiceMain},
{NULL, NULL}
};//如果只有一个SERVICE就定义成2,如果有
//二个以上的SERVICE在一个文件里,这个
//表就要定义成3维或更多
m_bService = TRUE;
if(!StartServiceCtrlDispatcher(DispatchTable))
{
DWORD vat = GetLastError();
return FALSE;
}
return TRUE;
}
void WINAPI CNTService::ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv)
{
_asm
{
INT 3
}
m_sshServiceStatusHandle =
RegisterServiceCtrlHandler(m_lpServiceName, ServiceHandle);
if(!m_sshServiceStatusHandle)
{
AddToMessageLog(_T("RegisterServiceCtrlHandler Error!"));
return;
}
if(SetSCMStatus(SERVICE_START_PENDING, NO_ERROR,3000))
{
m_pService->dwThreadId = GetCurrentThreadId();
if(m_pService->Initialize())
{
m_pService->Run();
m_pService->UnInitialize();
}
}
SetSCMStatus(SERVICE_STOPPED, NO_ERROR, 0);
}
void WINAPI CNTService::ServiceHandle(DWORD dwControl)
{
switch(dwControl)
{
case SERVICE_CONTROL_STOP:
m_pService->Stop();
SetSCMStatus(SERVICE_STOP_PENDING, NO_ERROR, 3000);
PostThreadMessage(m_pService->dwThreadId, WM_QUIT, 0, 0);
break;
case SERVICE_CONTROL_PAUSE:
m_pService->Pause();
break;
case SERVICE_CONTROL_CONTINUE:
m_pService->Continue();
break;
case SERVICE_CONTROL_INTERROGATE:
break;
default:
break;
}
}
void CNTService::AddToMessageLog(LPCTSTR lpszMsg)
{
TCHAR szMsg[256];
HANDLE hEventSource;
LPCTSTR lpszStrings[2];
if(!m_pService->m_bService)
{
printf("%s",lpszMsg);
return;
}
//Use event logging to log the error.
hEventSource = RegisterEventSource(0, m_lpServiceName);
_stprintf(szMsg, TEXT("\n%s 提示信息: %d"), m_lpServiceDisplayName, GetLastError());
lpszStrings[0] = szMsg;
lpszStrings[1] = lpszMsg;
if(hEventSource != NULL)
{
ReportEvent(hEventSource, // handle of event source
EVENTLOG_INFORMATION_TYPE, //EVENTLOG_SUCCESS, // event type
0, // event category
0, // event ID
NULL, // current user's SID
2, // number of strings in lpszStrings
0, // no bytes of raw data
lpszStrings, // array of error strings
NULL); // no raw data
(VOID)DeregisterEventSource(hEventSource);
}
}
void CNTService::AddToErrorMessageLog(LPCTSTR lpszMsg)
{
TCHAR szMsg[256];
HANDLE hEventSource;
LPCTSTR lpszStrings[2];
if(!m_pService->m_bService)
{
printf("%s",lpszMsg);
return;
}
// Use event logging to log the error.
hEventSource = RegisterEventSource(0, m_lpServiceName);
_stprintf(szMsg, TEXT("\n%s 提示信息: %d"),m_lpServiceDisplayName,GetLastError());
lpszStrings[0] = szMsg;
lpszStrings[1] = lpszMsg;
if(hEventSource != NULL)
{
ReportEvent(hEventSource, // handle of event source
EVENTLOG_ERROR_TYPE, // event type
0, // event category
0, // event ID
NULL, // current user's SID
2, // number of strings in lpszStrings
0, // no bytes of raw data
lpszStrings, // array of error strings
NULL); // no raw data
(VOID)DeregisterEventSource(hEventSource);
}
}
void CNTService::AddToWarningMessageLog(LPCTSTR lpszMsg)
{
TCHAR szMsg[256];
HANDLE hEventSource;
LPCTSTR lpszStrings[2];
if(!m_pService->m_bService)
{
printf("%s",lpszMsg);
return;
}
// Use event logging to log the error.
hEventSource = RegisterEventSource(0, m_lpServiceName);
_stprintf(szMsg, TEXT("\n%s 提示信息: %d"), m_lpServiceDisplayName, GetLastError());
lpszStrings[0] = szMsg;
lpszStrings[1] = lpszMsg;
if(hEventSource != NULL)
{
ReportEvent(hEventSource, // handle of event source
EVENTLOG_WARNING_TYPE, // event type
0, // event category
0, // event ID
NULL, // current user's SID
2, // number of strings in lpszStrings
0, // no bytes of raw data
lpszStrings, // array of error strings
NULL); // no raw data
(VOID)DeregisterEventSource(hEventSource);
}
}
BOOL CNTService::SetSCMStatus(DWORD dwCurrentState,DWORD dwWin32ExitCode,DWORD dwWaitHint)
{
static DWORD dwCheckPoint = 1;
BOOL fResult = TRUE;
if(dwCurrentState == SERVICE_START_PENDING)
m_ssServiceStatus.dwControlsAccepted = 0;
else
m_ssServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
m_ssServiceStatus.dwCurrentState = dwCurrentState;
m_ssServiceStatus.dwWin32ExitCode = dwWin32ExitCode;
m_ssServiceStatus.dwWaitHint = dwWaitHint;
if((dwCurrentState == SERVICE_RUNNING) || (dwCurrentState == SERVICE_STOPPED))
m_ssServiceStatus.dwCheckPoint = 0;
else
m_ssServiceStatus.dwCheckPoint = dwCheckPoint++;
// Report the status of the service to the service control manager.
//
fResult = SetServiceStatus(m_sshServiceStatusHandle, &m_ssServiceStatus);
if(!fResult)
{
AddToMessageLog(TEXT("SetServiceStatus"));
}
return fResult;
}
BOOL CNTService::Initialize()
{
if(!SetSCMStatus(SERVICE_RUNNING, NO_ERROR, 0))
return FALSE;
return TRUE;
}
void CNTService::UnInitialize()
{
}
void CNTService::Stop()
{
}
void CNTService::Pause()
{
}
void CNTService::Continue()
{
}
void CNTService::Run()
{
//在此调用服务的实际程序
//进入消息循环;
MSG msg;
while(GetMessage(&msg,0,0,0))
{
AddToMessageLog(_T("收到消息"));
DispatchMessage(&msg);
}
}