基于visual c++之windows核心编程代码分析(9)实现Windows服务并安装,控制

来源:互联网 发布:vscode github 编辑:程序博客网 时间:2024/05/17 06:22

我们进行Windows编程的时候,经常涉及到Windows服务编程,针对Windows服务我们该怎么编程呢,

我们先来实现一个Windows服务并实现之,请见注释代码分析。

[cpp] view plain copy
  1. /* 头文件 */  
  2. #include <windows.h>  
  3. /* 全局变量 */  
  4. SERVICE_STATUS          SplSrvServiceStatus;   
  5. SERVICE_STATUS_HANDLE   SplSrvServiceStatusHandle;   
  6. /* 函数声明 */  
  7. VOID SvcDebugOut(LPSTR String, DWORD Status);  
  8. VOID WINAPI SplSrvServiceCtrlHandler (DWORD opcode);   
  9. VOID WINAPI SplSrvServiceStart (DWORD argc, LPTSTR *argv);   
  10. DWORD SplSrvServiceInitialization (DWORD argc, LPTSTR *argv,   
  11.                                    DWORD *specificError);   
  12.   
  13. /************************************* 
  14. * VOID WINAPI SplSrvServiceStart (DWORD argc, LPTSTR *argv) 
  15. * 功能    服务启动函数 
  16. * 
  17. * 参数    未使用 
  18. **************************************/  
  19. VOID WINAPI SplSrvServiceStart (DWORD argc, LPTSTR *argv)   
  20. {   
  21.     DWORD status;   
  22.     DWORD specificError;   
  23.     // 填充SERVICE_STATUS 结构  
  24.     SplSrvServiceStatus.dwServiceType        = SERVICE_WIN32;   
  25.     SplSrvServiceStatus.dwCurrentState         
  26.         = SERVICE_START_PENDING;        // 服务在运行  
  27.     SplSrvServiceStatus.dwControlsAccepted     
  28.         = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE;   
  29.     SplSrvServiceStatus.dwWin32ExitCode      = 0;   
  30.     SplSrvServiceStatus.dwServiceSpecificExitCode = 0;   
  31.     SplSrvServiceStatus.dwCheckPoint         = 0;   
  32.     SplSrvServiceStatus.dwWaitHint           = 0;   
  33.     // 注册服务控制请求处理例程  
  34.     SplSrvServiceStatusHandle = RegisterServiceCtrlHandler(   
  35.         "Sample_Srv",   // 服务名,在创建服务时使用了  
  36.         // SERVICE_WIN32_OWN_PROCESS,因此本参数被忽略。  
  37.         SplSrvServiceCtrlHandler);  // 控制请求处理例程,函数名  
  38.   
  39.     if (SplSrvServiceStatusHandle == (SERVICE_STATUS_HANDLE)0)   
  40.     {   
  41.         SvcDebugOut(" [SPLSRV_SERVICE] RegisterServiceCtrlHandler "  
  42.             "failed %d\n", GetLastError());   
  43.         return;   
  44.     }    
  45.     // 初始化工作,本示例未使用,函数为空  
  46.     status = SplSrvServiceInitialization(argc,argv, &specificError);    
  47.     // 初始化出错,用户自行修改  
  48.     if (status != NO_ERROR)   
  49.     {   
  50.         SplSrvServiceStatus.dwCurrentState       = SERVICE_STOPPED;   
  51.         SplSrvServiceStatus.dwCheckPoint         = 0;   
  52.         SplSrvServiceStatus.dwWaitHint           = 0;   
  53.         SplSrvServiceStatus.dwWin32ExitCode      = status;   
  54.         SplSrvServiceStatus.dwServiceSpecificExitCode = specificError;   
  55.   
  56.         SetServiceStatus (SplSrvServiceStatusHandle, &SplSrvServiceStatus);   
  57.         return;   
  58.     }   
  59.     // 初始化完成,设置运行状态  
  60.     SplSrvServiceStatus.dwCurrentState       = SERVICE_RUNNING;   
  61.     SplSrvServiceStatus.dwCheckPoint         = 0;   
  62.     SplSrvServiceStatus.dwWaitHint           = 0;   
  63.   
  64.     if (!SetServiceStatus (SplSrvServiceStatusHandle, &SplSrvServiceStatus))   
  65.     {   
  66.         status = GetLastError();   
  67.         SvcDebugOut(" [SPLSRV_SERVICE] SetServiceStatus error %ld\n",status);   
  68.     }   
  69.     // 用户自行修改,用于完成服务的工作  
  70.     SvcDebugOut(" [SPLSRV_SERVICE] Returning the Main Thread \n",0);   
  71.   
  72.     return;   
  73. }   
  74.   
  75.   
  76. /************************************* 
  77. * DWORD SplSrvServiceInitialization(DWORD   argc,  
  78. *   LPTSTR  *argv,  
  79. *   DWORD *specificError) 
  80. * 功能    初始化,这里未进行任何工作,留待读者修改 
  81. * 
  82. * 参数     
  83. **************************************/  
  84. DWORD SplSrvServiceInitialization(DWORD   argc,   
  85.                                   LPTSTR  *argv,   
  86.                                   DWORD *specificError)   
  87. {   
  88.     return(0);   
  89. }  
  90.   
  91. /************************************* 
  92. * VOID WINAPI SplSrvServiceCtrlHandler (DWORD Opcode) 
  93. * 功能    服务控制请求的处理函数,与ControlService函数配合。 
  94. * 
  95. * 参数    服务控制码 
  96. **************************************/  
  97. VOID WINAPI SplSrvServiceCtrlHandler (DWORD Opcode)   
  98. {   
  99.     DWORD status;   
  100.     switch(Opcode)   
  101.     {   
  102.     case SERVICE_CONTROL_PAUSE:   
  103.         // 完成相关功能  
  104.         SplSrvServiceStatus.dwCurrentState = SERVICE_PAUSED;   
  105.         break;   
  106.     case SERVICE_CONTROL_CONTINUE:   
  107.         // 完成相关功能  
  108.         SplSrvServiceStatus.dwCurrentState = SERVICE_RUNNING;   
  109.         break;   
  110.     case SERVICE_CONTROL_STOP:   
  111.         // 完成相关功能  
  112.         SplSrvServiceStatus.dwWin32ExitCode = 0;   
  113.         SplSrvServiceStatus.dwCurrentState  = SERVICE_STOPPED;   
  114.         SplSrvServiceStatus.dwCheckPoint    = 0;   
  115.         SplSrvServiceStatus.dwWaitHint      = 0;   
  116.   
  117.         if (!SetServiceStatus (SplSrvServiceStatusHandle,   
  118.             &SplSrvServiceStatus))  
  119.         {   
  120.             status = GetLastError();   
  121.             SvcDebugOut(" [SPLSRV_SERVICE] SetServiceStatus error %ld\n",   
  122.                 status);   
  123.         }    
  124.         SvcDebugOut(" [SPLSRV_SERVICE] Leaving SplSrvService \n",0);   
  125.         return;   
  126.     case SERVICE_CONTROL_INTERROGATE:   
  127.         // 收到此请求后发出声响,演示服务控制请求的处理过程,读者可自行修改  
  128.         MessageBeep(MB_OK);  
  129.         break;   
  130.     default:   
  131.         SvcDebugOut(" [SPLSRV_SERVICE] Unrecognized opcode %ld\n",   
  132.             Opcode);   
  133.     }   
  134.     // 当前状态  
  135.     if (!SetServiceStatus (SplSrvServiceStatusHandle,  &SplSrvServiceStatus))   
  136.     {   
  137.         status = GetLastError();   
  138.         SvcDebugOut(" [SPLSRV_SERVICE] SetServiceStatus error %ld\n",   
  139.             status);   
  140.     }   
  141.     return;   
  142. }  
  143. /************************************* 
  144. * void main( )  
  145. * 功能    程序入口函数,注册服务启动函数等。 
  146. * 
  147. * 参数    服务控制码 
  148. **************************************/  
  149. void main( )   
  150. {   
  151.     // 设置SERVICE_TABLE_ENTRY 数据结构,以NULL 结构结束,  
  152.     // 作为StartServiceCtrlDispatcher 函数的参数。  
  153.     SERVICE_TABLE_ENTRY   DispatchTable[] =   
  154.     {   
  155.         { "Sample_Srv", (LPSERVICE_MAIN_FUNCTION) SplSrvServiceStart },   
  156.         { NULL, NULL }   
  157.     };   
  158.     if (!StartServiceCtrlDispatcher( DispatchTable))   
  159.     {   
  160.         SvcDebugOut(" [SPLSRV_SERVICE] StartServiceCtrlDispatcher (%d)\n",   
  161.             GetLastError());   
  162.     }   
  163. }   
  164. /************************************* 
  165. * VOID SvcDebugOut(LPSTR String, DWORD Status)  
  166. * 功能    显示信息给调试器。 
  167. * 
  168. * 参数    LPSTR String    消息字符串 
  169. *       DWORD Status    状态 
  170. **************************************/  
  171. VOID SvcDebugOut(LPSTR String, DWORD Status)   
  172. {   
  173.     CHAR  Buffer[1024];   
  174.     if (strlen(String) < 1000)   
  175.     {   
  176.         wsprintf(Buffer, String, Status);   
  177.         OutputDebugString(Buffer);   
  178.     }   
  179. }  

然后我们实现了服务以后,需要进行安装,删除服务

具体实现代码如下,请见代码分析

[cpp] view plain copy
  1. **************************************/  
  2. /* 头文件 */  
  3. #include <windows.h>  
  4. #include <tchar.h>  
  5. #include <stdio.h>  
  6. /* 全局变量 */  
  7. SC_HANDLE schService;  
  8. SC_HANDLE schSCManager;  
  9. LPTSTR szServiceName = TEXT("Sample_Srv");  
  10.   
  11. /************************************* 
  12. * BOOL CreateSampleService(LPTSTR szPath, LPSTR szServiceName)  
  13. * 功能    创建服务 
  14. * 
  15. * 参数 
  16. *       SC_HANDLE schSCManager,SCM句柄 
  17. *       LPTSTR szPath, 服务程序的路径 
  18. *       LPSTR szServiceName, 服务名 
  19. **************************************/  
  20. BOOL CreateSampleService(   
  21.                          SC_HANDLE schSCManager,  
  22.                          LPTSTR szPath,  
  23.                          LPSTR szServiceName)   
  24. {   
  25.     // 创建服务  
  26.     schService = CreateService(   
  27.         schSCManager,               // SCM 句柄  
  28.         szServiceName,              // 服务名  
  29.         "Service sample",           // 显示的服务名  
  30.         SERVICE_ALL_ACCESS,         // 存取权限  
  31.         SERVICE_WIN32_OWN_PROCESS,  // 服务类别  
  32.         SERVICE_DEMAND_START,       // 启动类别  
  33.         SERVICE_ERROR_NORMAL,       // 错误控制类别  
  34.         szPath,                     // 服务的可执行文件路径  
  35.         NULL,                       // no load ordering group   
  36.         NULL,                       // no tag identifier   
  37.         NULL,                       // no dependencies   
  38.         NULL,                       // LocalSystem account   
  39.         NULL);                      // no password   
  40.   
  41.     if (schService == NULL)   
  42.     {  
  43.         printf("CreateService failed (%d)\n", GetLastError());   
  44.         return FALSE;  
  45.     }  
  46.     else  
  47.     {  
  48.         printf("CreateService succeeded\n");   
  49.         CloseServiceHandle(schService);   
  50.         return TRUE;  
  51.     }  
  52. }  
  53.   
  54. /************************************* 
  55. * BOOL DeleteSampleService(LPTSTR szNameOfService)  
  56. * 功能    删除服务 
  57. * 
  58. * 参数    LPTSTR szNameOfService  服务的名字 
  59. **************************************/  
  60. BOOL DeleteSampleService(LPTSTR szNameOfService)   
  61. {   
  62.     schService = OpenService(   
  63.         schSCManager,       // SCM 句柄   
  64.         szNameOfService,    // 服务名  
  65.         DELETE);            // 可删除  
  66.   
  67.     if (schService == NULL)  
  68.     {   
  69.         printf("OpenService failed (%d)\n", GetLastError());   
  70.         return FALSE;  
  71.     }  
  72.     // 删除服务  
  73.     if (! DeleteService(schService) )   
  74.     {  
  75.         printf("DeleteService failed (%d)\n", GetLastError());   
  76.         return FALSE;  
  77.     }  
  78.     else   
  79.         printf("DeleteService succeeded\n");   
  80.     // 关闭句柄  
  81.     CloseServiceHandle(schService);   
  82.     return TRUE;  
  83. }  
  84. /************************************* 
  85. * void main( int argc, TCHAR *argv[] ) 
  86. * 功能    演示 
  87. * 
  88. * 参数    未使用 
  89. **************************************/  
  90. void main( int argc, TCHAR *argv[] )   
  91. {  
  92.     TCHAR szBinFilePath[MAX_PATH];  
  93.     PTCHAR pTemp;  
  94.     DWORD dwStopError;  
  95.     // 构造服务可执行程序的路径  
  96.     GetModuleFileName(NULL,szBinFilePath,MAX_PATH);  
  97.     pTemp = szBinFilePath+lstrlen(szBinFilePath);  
  98.     while(*--pTemp!='\\');  
  99.     lstrcpy(pTemp,TEXT("\\SplSrv.exe"));  
  100.   
  101.     // 打开 SCM  
  102.     schSCManager = OpenSCManager(   
  103.         NULL,                    // local machine   
  104.         NULL,                    // ServicesActive database   
  105.         SC_MANAGER_ALL_ACCESS);  // full access rights   
  106.   
  107.     if (NULL == schSCManager)   
  108.         printf("OpenSCManager failed (%d)\n", GetLastError());  
  109.   
  110.     // 创建服务  
  111.     CreateSampleService(schSCManager, szBinFilePath, szServiceName);  
  112.     // 启动服务  
  113.     StartSampleService(schSCManager,szServiceName);  
  114.     // 发送请求控制  
  115.     ControlSampleService(SERVICE_CONTROL_INTERROGATE);  
  116.     ControlSampleService(SERVICE_CONTROL_CONTINUE);  
  117.     // 停止服务  
  118.     dwStopError = StopService( schSCManager, szServiceName,   
  119.         TRUE, 1000);  
  120.   
  121.     if(ERROR_SUCCESS == dwStopError)  
  122.     {  
  123.         printf("Service Stoped\n");   
  124.     }   
  125.     else  
  126.     {  
  127.         printf("Service stoped error (%u)\n",dwStopError);   
  128.     }  
  129.     // 删除服务  
  130.     DeleteSampleService(szServiceName);  
  131.     CloseServiceHandle(schSCManager);   
  132. }  

然后我们如何控制服务呢,我们来实现启动、停止服务,向服务发送请求。

 

[cpp] view plain copy
  1. /* 头文件 */  
  2. #include <windows.h>  
  3. #include <tchar.h>  
  4. #include <stdio.h>  
  5. /* 全局变量 */  
  6. extern SC_HANDLE schService;    // 在init.c中定义,下同  
  7. extern SC_HANDLE schSCManager;  
  8. extern LPTSTR szServiceName;  
  9.   
  10. /************************************* 
  11. * BOOL StartSampleService(SC_HANDLE schSCManager,LPTSTR szServiceName)  
  12. * 功能    启动服务 
  13. * 
  14. * 参数    SC_HANDLE schSCManager  SCM 句柄 
  15. *       LPTSTR szServiceName    服务名 
  16. **************************************/  
  17. BOOL StartSampleService(SC_HANDLE schSCManager,LPTSTR szServiceName)   
  18. {   
  19.     SC_HANDLE schService;  
  20.     SERVICE_STATUS_PROCESS ssStatus;   
  21.     DWORD dwOldCheckPoint;   
  22.     DWORD dwStartTickCount;  
  23.     DWORD dwWaitTime;  
  24.     DWORD dwBytesNeeded;  
  25.     // 打开服务  
  26.     schService = OpenService(   
  27.         schSCManager,           // SCM database   
  28.         szServiceName,          // service name  
  29.         SERVICE_ALL_ACCESS);   
  30.     if (schService == NULL)   
  31.     {   
  32.         return 0;   
  33.     }  
  34.     // 启动服务  
  35.     if (!StartService(  
  36.         schService,  // handle to service   
  37.         0,           // number of arguments   
  38.         NULL) )      // no arguments   
  39.     {  
  40.         printf("Service start error (%u).\n",GetLastError());   
  41.         return 0;   
  42.     }  
  43.     else   
  44.     {  
  45.         printf("Service start pending.\n");   
  46.     }  
  47.   
  48.     // 验证状态  
  49.     if (!QueryServiceStatusEx(   
  50.         schService,             // handle to service   
  51.         SC_STATUS_PROCESS_INFO, // info level  
  52.         (LPBYTE)&ssStatus,              // address of structure  
  53.         sizeof(SERVICE_STATUS_PROCESS), // size of structure  
  54.         &dwBytesNeeded ) )              // if buffer too small  
  55.     {  
  56.         return 0;   
  57.     }  
  58.   
  59.     // tick count & checkpoint.  
  60.     dwStartTickCount = GetTickCount();  
  61.     dwOldCheckPoint = ssStatus.dwCheckPoint;  
  62.     // 查询状态,确定 PENDING 状态结束  
  63.     while (ssStatus.dwCurrentState == SERVICE_START_PENDING)   
  64.     {   
  65.         // 等待一段时间  
  66.         dwWaitTime = ssStatus.dwWaitHint / 10;  
  67.         if( dwWaitTime < 1000 )  
  68.             dwWaitTime = 1000;  
  69.         else if ( dwWaitTime > 10000 )  
  70.             dwWaitTime = 10000;  
  71.         Sleep( dwWaitTime );  
  72.         // 再次查询  
  73.         if (!QueryServiceStatusEx(   
  74.             schService,             // handle to service   
  75.             SC_STATUS_PROCESS_INFO, // info level  
  76.             (LPBYTE)&ssStatus,              // address of structure  
  77.             sizeof(SERVICE_STATUS_PROCESS), // size of structure  
  78.             &dwBytesNeeded ) )              // if buffer too small  
  79.             break;   
  80.         if ( ssStatus.dwCheckPoint > dwOldCheckPoint )  
  81.         {  
  82.             // 进程创建中  
  83.             dwStartTickCount = GetTickCount();  
  84.             dwOldCheckPoint = ssStatus.dwCheckPoint;  
  85.         }  
  86.         else  
  87.         {  
  88.             if(GetTickCount()-dwStartTickCount > ssStatus.dwWaitHint)  
  89.             {  
  90.                 // WaitHint 时间到  
  91.                 break;  
  92.             }  
  93.         }  
  94.     }   
  95.     // 关闭句柄  
  96.     CloseServiceHandle(schService);   
  97.     // 判断是否创建成功(状态由PENDING变为RUNNING)  
  98.     if (ssStatus.dwCurrentState == SERVICE_RUNNING)   
  99.     {  
  100.         printf("StartService SUCCESS.\n");   
  101.         return 1;  
  102.     }  
  103.     else   
  104.     {   
  105.         printf("\nService not started. \n");  
  106.         printf("  Current State: %d\n", ssStatus.dwCurrentState);   
  107.         printf("  Exit Code: %d\n", ssStatus.dwWin32ExitCode);   
  108.         printf("  Service Specific Exit Code: %d\n",   
  109.             ssStatus.dwServiceSpecificExitCode);   
  110.         printf("  Check Point: %d\n", ssStatus.dwCheckPoint);   
  111.         printf("  Wait Hint: %d\n", ssStatus.dwWaitHint);   
  112.         return 0;  
  113.     }   
  114. }  
  115.   
  116. /************************************* 
  117. * DWORD StopService( SC_HANDLE hSCM,  
  118. LPTSTR szServiceName,  
  119. BOOL fStopDependencies,  
  120. DWORD dwTimeout )   
  121. * 功能    停止服务 
  122. * 
  123. * 参数    SC_HANDLE hSCM          SCM 句柄 
  124. *       LPTSTR szServiceName    服务名 
  125. *       BOOL fStopDependencies  是否结束依赖的服务 
  126. *       DWORD dwTimeout         超时 
  127. **************************************/  
  128. DWORD StopService(SC_HANDLE hSCM,   
  129.                   LPTSTR szServiceName,   
  130.                   BOOL fStopDependencies,   
  131.                   DWORD dwTimeout )   
  132. {  
  133.     SERVICE_STATUS_PROCESS ssp;  
  134.     SERVICE_STATUS ss;  
  135.     DWORD dwStartTime = GetTickCount();  
  136.     DWORD dwBytesNeeded;  
  137.     // 打开服务  
  138.     SC_HANDLE hService = OpenService(   
  139.         hSCM,          // SCM 句柄   
  140.         szServiceName,          // 服务名  
  141.         SERVICE_ALL_ACCESS);   
  142.   
  143.     // 查询状态,确定是否已经停止  
  144.     if ( !QueryServiceStatusEx(   
  145.         hService,   
  146.         SC_STATUS_PROCESS_INFO,  
  147.         (LPBYTE)&ssp,   
  148.         sizeof(SERVICE_STATUS_PROCESS),  
  149.         &dwBytesNeeded ) )  
  150.     {  
  151.         return GetLastError();  
  152.     }  
  153.     if ( ssp.dwCurrentState == SERVICE_STOPPED )   
  154.     {  
  155.         return ERROR_SUCCESS;  
  156.     }  
  157.     // 如果是 STOP_PENDING 状态,则只需等待  
  158.     while ( ssp.dwCurrentState == SERVICE_STOP_PENDING )   
  159.     {  
  160.         Sleep( ssp.dwWaitHint );  
  161.         // 循环查询,直到状态改变  
  162.         if ( !QueryServiceStatusEx(   
  163.             hService,   
  164.             SC_STATUS_PROCESS_INFO,  
  165.             (LPBYTE)&ssp,   
  166.             sizeof(SERVICE_STATUS_PROCESS),  
  167.             &dwBytesNeeded ) )  
  168.         {  
  169.             return GetLastError();  
  170.         }  
  171.         if ( ssp.dwCurrentState == SERVICE_STOPPED )  
  172.         {  
  173.             return ERROR_SUCCESS;  
  174.         }  
  175.         if ( GetTickCount() - dwStartTime > dwTimeout )  
  176.         {  
  177.             return ERROR_TIMEOUT;  
  178.         }  
  179.     }  
  180.   
  181.     // 先结束依赖服务  
  182.     if ( fStopDependencies )   
  183.     {  
  184.         DWORD i;  
  185.         DWORD dwBytesNeeded;  
  186.         DWORD dwCount;  
  187.   
  188.         LPENUM_SERVICE_STATUS   lpDependencies = NULL;  
  189.         ENUM_SERVICE_STATUS     ess;  
  190.         SC_HANDLE               hDepService;  
  191.   
  192.         // 使用 0 大小的 buf,获取buf的大小  
  193.         // 如果 EnumDependentServices 直接返回成功,说明没有依赖服务  
  194.         if ( !EnumDependentServices( hService, SERVICE_ACTIVE,   
  195.             lpDependencies, 0, &dwBytesNeeded, &dwCount ) )   
  196.         {  
  197.             if ( GetLastError() != ERROR_MORE_DATA )  
  198.                 return GetLastError(); // Unexpected error  
  199.   
  200.             // 分配缓冲区存储依赖服务的数据  
  201.             lpDependencies = (LPENUM_SERVICE_STATUS) HeapAlloc(   
  202.                 GetProcessHeap(), HEAP_ZERO_MEMORY, dwBytesNeeded );  
  203.   
  204.             if ( !lpDependencies )  
  205.                 return GetLastError();  
  206.   
  207.             __try {  
  208.                 // 获得依赖服务  
  209.                 if ( !EnumDependentServices( hService, SERVICE_ACTIVE,   
  210.                     lpDependencies, dwBytesNeeded, &dwBytesNeeded,  
  211.                     &dwCount ) )  
  212.                     return GetLastError();  
  213.   
  214.                 for ( i = 0; i < dwCount; i++ )   
  215.                 {  
  216.                     ess = *(lpDependencies + i);  
  217.   
  218.                     // 打开服务  
  219.                     hDepService = OpenService( hSCM, ess.lpServiceName,   
  220.                         SERVICE_STOP | SERVICE_QUERY_STATUS );  
  221.                     if ( !hDepService )  
  222.                         return GetLastError();  
  223.   
  224.                     __try {  
  225.                         // 结束服务  
  226.                         if ( !ControlService( hDepService,   
  227.                             SERVICE_CONTROL_STOP,  
  228.                             &ss ) )  
  229.                             return GetLastError();  
  230.   
  231.                         // 等待服务结束  
  232.                         while ( ss.dwCurrentState != SERVICE_STOPPED )   
  233.                         {  
  234.                             Sleep( ss.dwWaitHint );  
  235.                             if ( !QueryServiceStatusEx(   
  236.                                 hDepService,   
  237.                                 SC_STATUS_PROCESS_INFO,  
  238.                                 (LPBYTE)&ssp,   
  239.                                 sizeof(SERVICE_STATUS_PROCESS),  
  240.                                 &dwBytesNeeded ) )  
  241.                                 return GetLastError();  
  242.   
  243.                             if ( ss.dwCurrentState == SERVICE_STOPPED )  
  244.                                 break;  
  245.   
  246.                             if ( GetTickCount() - dwStartTime > dwTimeout )  
  247.                                 return ERROR_TIMEOUT;  
  248.                         }  
  249.   
  250.                     }   
  251.                     __finally   
  252.                     {  
  253.                         // 关闭服务  
  254.                         CloseServiceHandle( hDepService );  
  255.   
  256.                     }  
  257.                 }  
  258.             }   
  259.             __finally   
  260.             {  
  261.                 // 释放内存  
  262.                 HeapFree( GetProcessHeap(), 0, lpDependencies );  
  263.             }  
  264.         }   
  265.     }  
  266.   
  267.     // 所有的依赖服务已经结束,结束指定服务  
  268.     if ( !ControlService( hService, SERVICE_CONTROL_STOP, &ss ) )  
  269.         return GetLastError();  
  270.     while ( ss.dwCurrentState != SERVICE_STOPPED )   
  271.     {  
  272.         Sleep( ss.dwWaitHint );  
  273.         if ( !QueryServiceStatusEx(   
  274.             hService,   
  275.             SC_STATUS_PROCESS_INFO,  
  276.             (LPBYTE)&ssp,   
  277.             sizeof(SERVICE_STATUS_PROCESS),  
  278.             &dwBytesNeeded ) )  
  279.             return GetLastError();  
  280.   
  281.         if ( ss.dwCurrentState == SERVICE_STOPPED )  
  282.             break;  
  283.   
  284.         if ( GetTickCount() - dwStartTime > dwTimeout )  
  285.             return ERROR_TIMEOUT;  
  286.     }  
  287.     return ERROR_SUCCESS;  
  288. }  
  289.   
  290. /************************************* 
  291. * BOOL ControlSampleService(DWORD fdwControl)  
  292. * 功能    向服务发送控制码 
  293. * 
  294. * 参数    DWORD fdwControl        控制码值 
  295. *       SCM 句柄,服务名直接使用全局变量 
  296. **************************************/  
  297. BOOL ControlSampleService(DWORD fdwControl)   
  298. {   
  299.     SERVICE_STATUS ssStatus;   
  300.     DWORD fdwAccess;   
  301.     DWORD dwStartTickCount, dwWaitTime;  
  302.   
  303.     // Access  
  304.     switch (fdwControl)   
  305.     {   
  306.     case SERVICE_CONTROL_STOP:   
  307.         fdwAccess = SERVICE_STOP;   
  308.         break;   
  309.     case SERVICE_CONTROL_PAUSE:   
  310.     case SERVICE_CONTROL_CONTINUE:   
  311.         fdwAccess = SERVICE_PAUSE_CONTINUE;   
  312.         break;   
  313.     case SERVICE_CONTROL_INTERROGATE:   
  314.         fdwAccess = SERVICE_INTERROGATE;   
  315.         break;   
  316.     default:   
  317.         fdwAccess = SERVICE_INTERROGATE;   
  318.     }   
  319.   
  320.     // 打开服务  
  321.     schService = OpenService(   
  322.         schSCManager,        // SCManager 句柄   
  323.         szServiceName,       // 服务名  
  324.         fdwAccess);          // 存取权限  
  325.     if (schService == NULL)   
  326.     {  
  327.         printf("OpenService failed (%d)\n", GetLastError());   
  328.         return FALSE;  
  329.     }  
  330.   
  331.     // 发送控制码  
  332.     if (! ControlService(   
  333.         schService,   // 服务的句柄  
  334.         fdwControl,   // 控制码  
  335.         &ssStatus) )  // 状态  
  336.     {  
  337.         printf("ControlService failed (%d)\n", GetLastError());   
  338.         return FALSE;  
  339.     }  
  340.   
  341.     // 显示状态  
  342.     printf("\nStatus of Sample_Srv: \n");  
  343.     printf("  Service Type: 0x%x\n", ssStatus.dwServiceType);   
  344.     printf("  Current State: 0x%x\n", ssStatus.dwCurrentState);   
  345.     printf("  Controls Accepted: 0x%x\n",   
  346.         ssStatus.dwControlsAccepted);   
  347.     printf("  Exit Code: %d\n", ssStatus.dwWin32ExitCode);   
  348.     printf("  Service Specific Exit Code: %d\n",   
  349.         ssStatus.dwServiceSpecificExitCode);   
  350.     printf("  Check Point: %d\n", ssStatus.dwCheckPoint);   
  351.     printf("  Wait Hint: %d\n", ssStatus.dwWaitHint);   
  352.   
  353.     return TRUE;   
  354. }  

0 0