写一个ServiceMain函数
来源:互联网 发布:js数组get 编辑:程序博客网 时间:2024/06/04 18:09
#define SVCNAME TEXT("SvcName")SERVICE_STATUS gSvcStatus; SERVICE_STATUS_HANDLE gSvcStatusHandle; HANDLE ghSvcStopEvent = NULL;//// Purpose: // Entry point for the service//// Parameters:// dwArgc - Number of arguments in the lpszArgv array// lpszArgv - Array of strings. The first string is the name of// the service and subsequent strings are passed by the process// that called the StartService function to start the service.// // Return value:// None.//VOID WINAPI SvcMain( DWORD dwArgc, LPTSTR *lpszArgv ){ // Register the handler function for the service gSvcStatusHandle = RegisterServiceCtrlHandler( SVCNAME, SvcCtrlHandler); if( !gSvcStatusHandle ) { SvcReportEvent(TEXT("RegisterServiceCtrlHandler")); return; } // These SERVICE_STATUS members remain as set here gSvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; gSvcStatus.dwServiceSpecificExitCode = 0; // Report initial status to the SCM ReportSvcStatus( SERVICE_START_PENDING, NO_ERROR, 3000 ); // Perform service-specific initialization and work. SvcInit( dwArgc, lpszArgv );}//// Purpose: // The service code//// Parameters:// dwArgc - Number of arguments in the lpszArgv array// lpszArgv - Array of strings. The first string is the name of// the service and subsequent strings are passed by the process// that called the StartService function to start the service.// // Return value:// None//VOID SvcInit( DWORD dwArgc, LPTSTR *lpszArgv){ // TO_DO: Declare and set any required variables. // Be sure to periodically call ReportSvcStatus() with // SERVICE_START_PENDING. If initialization fails, call // ReportSvcStatus with SERVICE_STOPPED. // Create an event. The control handler function, SvcCtrlHandler, // signals this event when it receives the stop control code. ghSvcStopEvent = CreateEvent( NULL, // default security attributes TRUE, // manual reset event FALSE, // not signaled NULL); // no name if ( ghSvcStopEvent == NULL) { ReportSvcStatus( SERVICE_STOPPED, NO_ERROR, 0 ); return; } // Report running status when initialization is complete. ReportSvcStatus( SERVICE_RUNNING, NO_ERROR, 0 ); // TO_DO: Perform work until service stops. while(1) { // Check whether to stop the service. WaitForSingleObject(ghSvcStopEvent, INFINITE); ReportSvcStatus( SERVICE_STOPPED, NO_ERROR, 0 ); return; }}//// Purpose: // Sets the current service status and reports it to the SCM.//// Parameters:// dwCurrentState - The current state (see SERVICE_STATUS)// dwWin32ExitCode - The system error code// dwWaitHint - Estimated time for pending operation, // in milliseconds// // Return value:// None//VOID ReportSvcStatus( DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint){ static DWORD dwCheckPoint = 1; // Fill in the SERVICE_STATUS structure. gSvcStatus.dwCurrentState = dwCurrentState; gSvcStatus.dwWin32ExitCode = dwWin32ExitCode; gSvcStatus.dwWaitHint = dwWaitHint; if (dwCurrentState == SERVICE_START_PENDING) gSvcStatus.dwControlsAccepted = 0; else gSvcStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; if ( (dwCurrentState == SERVICE_RUNNING) || (dwCurrentState == SERVICE_STOPPED) ) gSvcStatus.dwCheckPoint = 0; else gSvcStatus.dwCheckPoint = dwCheckPoint++; // Report the status of the service to the SCM. SetServiceStatus( gSvcStatusHandle, &gSvcStatus );}
上面例子中的SvcMain函数就是服务实例中的ServiceMain函数。SvcMain可以main函数的方式来访问服务的命令行参数。第一个参数包含要传入到服务中的第二个参数的数量。至少有一个参数。第二个参数是一个指向字符串指针数组的指针。数组中的第一项为服务名。
SvcMain函数首先调用RegisterServiceCtrlHandler函数来注册SvcCtrlHandler函数作为服务的Handler函数,然后开始初始化。RegisterSreviceCtrlHandler是在ServiceMain中第一个必须返回成功的函数,之后服务能够使用该函数返回的状态去调用SetServiceStatus函数设置状态,若发生错误,则状态设为SERVICE_STOPPED。
下一步,SvcMain函数调用ReportSvcStatus函数来指定它的初始状态为SERVICE_START_PENDING。若服务处在这种状态中,将无法接收控制命令。为了简化服务逻辑,建议在初始化操作时,服务不接收任何控制命令。
样例的初始化函数SvcInit,是一个很简单的例子。它不会处理复杂的初始化任务,比如创建额外线程等。它创建一个事件:服务控制处理程序能够发信号让服务停止,随后调用ReportSvcStatus预示服务已经进入SERVICE_RUNNING状态。此时,服务已经完成初始化并准备接收控制命令。为了最好的系统性能,在25~100ms内应用程序应该进入运行状态。
由于该实例服务没有完成任何实际任务,SvcInit仅仅通过调用WaitForSingleObject来等待服务停止事件触发,调用ReportSvcStatus来预示服务已经进入SERVICE_STOPPED状态,并返回。(注意函数返回很重要,而不应该去调用ExitThread函数,由于返回会为之前参数创建的内存做清理工作)。可通过使用函数RegisterWaitForSingleObject来做额外的清理任务而不是用WaitForSingleObject。运行ServiceMain函数的线程终止,但是服务仍然在继续。当服务控制处理函数触发事件时,线程池中的线程执行回调来处理额外的清理工作,包括设置状态为SERVICE_STOPPED。
注意该实例使用SvcReportEvent来写错误事件到事件log。
参考网址:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms687414(v=vs.85).aspx
- 写一个ServiceMain函数
- ServiceMain
- VC++ Service编程(二)编写ServiceMain函数
- VC++ Service编程(四)服务ServiceMain函数
- ServiceMain、StartServiceCtrlDispatcher
- 写一个atoi函数
- 写一个内存拷贝函数
- 如何写一个分段函数
- 写一个memcpy的函数
- c函数-写一个字符
- 写一个 JSONP 请求函数
- 写一个内存拷贝函数
- 写一个验证邮箱函数
- 写的一个split函数
- 写一个随机洗牌函数
- 自己写一个pow()函数
- 写一个函数,判断素数
- 写一个函数求平均数
- JAVA Pattern regex
- TX2 CAN通信配置
- setSystemUiVisibility(int visibility)传入的实参类型解释
- Java的数据类型
- OpenCV-Python教程(4、形态学处理)
- 写一个ServiceMain函数
- xcode使用Scheme管理项目
- cocos android 中文转拼音
- V4L2采集YUYV数据—X264编码H264视频实例
- Oracle创建和调用存储过程,函数,视图
- 淘宝atlas补丁包构建使用详细说明
- 关于xiang项目导入出现java.lang.notfoundexception的解决办法
- 针对不同的应用场景选用不同的语言
- nmap之安全工具学习路线