2018年8月9日 星期四

[C++] Build Services by window

It can be started automatically at system boot, by a user through the Services control panel applet, or by an application that uses the service functions.Then Create the Service Control Manager begin.

Now we need calling process to run service.
int WINAPI WinMain(HINSTANCE hInstance,
 HINSTANCE hPrevInstance,
 PSTR szCmdLine,
 int iCmdShow)
{
 SERVICE_TABLE_ENTRY ServiceTables[] =
 {
  { (LPWSTR)SERVICE_NAME,
  ((LPSERVICE_MAIN_FUNCTION)ServiceMaines) },
 { NULL, NULL }
 };
 
 if (StartServiceCtrlDispatcher(ServiceTables) == FALSE)
 {
  return GetLastError();
 }
}

In the ServiceMaines process, and register our service control handler with the SCM.
VOID WINAPI ServiceMaines(DWORD argc, LPTSTR *argv)
{
 DWORD Status = E_FAIL;

 StatusHandles = RegisterServiceCtrlHandler(SERVICE_NAME, ServiceCtrlHandler);
 //StatusHandles = RegisterServiceCtrlHandlerEx(SERVICE_NAME, ServiceCtrlHandler, this);

 if (StatusHandles == NULL)
 {
  return void();
 }

 ZeroMemory(&StatusService, sizeof(StatusService));
 StatusService.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
 StatusService.dwControlsAccepted = 0;
 StatusService.dwCurrentState = SERVICE_START_PENDING;
 StatusService.dwWin32ExitCode = 0;
 StatusService.dwServiceSpecificExitCode = 0;
 StatusService.dwCheckPoint = 0;

 if (SetServiceStatus(StatusHandles, &StatusService) == FALSE)
 {
  OutputDebugString(_T(
   "Service controller set Service Status fail"));
 }

 g_ServiceStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
 if (g_ServiceStopEvent == NULL)
 {
  StatusService.dwControlsAccepted = 0;
  StatusService.dwCurrentState = SERVICE_STOPPED;
  StatusService.dwWin32ExitCode = GetLastError();
  StatusService.dwCheckPoint = 1;

  if (SetServiceStatus(StatusHandles, &StatusService) == FALSE)
  {
   OutputDebugString(_T(
    "Create a service stop set Service Status fail"));
  }
  return void();
 }

 StatusService.dwControlsAccepted = SERVICE_ACCEPT_STOP;
 StatusService.dwCurrentState = SERVICE_RUNNING;
 StatusService.dwWin32ExitCode = 0;
 StatusService.dwCheckPoint = 0;

 if (SetServiceStatus(StatusHandles, &StatusService) == FALSE)
 {
  OutputDebugString(_T(
   "SetServiceStatus returned error"));
 }

 HANDLE hThread = CreateThread(NULL, 0, ServiceWorkerThread, NULL, 0, NULL);

 WaitForSingleObject(hThread, INFINITE);

 CloseHandle(g_ServiceStopEvent);

 StatusService.dwControlsAccepted = 0;
 StatusService.dwCurrentState = SERVICE_STOPPED;
 StatusService.dwWin32ExitCode = 0;
 StatusService.dwCheckPoint = 3;

 if (SetServiceStatus(StatusHandles, &StatusService) == FALSE)
 {
  OutputDebugString(_T(
   "SetServiceStatus returned error"));
 }

}

By the Handler
VOID WINAPI ServiceCtrlHandler (DWORD CtrlCode)
{
    switch (CtrlCode) 
 {
     case SERVICE_CONTROL_STOP :
 
        if (StatusService.dwCurrentState != SERVICE_RUNNING)
           break;

        StatusService.dwControlsAccepted = 0;
        StatusService.dwCurrentState = SERVICE_STOP_PENDING;
        StatusService.dwWin32ExitCode = 0;
        StatusService.dwCheckPoint = 4;
 
        if (SetServiceStatus (StatusHandles, &StatusService) == FALSE)
        {
            OutputDebugString(_T(
              "SetServiceStatus returned error"));
        }
 
        // This will signal the worker thread to start shutting down
        SetEvent (g_ServiceStopEvent);
 
        break;
 
     default:
         break;
    }
}

The Service Thread
DWORD WINAPI ServiceSubThread(LPVOID lpParam)
{
 OutputDebugString(_T("================= Service Thread Start========================");
 //Do something..
 OutputDebugString(_T("================= Service Thread End========================");
}

沒有留言:

張貼留言