2012-01-06 22 views
5

Windowsがシャットダウン(またはユーザーがログオフ)したときに正常にシャットダウンするアプリケーションがあります。これは(xpで)動作するのに使用されましたが、昨年、ある時点で誰も気づかずに壊れました。また、当社の製品は、多くの他のプロセスを開始し、メインプロセス(SERVER.EXE)を持つWindows 7の下で(違ったけど)Windowsがシャットダウンしたときのアプリケーションのシャットダウン

を破っています。グレースフルシャットダウンでは、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の下で動作させるが、私は両方のOSのために機能するソリューションを持つことができますので、それはXPの下で破っている理由を把握したいと思います。

助けが必要ですか?

+1

何らかの理由でWindowsが別の順序でプロセスをシャットダウンしているだけでも問題ありませんか?あなたの 'server.exe'がWindowsが最初にシャットダウンすることを保証するものは何ですか? –

+0

ソース管理にこのビットのコードがある可能性はありますか?あなたは少なくとも、昨年に変更されているかどうかを見ることができますか? –

+0

ない他の人の前にSERVER.EXEシャットダウンを作っていたかわから... –

答えて

3

物事は、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

これはほとんど動作します... –

+0

XPの下でこれは素晴らしい作品です。 Windows 7では、動作は同じです。 –

+0

私はこれがWin7で動作することを知っています。何か他のものがあなたを襲って、推測するのは難しい。 –

関連する問題