- 文章概要:
- 本文主要介绍了 OpenSCManager、CreateService、OpenService、ControlService、DeleteService、RegisterServiceCtrlHandler、SetServiceStatus、StartServiceCtrlDispatcher等操作服务程序的主要几个API的用法,具体的函数参数大家可以查阅MSDN。
本文主要介绍了 OpenSCManager、CreateService、OpenService、ControlService、DeleteService、RegisterServiceCtrlHandler、SetServiceStatus、StartServiceCtrlDispatcher等操作服务程序的主要几个API的用法,具体的函数参数大家可以查阅MSDN。 为什么要使用服务应该程序呢?服务程序就像系统的一些服务一样,能够自动地启动,并执行相应的操作;而且因为服务程序的在层次上和一般的应用程序不同,其能够在系统启动时就自动地运行,而不像一般的应用程序那样一定要在登陆后才能运行,这些就是服务的一些好处了,如果你也想你的程序具有这样的功能,那么你就可以建立一个服务应用程序了。下面就跟着我一步一步地教你怎么去创建一个服务应用程序吧。 一、建立 Win32 Application 应用程序(当然你也可以建立其它的应用程序,但服务一般是没有用户界面的),并命名为 ServiceTest。
二、定义全局函数变量。这里主要是设置服务句柄和状态。 01. BOOL IsInstalled(); 02. BOOL Install(); 03. BOOL Uninstall(); 04. void LogEvent( LPCTSTR pszFormat,
...); 05. void WINAPI
ServiceMain(); 06. void WINAPI
ServiceStrl( DWORD dwOpcode); 07. 08. TCHAR szServiceName[]
= _T( "ServiceTest" ); 09. BOOL bInstall; 10. SERVICE_STATUS_HANDLE hServiceStatus; 11. SERVICE_STATUS
status; 12. DWORD dwThreadID; 三、添加Init初始化函数。 01. void Init() 02. { 03. hServiceStatus
= NULL; 04. status.dwServiceType
= SERVICE_WIN32_OWN_PROCESS; 05. status.dwCurrentState
= SERVICE_STOPPED; 06. tatus.dwControlsAccepted
= SERVICE_ACCEPT_STOP; 07. status.dwWin32ExitCode
= 0; 08. status.dwServiceSpecificExitCode
= 0; 09. status.dwCheckPoint
= 0; 10. status.dwWaitHint
= 0; 11. } 四、添加安装和删除服务函数。这里主要是用到了四个函数 OpenSCManager 和 CreateService。OpenSCManager 用于打开服务控制管理器;CreateService 用于创建服务;OpenService用于打开已有的服务,返回该服务的句柄;ControlService则用于控制已打开的服务状态,这里是让服务停止后才删除;DeleteService 用于删除指定服务。 01. BOOL Install(); 02. { 03. //这里列出主要的两个函数,其它的可以在代码里找。 04. 05. //打开服务控制管理器 06. OpenSCManager(NULL,
NULL, SC_MANAGER_ALL_ACCESS); 07. 08. //创建服务 09. SC_HANDLE hService
= ::CreateService( 10. hSCM,
szServiceName, szServiceName, 11. SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS, 12. SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL, 13. szFilePath,
NULL, NULL, _T( "" ),
NULL, NULL); 14. 15. ::CloseServiceHandle(hService); 16. ::CloseServiceHandle(hSCM); 17. } 18. 19. 20. BOOL Uninstall(); 21. { 22. //这里列出主要的两个函数,其它的可以在代码里找。 23. 24. //打开服务控制管理器 25. OpenSCManager(NULL,
NULL, SC_MANAGER_ALL_ACCESS); 26. 27. //打开服务 28. OpenService(hSCM,
szServiceName, SERVICE_STOP | DELETE); 29. 30. //停止服务 31. ControlService(hService,
SERVICE_CONTROL_STOP, &status); 32. 33. //删除服务 34. DeleteService(hService); 35. 36. … 37. } 五、添加服务主线程函数和控制函数。这里调用 RegisterServiceCtrlHandler 来注册服务的控制函数,这里要设置status.dwControlsAccepted 为 SERVICE_ACCEPT_STOP,否则你不能控制这个服务的状态。 01. void WINAPI
ServiceMain() 02. { 03. //
Register the control request handler 04. status.dwCurrentState
= SERVICE_START_PENDING; 05. status.dwControlsAccepted
= SERVICE_ACCEPT_STOP; //这个要使用,否则你不能控制 06. 07. //注册服务控制 08. hServiceStatus
= RegisterServiceCtrlHandler(szServiceName, ServiceStrl); 09. if (hServiceStatus
== NULL) 10. { 11. LogEvent(_T( "Handler
not installed" )); 12. return ; 13. } 14. SetServiceStatus(hServiceStatus,
&status); 15. 16. status.dwWin32ExitCode
= S_OK; 17. status.dwCheckPoint
= 0; 18. status.dwWaitHint
= 0; 19. status.dwCurrentState
= SERVICE_RUNNING; 20. SetServiceStatus(hServiceStatus,
&status); 21. 22. //模拟服务的运行,10后自动退出。应用时将主要任务放于此即可 23. int i
= 0; 24. while (i
< 10) 25. { 26. Sleep(1000); 27. i++; 28. } 29. // 30. 31. status.dwCurrentState
= SERVICE_STOPPED; 32. SetServiceStatus(hServiceStatus,
&status); 33. LogEvent(_T( "Service
stopped" )); 34. } 六、在主线程函数里注册控制函数和程序执行主体。这里主要是说明这就是程序的执行体。 01. void WINAPI
ServiceMain() 02. { 03. … 04. 05. //模拟服务的运行,10后自动退出。应用时将主要任务放于此即可 06. int i
= 0; 07. while (i
< 10) 08. { 09. Sleep(1000); 10. 11. i++; 12. } 13. 14. … 15. } 七、最后,要在main函数里注册添加安装、删除、注册主函数。 01. int APIENTRY
WinMain( HINSTANCE hInstance, 02. HINSTANCE hPrevInstance, 03. LPSTR lpCmdLine, 04. int nCmdShow) 05. { 06. Init(); 07. dwThreadID
= ::GetCurrentThreadId(); 08. SERVICE_TABLE_ENTRY
st[] = 09. { 10. {
szServiceName, (LPSERVICE_MAIN_FUNCTION)ServiceMain }, 11. {
NULL, NULL } 12. }; 13. 14. if (stricmp(lpCmdLine, "/install" )
== 0) 15. { 16. Install(); 17. } 18. else if (stricmp(lpCmdLine, "/uninstall" )
== 0) 19. { 20. Uninstall(); 21. } 22. else 23. { 24. if (!::StartServiceCtrlDispatcher(st)) 25. { 26. LogEvent(_T( "Register
Service Main Function Error!" )); 27. } 28. } 29. return 0; 30. } 八、总结。其实做一个服务程序并不难,主要是懂得程序的执行体放于哪里?和注册程序的主函数和注册控制函数,如果这两个没有注册的话,你就程序就不知道如何去控制了。status.dwControlsAccepted = SERVICE_ACCEPT_STOP;这个也重要,如果你没有设置的话,那么服务就不会受你控制了。
转自:http://www.vckbase.com/index.php/wv/1391 |