简体   繁体   English

如何确保Windows 2008 R2将SERVICE_CONTROL_PRESHUTDOWN控制通知传递给服务

[英]How can I ensure that Windows 2008 R2 will pass the SERVICE_CONTROL_PRESHUTDOWN control notification to a service

I'm writing a service using plain C++ and the windows API and want it to receive the PRESHUTDOWN notifications which are available from Windows 2008 R2. 我正在使用普通的C ++和Windows API编写服务,并希望它接收可从Windows 2008 R2获得的PRESHUTDOWN通知。

http://msdn.microsoft.com/en-us/library/windows/desktop/ms685996(v=vs.85).aspx http://msdn.microsoft.com/en-us/library/windows/desktop/ms685996(v=vs.85).aspx

I want this service to handle pre-shutdown events and prevent the machine from finishing its shutdown for an arbitrary time. 我希望该服务处理关机前事件,并防止计算机在任意时间内完成关机。

My ServiceMain loops, logging out a message every 5 seconds. 我的ServiceMain循环,每5秒注销一条消息。

I'm setting dwControlsAccepted to: 我将dwControls设置为:

SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PRESHUTDOWN

I'm receiving the SERVICE_CONTROL_STOP notification in my ServiceControl callback just fine. 我在ServiceControl回调中收到SERVICE_CONTROL_STOP通知就好了。

If I run my service, and call 如果我运行我的服务,然后致电

sc query "MyService"

It says: 它说:

(STOPPABLE, NOT_PAUSABLE, ACCEPTS_PRESHUTDOWN)

I write an entry to the log file as soon as I receive any service control notification, before I even look at what it is. 我收到任何服务控制通知后立即写入日志文件的条目,然后我才会看到它是什么。

When I shutdown, windows makes a point of saying "Stopping MyService" in big white letters on the screen, and waits for a bit, then completes shutdown. 当我关机时,Windows会在屏幕上用大的白色字母说“停止MyService”,等待一下,然后完成关机。

However: 然而:

The main loop keeps writing to the log file. 主循环继续写入日志文件。 The log file contains no reference to any service control attempt. 日志文件不包含任何服务控制尝试的引用。

Then windows gives up on closing my service and just kills it. 然后,Windows放弃了关闭我的服务并终止了它。

Now, if I do exactly the same thing, but register for SHUTDOWN instead of PRESHUTDOWN, I see all the notifications in the log file that I would expect to see (although can't extend the shutdown period, as we can't do that from the SHUTDOWN notification). 现在,如果我做完全相同的事情,但是注册了SHUTDOWN而不是PRESHUTDOWN,我会在日志文件中看到我希望看到的所有通知(尽管不能延长关闭时间,因为我们不能这样做)从关机通知中)。

The only change to the code is the removal of the three letters "PRE" in the calls to set status. 对代码的唯一更改是在设置状态调用中​​删除三个字母“PRE”。

I'm not even getting to the point where I can start incrementing dwCheckPoint - the windows subsystem isn't notifying me. 我什至无法开始增加dwCheckPoint的程度-Windows子系统没有通知我。

Windows knows I'm looking for pre-shutdown messages, as evidenced by "sc query", is there anything that can be preventing it from receiving the pre-shutdown message? Windows知道我正在寻找预关闭消息,正如“sc查询”所证明的那样,有什么东西可以阻止它接收预关闭消息吗?

Relevant methods: 相关方法:

When reporting the status (SCM reports service as started, quite happily) 报告状态时(很高兴SCM报告服务已启动)

VOID ServiceReportStatus (DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint)
{
    // Fill in the SERVICE_STATUS structure.
    g_serviceStatus.dwCurrentState = dwCurrentState;
    g_serviceStatus.dwWin32ExitCode = dwWin32ExitCode;
    g_serviceStatus.dwWaitHint = dwWaitHint;

    switch(dwCurrentState)
    {
    case SERVICE_START_PENDING:
    case SERVICE_STOP_PENDING:
    case SERVICE_CONTINUE_PENDING:
    case SERVICE_PAUSE_PENDING:
        g_serviceStatus.dwControlsAccepted = 0;
        break;
    default:
        g_serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PRESHUTDOWN;
    }

    // Report the status of the service to the SCM.
    SetServiceStatus (g_serviceStatusHandle, &g_serviceStatus);
}

When I receive a message: 当我收到消息时:

VOID WINAPI ServiceCtrlHandler (DWORD dwCtrl)
{
    LOG(eDeveloper10, L"ServiceCtrlHandler", L"Decoding SvcControl %d\n", dwCtrl);
   switch(dwCtrl) 
   {
      case SERVICE_CONTROL_PRESHUTDOWN:
          {
             LOG(eDeveloper10, L"ServiceCtrlHandler", L"Received SERVICE_CONTROL_PRESHUTDOWN\n");
             ServiceReportStatus(SERVICE_STOP_PENDING, NO_ERROR, 10000);

             // Signal the service to stop.
             SetEvent(g_serviceStopEvent);
             break;
          }
    }
}

It does more, but nothing useful for this example, as I don't even see the log (unless I'm registering for SHUTDOWN instead). 它做的更多,但对于这个例子没什么用,因为我甚至没有看到日志(除非我注册SHUTDOWN)。

The ServiceCtrlHandler always returns quickly, I'm not blocking in here, I'm not getting in to here for the pre-shutdown handler. ServiceCtrlHandler总是快速返回,我在这里没有阻塞,我没有进入这里进行预关闭处理程序。 Registering for both PRESHUTDOWN and SHUTDOWN doesn't help either. 同时注册PRESHUTDOWN和SHUTDOWN也无济于事。 I've tried this on two Windows 2008R2 machines, one virtual machine, one physical, with the same results. 我已经在两台Windows 2008R2计算机,一台虚拟机,一台物理计算机上尝试了此方法,并且结果相同。 Service is compiled as a x64 binary. 服务被编译为x64二进制文件。

Any ideas? 有任何想法吗?

Some sample logs, this log is when I request to be notified of SHUTDOWN: 一些示例日志,这个日志是我请求收到SHUTDOWN的通知时:

L0  T2672 2781140 [CDbgEntry::LoadSystemDetails()] System Details Follow:

   Computer Name     : \\****
   Domain/Workgroup  : **** [Domain]
   User Name         : SYSTEM
   Operating System  : Windows NT Version 6.1 Build 7600
   Service Pack      : None.    
   Terminal Services : Terminal Services Present
   System Root       : C:\Windows\system32
   User's Windir     : C:\Windows


This file is recording debug messages with a maximum level of 10
L10 T2672 2781140 [ServiceInitialize] Service initialised, waiting for stop event
L10 T2672 2786140 [ServiceInitialize] Still waiting for stop event.
L10 T2668 2789328 [ServiceCtrlHandler] Decoding SvcControl 5
L10 T2668 2789328 [ServiceCtrlHandler] Received SERVICE_CONTROL_SHUTDOWN
L10 T2672 2789328 [ServiceInitialize] Stop event detected
L10 T2672 2789328 [ServiceInitialize] Blocking service shutdown
L10 T2672 2790328 [ServiceInitialize] Blocking service shutdown
L10 T2672 2791328 [ServiceInitialize] Blocking service shutdown
L10 T2672 2792328 [ServiceInitialize] Blocking service shutdown
L10 T2672 2793328 [ServiceInitialize] Blocking service shutdown
L10 T2672 2794328 [ServiceInitialize] Blocking service shutdown
L10 T2672 2795437 [ServiceInitialize] Blocking service shutdown
L10 T2672 2796437 [ServiceInitialize] Blocking service shutdown

Note that the Blocking Service shutdown is the correct behaviour in this particular case. 请注意,在这种特殊情况下,阻止服务关闭是正确的行为。

If I register for PRESHUTDOWN, I get nothing from the ServiceCtrlHandler at all: 如果我注册PRESHUTDOWN,我根本得不到ServiceCtrlHandler:

L0  T2244 516625 [CDbgEntry::LoadSystemDetails()] System Details Follow:

   Computer Name     : \\****
   Domain/Workgroup  : **** [Domain]
   User Name         : SYSTEM
   Operating System  : Windows NT Version 6.1 Build 7600
   Service Pack      : None.
   Terminal Services : Terminal Services Present
   System Root       : C:\Windows\system32
   User's Windir     : C:\Windows


This file is recording debug messages with a maximum level of 10
L10 T2244 516453 [ServiceInitialize] Service initialised, waiting for stop event
L10 T2244 521625 [ServiceInitialize] Still waiting for stop event.
L10 T2244 526625 [ServiceInitialize] Still waiting for stop event.
L10 T2244 531625 [ServiceInitialize] Still waiting for stop event.
L10 T2244 536625 [ServiceInitialize] Still waiting for stop event.
L10 T2244 541625 [ServiceInitialize] Still waiting for stop event.
L10 T2244 546625 [ServiceInitialize] Still waiting for stop event.
L10 T2244 551625 [ServiceInitialize] Still waiting for stop event.
L10 T2244 556625 [ServiceInitialize] Still waiting for stop event.
L10 T2244 561625 [ServiceInitialize] Still waiting for stop event.
L10 T2244 566625 [ServiceInitialize] Still waiting for stop event.
L10 T2244 571625 [ServiceInitialize] Still waiting for stop event.
L10 T2244 576625 [ServiceInitialize] Still waiting for stop event.
L10 T2244 581625 [ServiceInitialize] Still waiting for stop event.
L10 T2244 586625 [ServiceInitialize] Still waiting for stop event.
L10 T2244 591625 [ServiceInitialize] Still waiting for stop event.
L10 T2244 596625 [ServiceInitialize] Still waiting for stop event.
L10 T2244 601625 [ServiceInitialize] Still waiting for stop event.
L10 T2244 606625 [ServiceInitialize] Still waiting for stop event.
L10 T2244 611625 [ServiceInitialize] Still waiting for stop event.
L10 T2244 616625 [ServiceInitialize] Still waiting for stop event.
L10 T2244 621625 [ServiceInitialize] Still waiting for stop event.
L10 T2244 626625 [ServiceInitialize] Still waiting for stop event.
L10 T2244 631625 [ServiceInitialize] Still waiting for stop event.

No events whatsoever, until windows gives up and kills it. 没有任何事件,直到Windows放弃并杀死它。

According to the documentation , SERVICE_CONTROL_PRESHUTDOWN is only sent to the extended callback . 根据文档 ,SERVICE_CONTROL_PRESHUTDOWN仅发送到扩展回调 Try using RegisterServiceCtrlHandlerEx . 尝试使用RegisterServiceCtrlHandlerEx

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将PreShutdown事件添加到ATL服务? - How to add PreShutdown event to ATL service? 如何在Windows服务程序中捕获SERVICE_CONTROL_SHUTDOWN代码 - How to catch SERVICE_CONTROL_SHUTDOWN code in Windows Service Program “SERVICE_CONTROL_SESSIONCHANGE”通知从未在 Windows 10 中的 C++ 服务申请中收到 - "SERVICE_CONTROL_SESSIONCHANGE" notification is never received in C++ service application in Windows 10 如何在Windows 2008 R2中使用CreateVirtualDisk创建差异VHD - How to create a differencing VHD using CreateVirtualDisk in Windows 2008 R2 Windows Service启动过程终止通知(2003,2008) - Windows Service end of starting process notification (2003,2008) Windows Server 2008 r2上BluetoothGetRadioInfo的替代方法 - Alternative to BluetoothGetRadioInfo on Windows Server 2008 r2 Windows 2008 R2中缺少多播消息 - Missing multicast messages in Windows 2008 R2 QCoreApplication事件循环和Windows服务控制处理程序功能 - QCoreApplication event loop and Windows Service Control Handler Function Windows服务,用于控制对“所有用户\\应用程序数据”中文件的访问 - Windows service to control access to a file in “All Users\Application Data” 在 Windows Server 2012 R2 上构建的应用程序在 Windows Server 2008 R2 上失败 - Application built on Windows Server 2012 R2 fails on windows server 2008 R2
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM