Windows 创建服务(服务接受会话更改)

Windows 创建服务(服务接受会话更改),windows,winapi,service,Windows,Winapi,Service,我正在尝试按照下面链接中记录的示例创建服务: 我感兴趣的是能够捕获用户“锁定”和“解锁”工作站事件 使用提供的示例中的代码,我修改了以下内容: 第15行: 原件: VOID WINAPI SvcCtrlHandler(DWORD) 修改: DWORD WINAPI SvcCtrlHandler( DWORD dwControl, DWORD dwEventType, LPVOID lpEventData, LPVOID lpContext ) { DWORD dwErrorCode =

我正在尝试按照下面链接中记录的示例创建服务:

我感兴趣的是能够捕获用户“锁定”和“解锁”工作站事件

使用提供的示例中的代码,我修改了以下内容:

第15行:

原件:

VOID WINAPI SvcCtrlHandler(DWORD)

修改:

DWORD WINAPI SvcCtrlHandler( DWORD dwControl, DWORD dwEventType, LPVOID lpEventData, LPVOID lpContext )
{
   DWORD dwErrorCode = NO_ERROR;

   switch(dwControl) 
   {  
      case SERVICE_CONTROL_STOP: 
         ReportSvcStatus(SERVICE_STOP_PENDING, NO_ERROR, 0);

         // Signal the service to stop.

         SetEvent(ghSvcStopEvent);
         ReportSvcStatus(gSvcStatus.dwCurrentState, NO_ERROR, 0);
   break;

      case SERVICE_CONTROL_INTERROGATE: 
         break; 

      case SERVICE_CONTROL_SESSIONCHANGE:
 ReportSvcStatus(gSvcStatus.dwCurrentState, NO_ERROR, 0);
 break;

      default:
 break;
   }

   return dwErrorCode;   
}
DWORD-WINAPI SvcCtrlHandler(DWORD,DWORD,LPVOID,LPVOID)

第141行:

原件:

gSvcStatusHandle=RegisterServiceCtrlHandler(SVCNAME,SvcCtrlHandler)

修改:

gSvcStatusHandle=RegisterServiceCtrlHandlerEx(SVCNAME,SvcCtrlHandler,NULL)

第244行:

原件:

gSvcStatus.dwControlsAccepted=SERVICE\u ACCEPT\u STOP

修改:

gSvcStatus.dwControlsAccepted=SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SESSIONCHANGE

第266行:

原件:

VOID WINAPI SvcCtrlHandler( DWORD dwCtrl )
{
   // Handle the requested control code. 

   switch(dwCtrl) 
   {  
      case SERVICE_CONTROL_STOP: 
         ReportSvcStatus(SERVICE_STOP_PENDING, NO_ERROR, 0);

         // Signal the service to stop.

         SetEvent(ghSvcStopEvent);
         ReportSvcStatus(gSvcStatus.dwCurrentState, NO_ERROR, 0);

         return;

      case SERVICE_CONTROL_INTERROGATE: 
         break; 

      default: 
         break;
   }    
}
修改:

DWORD WINAPI SvcCtrlHandler( DWORD dwControl, DWORD dwEventType, LPVOID lpEventData, LPVOID lpContext )
{
   DWORD dwErrorCode = NO_ERROR;

   switch(dwControl) 
   {  
      case SERVICE_CONTROL_STOP: 
         ReportSvcStatus(SERVICE_STOP_PENDING, NO_ERROR, 0);

         // Signal the service to stop.

         SetEvent(ghSvcStopEvent);
         ReportSvcStatus(gSvcStatus.dwCurrentState, NO_ERROR, 0);
   break;

      case SERVICE_CONTROL_INTERROGATE: 
         break; 

      case SERVICE_CONTROL_SESSIONCHANGE:
 ReportSvcStatus(gSvcStatus.dwCurrentState, NO_ERROR, 0);
 break;

      default:
 break;
   }

   return dwErrorCode;   
}
通过上面的更改,我的服务编译并安装得很好

我尝试在windows 7计算机上启动我的服务,它将正常启动(但我将无法停止、暂停或对服务执行任何操作,因为所有选项都将被禁用)

我还在我的Windows 2000计算机上尝试了我的服务,它甚至没有启动(它将停留在“启动”状态)

我的主要目标是让服务在Windows7环境中正常运行,让它在Windows2000中向后兼容将是一个额外的好处

有人能给我建议吗? 提前谢谢大家,

Ron

:服务接受会话更改:“Windows 2000:不支持此值。”

不确定这是否是服务陷入启动阶段的实际原因

编辑:在windows 2000上获取会话事件的其他方法:

  • :

我这里有一个测试服务,它接受会话更改事件并在Windows 7上正常运行。它支持所有可能的通知,并正确地允许停止和暂停,并处理会话更改事件

我知道这没什么帮助,但至少你知道你应该能够让它按照文档的方式工作。。。我的服务代码比你的基本示例要复杂得多,所以我一眼就看不出你犯了什么错误


由于您没有将停止视为选项,我会检查您是否正确设置了接受的控件,或者将其更改为停止,并确保在启动服务后将停止视为选项…

您好,谢谢您的快速回复。我之所以尝试创建一个服务,是因为我们公司正在转向Windows7平台。我们曾经实现Winlogon方法(但Win7不支持),我忘了提到,实际上我在Windows7机器上尝试了该服务,并能够启动它。但是,当我右键单击服务后,所有操作按钮都将被禁用。任何其他建议都将不胜感激。好吧,你只需要Winlogon或SENS 2000上的代码路径,以后的平台支持sessionchange Flag是的,你是正确的,我修改了我的原始帖子以澄清我的意图。我正试图让它与Windows7一起工作。让它与Windows 2000向后兼容将是一个额外的奖励。您好,再次感谢您确认它应该可以工作。我从头开始重写代码,它似乎在工作:O.您的diff有一个bug,SvcStatus vs gSvcStatus,但在编译时会失败…对不起,这是我复制/粘贴的错误。在上面的帖子中更正。感谢您的确认。当我恢复到只接受stop命令时,服务运行良好(正确启动和停止)。似乎是服务\u ACCEPT\u SESSIONCHANGE导致了挂起。您能帮我检查一下会话更改事件的处理程序中是否有任何特殊代码吗?我在想如果我错过了一些关键的处理电话。提前谢谢你。我的代码与你的代码没有什么不同;唯一的变化是,我完全初始化了服务状态结构的所有元素,并且当我“报告状态”时,我倾向于将2000作为等待提示传递,而不是0。我还将一个非null上下文传递给处理程序,但我怀疑它是否会像我预期的那样在内部被视为不透明句柄(尽管文档没有明确声明它可以为null)。