当Windows关闭时,优雅的应用程序关闭

问题描述:

我有一个应用程序,当Windows关闭(或用户注销)时,我想优雅地关闭该应用程序。这曾经工作(在XP中),但在去年的某个时候它打破了,没有人注意到。在Windows 7下它也破碎了(但不同)。当Windows关闭时,优雅的应用程序关闭

我们的产品有一个启动许多其他进程的主进程(server.exe)。正常的关闭会让server.exe询问它开始关闭的所有进程。但是,当我调试此代码时,似乎其他进程已被终止。我们的主进程(server.exe)是处理WM_QUERYENDSESSION和WM_ENDSESSION消息的唯一进程。下面的代码(这个曾经在XP下工作,但没有任何更多):

LRESULT CALLBACK master_wnd_proc 
(
    HWND hwnd,  /* (in) handle to window */ 
    UINT uMsg,  /* (in) message identifier */ 
    WPARAM wParam, /* (in) first message parameter */ 
    LPARAM lParam /* (in) second message parameter */ 
) 
{ 
    LRESULT result; /* return value */ 
    long msg_code; 

    switch (uMsg) 
    { 
     case WM_ENDSESSION: 
     if (wParam) 
     { 
      msg_code = PCS_WINDOWS_SHUTDOWN; 
      if(lParam & 0x01L) 
       msg_code = WINDOWS_SHUT_CLOSE; 
      if(lParam & 0x40000000L) 
       msg_code = WINDOWS_SHUT_CRIT; 
      if((unsigned long)lParam & 0x80000000) 
       msg_code = WINDOWS_SHUT_LOGOFF; 
      MsgGenerate(msg_code, MSG_SEVERE, MSG_LOG, ""); 

      ipc_declare_shutdown(msg_code); 

      //We need one more message in the message queue 
      //to force the message loop, below, to exit. 
      PostQuitMessage(EXIT_SUCCESS); 

      /* WARNING: Don't call MsgGenerate() after this point! */ 
     } 
     result = 0; 
     break; 

     case WM_QUERYENDSESSION: 

     /* return TRUE to say "okay to shutdown" 
      * If FALSE is returned, then other processes are not stopped 
      * and the session isn't ended. 
      */ 
     result = TRUE; 
     break; 

     /* for a Windows TIMER or for an IPC prompt, handle 
     * the old server code and tcall messages and 
     * once-per-second work. Notice that the 
     * once-per-second work could just be done on the WM_TIMER 
     * and the tcall work could just be done on the WM_APP_IPC_POSTED 
     * but I've merged them together here. The merge isn't 
     * necessary to fix a bug or anything, but rather to 
     * make the code more robust in the face of unexpected 
     * conditions. 
     */ 
     case WM_TIMER: 
     case WM_APP_IPC_POSTED: 
     /* now handle tcall messages */ 
     (void) server(); 

     result = FALSE; 
     break; 

     default: 
     result = DefWindowProc (hwnd, uMsg, wParam, lParam); 
     break; 
    } 

    return result; 
} 

这好像我们已经在过去的一年改为东西将要求所有的子进程来处理WM_QUERYENDSESSION消息(我真的想避免这一点)。我似乎无法找到有关进程何时或没有收到此消息的任何信息。

我已经使用新的API在Windows 7下工作,但想弄清楚为什么它在XP下破解,所以我可以有一个适用于这两个操作系统的解决方案。

任何帮助?

+1

难道只是因为某些原因,Windows以不同的顺序关闭进程?有什么可以保证你的'server.exe'是Windows关闭的第一件事情? – 2012-01-06 16:06:44

+0

在源代码控制中你有这么点代码的可能性吗?你至少可以看到它在去年是否发生了变化? – 2012-01-06 16:14:15

+0

不知道是什么使得server.exe在其他人之前关机...... – 2012-01-06 17:30:16

事情围绕Vista时代发生了变化,不太确定这将如何影响您的代码。最好的办法就是不要让Windows确定关机顺序。只是要求它让你的服务器在辅助进程之前得到关机通知:

DWORD dwLevel, dwFlags; 
    BOOL fOkay = GetProcessShutdownParameters(&dwLevel, &dwFlags); 
    ASSERT(fOkay); 
    if (fOkay && dwLevel > 0x100) { 
     fOkay = SetProcessShutdownParameters(dwLevel + 1, SHUTDOWN_NORETRY); 
     ASSERT(fOkay); 
    } 
+0

这几乎可以... – 2012-01-06 17:11:24

+0

在XP下,这个工程很好。在Windows 7下,行为仍然相同。 – 2012-01-06 17:12:27

+0

我知道这适用于Win7。别的东西让你烦恼,很难猜到。 – 2012-01-06 17:21:01