WEB开发网
开发学院软件开发VC 用 C++ 创建简单的 Win32 服务程序(2) 阅读

用 C++ 创建简单的 Win32 服务程序(2)

 2006-04-09 11:41:10 来源:WEB开发网   
核心提示: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services我就是选择这里来存储我的服务配置信息,我创建了一个 Parameters 键,用 C++ 创建简单的 Win32 服务程序(2)(3),并在此存储我要保存的值,所以当服务启动时,然后在调
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services

我就是选择这里来存储我的服务配置信息。我创建了一个 Parameters 键,并在此存储我要保存的值。所以当服务启动时,OnInit 函数被调用;这个函数从注册表中读取初始设置。

BOOL CMyService::OnInit() {  // Read the registry parameters.  // Try opening the registry key:  // HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\\Parameters  HKEY hkey;  char szKey[1024];  strcpy(szKey, "SYSTEM\\CurrentControlSet\\Services\\");  strcat(szKey, m_szServiceName);  strcat(szKey, "\\Parameters");   if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,           szKey,           0,           KEY_QUERY_VALUE,           &hkey) == ERROR_SUCCESS) {     // Yes we are installed.     DWORD dwType = 0;     DWORD dwSize = sizeof(m_iStartParam);     RegQueryValueEx(hkey,             "Start",             NULL,             &dwType,             (BYTE*)&m_iStartParam,             &dwSize);     dwSize = sizeof(m_iIncParam);     RegQueryValueEx(hkey,             "Inc",             NULL,             &dwType,             (BYTE*)&m_iIncParam,             &dwSize);     RegCloseKey(hkey);   }  // Set the initial state.  m_iState = m_iStartParam;  return TRUE; } 现在我们有了服务参数,我们便可以运行服务了。
运行服务
当 Run 函数被调用时将执行服务的主体代码。本文例子的这部分很简单: void CMyService::Run() {   while (m_bIsRunning) {   // Sleep for a while.     DebugMsg("My service is sleeping (%lu)...", m_iState);     Sleep(1000);   // Update the current state.   m_iState += m_iIncParam;   } }   注意,只要服务不终止,这个函数就不会退出。当有终止服务的请求时,CNTService::m_bIsRunning 标志被置成 FALSE。如果在服务终止时,你要实现清除操作,那么你还可以改写 OnStop 和/或 OnShutdown。
响应控制请求
  你可以用任何适合的方式与服务通讯——命名管道,思想交流,便条等等——对于一些简单的请求,用系统函数 ControlService 很容易实现。CNTService 提供了一个处理器专门用于通过 ControlService 函数发送的非标准消息(也就是用户发送的消息)。本文例子用单一消息在注册表中保存当前服务的状态,以便其它应用程序能看到它。我不建议用这种方法来监控服务,因为它不是最佳方法,这只是比较容易编码实现而已。ControlService 所能处理的用户消息必须在 128 到 255 这个范围。我定义了一个常量 SERVICE_CONTROL_USER,128 作为基值。范围内的用户消息被发送到 CNTService:: OnUserControl,在例子服务中,处理此消息的细节如下:
BOOL CMyService::OnUserControl(DWORD dwOpcode) {   switch (dwOpcode) {   case SERVICE_CONTROL_USER + 0:     // Save the current status in the registry.     SaveStatus();     return TRUE;   default:     break;   }   return FALSE;  // say not handled } SaveStatus 是一个局部函数,用来在注册表中存储服务状态。
调试 Win32 服务
  main 函数中包含一个对 DebugBreak 的调用,当服务第一次被启动时,它会激活系统调试器。你可以监控来自调试器命令窗口中的服务调试信息。你可以在服务中用 CNTService::DebugMsg 来报告调试期间感兴趣的事件。
  为了调试服务代码,你需要按照 Platform SDK 文档中的要求安装 系统调试器(WinDbg)。你也可以用 Visual Studio 自带的调试器调试 Win32 服务。
  有一点很重要,那就是 当它被服务管理器控制时,你不能终止服务和单步执行,因为服务管理器会让服务请求 超时并终止服务线程。所以你只能让服务吐出消息,跟踪其过程并在调试器窗口查看它们。
  当服务启动后(例如,从控制面板的“服务”中),调试器将在服务线程的挂起后启动。你需要通过单击“Go”按钮或按 F5 让继续运行。然后在调试器中观察服务的运行过程。
下面是启动和终止服务的调试输出例子:Module Load: WinDebug/NTService.exe (symbol loading deferred) Thread Create: Process=0, Thread=0 Module Load: C:\NT351\system32\NTDLL.DLL (symbol loading deferred) Module Load: C:\NT351\system32\KERNEL32.DLL (symbol loading deferred) Module Load: C:\NT351\system32\ADVAPI32.DLL (symbol loading deferred) Module Load: C:\NT351\system32\RPCRT4.DLL (symbol loading deferred) Thread Create: Process=0, Thread=1 *** WARNING: symbols checksum is wrong 0x0005830f 0x0005224f for C:\NT351\symbols\dll\NTDLL.DBG Module Load: C:\NT351\symbols\dll\NTDLL.DBG (symbols loaded) Thread Terminate: Process=0, Thread=1, Exit Code=0 Hard coded breakpoint hit Hard coded breakpoint hit [](130): CNTService::CNTService() Module Load: C:\NT351\SYSTEM32\RPCLTC1.DLL (symbol loading deferred) [NT Service Demonstration](130): Calling StartServiceCtrlDispatcher() Thread Create: Process=0, Thread=2 [NT Service Demonstration](174): Entering CNTService::ServiceMain() [NT Service Demonstration](174): Entering CNTService::Initialize() [NT Service Demonstration](174): CNTService::SetStatus(3026680, 2) [NT Service Demonstration](174): Sleeping... [NT Service Demonstration](174): CNTService::SetStatus(3026680, 4) [NT Service Demonstration](174): Entering CNTService::Run() [NT Service Demonstration](174): Sleeping... [NT Service Demonstration](174): Sleeping... [NT Service Demonstration](174): Sleeping... [NT Service Demonstration](130): CNTService::Handler(1) [NT Service Demonstration](130): Entering CNTService::Stop() [NT Service Demonstration](130): CNTService::SetStatus(3026680, 3) [NT Service Demonstration](130): Leaving CNTService::Stop() [NT Service Demonstration](130): Updating status (3026680, 3) [NT Service Demonstration](174): Leaving CNTService::Run() [NT Service Demonstration](174): Leaving CNTService::Initialize() [NT Service Demonstration](174): Leaving CNTService::ServiceMain() [NT Service Demonstration](174): CNTService::SetStatus(3026680, 1) Thread Terminate: Process=0, Thread=2, Exit Code=0 [NT Service Demonstration](130): Returned from StartServiceCtrlDispatcher() Module Unload: WinDebug/NTService.exe Module Unload: C:\NT351\system32\NTDLL.DLL Module Unload: C:\NT351\system32\KERNEL32.DLL Module Unload: C:\NT351\system32\ADVAPI32.DLL Module Unload: C:\NT351\system32\RPCRT4.DLL Module Unload: C:\NT351\SYSTEM32\RPCLTC1.DLL Thread Terminate: Process=0, Thread=0, Exit Code=0 Process Terminate: Process=0, Exit Code=0 > 总结
  也许用 C++ 创建 Win32 服务并不是最理想的,但使用单一的类来派生你自己的服务的确方便了你的服务开发工作。

上一页  1 2 3 

Tags:创建 简单 Win

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接