簡體   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

我正在使用普通的C ++和Windows API編寫服務,並希望它接收可從Windows 2008 R2獲得的PRESHUTDOWN通知。

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

我希望該服務處理關機前事件,並防止計算機在任意時間內完成關機。

我的ServiceMain循環,每5秒注銷一條消息。

我將dwControls設置為:

SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PRESHUTDOWN

我在ServiceControl回調中收到SERVICE_CONTROL_STOP通知就好了。

如果我運行我的服務,然后致電

sc query "MyService"

它說:

(STOPPABLE, NOT_PAUSABLE, ACCEPTS_PRESHUTDOWN)

我收到任何服務控制通知后立即寫入日志文件的條目,然后我才會看到它是什么。

當我關機時,Windows會在屏幕上用大的白色字母說“停止MyService”,等待一下,然后完成關機。

然而:

主循環繼續寫入日志文件。 日志文件不包含任何服務控制嘗試的引用。

然后,Windows放棄了關閉我的服務並終止了它。

現在,如果我做完全相同的事情,但是注冊了SHUTDOWN而不是PRESHUTDOWN,我會在日志文件中看到我希望看到的所有通知(盡管不能延長關閉時間,因為我們不能這樣做)從關機通知中)。

對代碼的唯一更改是在設置狀態調用中​​刪除三個字母“PRE”。

我什至無法開始增加dwCheckPoint的程度-Windows子系統沒有通知我。

Windows知道我正在尋找預關閉消息,正如“sc查詢”所證明的那樣,有什么東西可以阻止它接收預關閉消息嗎?

相關方法:

報告狀態時(很高興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);
}

當我收到消息時:

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;
          }
    }
}

它做的更多,但對於這個例子沒什么用,因為我甚至沒有看到日志(除非我注冊SHUTDOWN)。

ServiceCtrlHandler總是快速返回,我在這里沒有阻塞,我沒有進入這里進行預關閉處理程序。 同時注冊PRESHUTDOWN和SHUTDOWN也無濟於事。 我已經在兩台Windows 2008R2計算機,一台虛擬機,一台物理計算機上嘗試了此方法,並且結果相同。 服務被編譯為x64二進制文件。

有任何想法嗎?

一些示例日志,這個日志是我請求收到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

請注意,在這種特殊情況下,阻止服務關閉是正確的行為。

如果我注冊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.

沒有任何事件,直到Windows放棄並殺死它。

根據文檔 ,SERVICE_CONTROL_PRESHUTDOWN僅發送到擴展回調 嘗試使用RegisterServiceCtrlHandlerEx

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM