VC編寫Windows服務程序

#include <stdio.h>

#include <Windows.h>

#include <tchar.h>

 

TCHAR szServiceName[] = _T("MyTestService");

DWORD dwThreadID;

HANDLE hEvent = INVALID_HANDLE_VALUE;

SERVICE_STATUS status;

SERVICE_STATUS_HANDLE hServiceStatus;

 

void Init();

BOOL IsServiceInstalled();

BOOL InstallService();

BOOL UninstallService();

BOOL ServiceCtrlStart();

BOOL ServiceCtrlStop();

void WINAPI ServiceMain();

void WINAPI ServiceStrl(DWORD dwOpcode);

void LogEvent(LPCTSTR pszFormat, ...);

 

//Usuage

// Install service:

//TestService.exe /install

// Uninstall service:

//TestService.exe /uninstall

// Start service:

//TestService.exe /start

// Stop service:

//TestService.exe /stop

 

int main( int argc, char* argv[] )

{

     Init();

 

     dwThreadID = ::GetCurrentThreadId();

 

     SERVICE_TABLE_ENTRY st[] =

     {

         { szServiceName, (LPSERVICE_MAIN_FUNCTION)ServiceMain },

         { NULL, NULL }

     };

 

     LPSTR lpCmdLine = argv[1];

 

     if ( argc == 2 )

     {

         BOOL bRet;

 

         if (stricmp(lpCmdLine, "/install") == 0)

         {

              bRet = InstallService();

              if ( bRet == TRUE )

              {

                   printf( "Install service %s success", szServiceName );

              }else

              {

                   printf( "Install service %s failed", szServiceName );

              }

         }

         else if (stricmp(lpCmdLine, "/uninstall") == 0)

         {

              bRet = UninstallService();

              if ( bRet == TRUE )

              {

                   printf( "Uninstall service %s success", szServiceName );

              }else

              {

                   printf( "Uninstall service %s failed", szServiceName );

              }

         }else if (stricmp(lpCmdLine, "/start") == 0)

         {

              bRet = ServiceCtrlStart();

              if ( bRet == TRUE )

              {

                   printf( "Start service %s success", szServiceName );

              }else

              {

                   printf( "Start service %s failed", szServiceName );

              }

         }else if (stricmp(lpCmdLine, "/stop") == 0)

         {

              bRet = ServiceCtrlStop();

              if ( bRet == TRUE )

              {

                   printf( "Stop service %s success", szServiceName );

              }else

              {

                   printf( "Stop service %s failed", szServiceName );

              }

         }

         else

         {

              if (!::StartServiceCtrlDispatcher(st))

              {

                   LogEvent(_T("Register Service Main Function Error!"));

              }

         }

     }else

     {

         if (!::StartServiceCtrlDispatcher(st))

         {

              LogEvent(_T("Register Service Main Function Error!"));

         }

     }

     return 0;

}

 

//初始化相關結構

void Init()

{

     hServiceStatus = NULL;

     status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;

     status.dwCurrentState = SERVICE_STOPPED;

     status.dwControlsAccepted = SERVICE_ACCEPT_STOP;

     status.dwWin32ExitCode = 0;

     status.dwServiceSpecificExitCode = 0;

     status.dwCheckPoint = 0;

     status.dwWaitHint = 0;

}

 

//服務主線程函數,既用戶選擇開啓服務時調用的函數

void WINAPI ServiceMain()

{

     // Register the control request handler

     status.dwCurrentState = SERVICE_START_PENDING;

     status.dwControlsAccepted = SERVICE_ACCEPT_STOP;

 

&a, mp;n, bsp;   LogEvent(_T("ServiceMain"));

 

     //註冊服務控制

     hServiceStatus = RegisterServiceCtrlHandler(szServiceName, ServiceStrl);

     if (hServiceStatus == NULL)

     {

         LogEvent(_T("Handler not installed"));

         return;

     }

     SetServiceStatus(hServiceStatus, &status);

 

     //如下代碼可以爲啓動服務前的準備工作

     hEvent = ::CreateEvent( NULL, TRUE, FALSE, NULL );

     if ( hEvent == NULL )

     {

         status.dwCurrentState = SERVICE_STOPPED;

         SetServiceStatus(hServiceStatus, &status);

         LogEvent(_T("Failure to start service"));

         return;

     }

     //

 

     //更改服務狀態爲啓動

     status.dwWin32ExitCode = S_OK;

     status.dwCheckPoint = 0;

     status.dwWaitHint = 0;

     status.dwCurrentState = SERVICE_RUNNING;

     SetServiceStatus(hServiceStatus, &status);

 

     //等待用戶選擇停止服務,

     //當然你也可以把你的服務代碼用線程來執行,

     //此時這裏只需等待線程結束既可。

     while ( WaitForSingleObject( hEvent, 1000 ) != WAIT_OBJECT_0 )

     {

         //模擬服務的運行,應用時將主要任務放於此即可

         LogEvent(_T("Service runing..."));

     }

     //

 

     //停止服務

     status.dwCurrentState = SERVICE_STOPPED;

     SetServiceStatus(hServiceStatus, &status);

     LogEvent(_T("Service stopped"));

}

 

//服務控制函數

void WINAPI ServiceStrl(DWORD dwOpcode)

{

     switch (dwOpcode)

     {

     case SERVICE_CONTROL_STOP:

         status.dwCurrentState = SERVICE_STOP_PENDING;

         SetServiceStatus(hServiceStatus, &status);

         //告訴服務線程停止工作

         ::SetEvent( hEvent );

         LogEvent(_T("want to stopped Service"));

         break;

     case SERVICE_CONTROL_PAUSE:

         break;

     case SERVICE_CONTROL_CONTINUE:

         break;

     case SERVICE_CONTROL_INTERROGATE:

         break;

     case SERVICE_CONTROL_SHUTDOWN:

         break;

     default:

         LogEvent(_T("Bad service request"));

     }

}

 

//判斷服務是否已安裝

BOOL IsServiceInstalled()

{

     BOOL bResult = FALSE;

 

     //打開服務控制管理器

     SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);

 

     if (hSCM != NULL)

     {

         //打開服務

         SC_HANDLE hService = ::OpenService(hSCM, szServiceName, SERVICE_QUERY_CONFIG);

         if (hService != NULL)

         {

              bResult = TRUE;

              ::CloseServiceHandle(hService);

         }

         ::CloseServiceHandle(hSCM);

     }

     return bResult;

}

 

//安裝服務

BOOL InstallService()

{

     if (IsServiceInstalled())

         return TRUE;

 

     //打開服務控制管理器

     SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);

     if (hSCM == NULL)

     {

         return FALSE;

     }

 

     // Get the executable file path

     TCHAR szFilePath[MAX_PATH];

     ::GetModuleFileName(NULL, szFilePath, MAX_PATH);

 

     //創建服務

     SC_HANDLE hService = ::CreateService(

         hSCM,

         szServiceName,

         szServiceName,

         SERVICE_ALL_ACCESS,

         SERVICE_WIN32_OWN_PROCESS,

         SERVICE_AUTO_START, //如果爲SERVICE_DEMAND_START則表示此服務需手工啓動

         SERVICE_ERROR_NORMAL,

         szFilePath,

         NULL,

         NULL,

         _T(""),

         NULL,

         NULL);

 

     if (hService == NULL)

     {

         ::CloseServiceHandle(hSCM);

         return FALSE;

     }

 

     ::CloseServiceHandle(hService);

     ::CloseServiceHandle(hSCM);

     return TRUE;

}

 

//刪除服務

BOOL UninstallService()

{

     if (!IsServiceInstalled())

         return TRUE;

 

     SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);

 

     if (hSCM == NULL)

     {

         return FALSE;

     }

 

     SC_HANDLE hService = ::OpenService(hSCM, szServiceName, SERVICE_STOP | DELETE);

 

     if (hService == NULL)

     {

         ::CloseServiceHandle(hSCM);

         return FALSE;

     }

     SERVICE_STATUS status;

     ::ControlService(hService, SERVICE_CONTROL_STOP, &status);

 

     //刪除服務

     BOOL bDelete = ::DeleteService(hService);

     ::CloseServiceHandle(hService);

     ::CloseServiceHandle(hSCM);

 

     if (bDelete)

         return TRUE;

 

     LogEvent(_T("Service could not be deleted"));

     return FALSE;

}

 

//開啓服務

BOOL ServiceCtrlStart()

{

     BOOL bRet;

     SC_HANDLE hSCM;

     SC_HANDLE hService;

 

     hSCM=OpenSCManager(NULL,NULL,SC_MANAGER_CONNECT);

     if (hSCM!=NULL)

     {

         hService=OpenService( hSCM, szServiceName, SERVICE_START);

         if (hService!=NULL)

         {

              //開始Service

              bRet = StartService(hService,0,NULL);

              CloseServiceHandle(hService);

         }else

         {

              bRet = FALSE;

         }

         CloseServiceHandle(hSCM);

     }else

     {

         bRet = FALSE;

     }

     return bRet;

}

 

//停止服務

BOOL ServiceCtrlStop()

{

     BOOL bRet;

     SC_HANDLE hSCM;

     SC_HANDLE hService;

     SERVICE_STATUS ServiceStatus;

 

     hSCM=OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );

     if (hSCM!=NULL)

     {

         hService=OpenService( hSCM, szServiceName, SERVICE_STOP|SERVICE_QUERY_STATUS );

         if (hService!=NULL)

         {

              QueryServiceStatus( hService, &ServiceStatus );

              if (ServiceStatus.dwCurrentState == SERVICE_RUNNING)

              {

                   bRet = ControlService( hService, SERVICE_CONTROL_STOP, &ServiceStatus );

              }else

              {

                   bRet = FALSE;

              }

              CloseServiceHandle( hService );

         }else

         {

              bRet = FALSE;

         }

         CloseServiceHandle( hSCM );

     }else

     {

         bRet = FALSE;

     }

     return bRet;

}

 

//記錄日記

void LogEvent(LPCTSTR pFormat, ...)

{

     TCHAR    chMsg[256];

     HANDLE hEventSource;

     LPTSTR lpszStrings[1];

     va_list pArg;

 

     va_start(pArg, pFormat);

     _vstprintf(chMsg, pFormat, pArg);

     va_end(pArg);

 

     lpszStrings[0] = chMsg;

 

     hEventSource = RegisterEventSource(NULL, szServiceName);

     if (hEventSource != NULL)

     {

         ReportEvent(hEventSource, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (LPCTSTR*) &lpszStrings[0], NULL);

         DeregisterEventSource(hEventSource);

     }

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章