确定哪个应用程序阻止关闭

时间:2009-10-06 04:34:07

标签: c# c++ shutdown

与Windows Vista不同,Windows XP正在关闭时 - 它不会告诉您哪个程序请求不关闭。这使Windows仍在运行,并没有告诉您哪个程序阻止了关机。

据我了解,Windows将WM_QUERYENDSESSION发送给所有应用程序。如果任何应用程序将0返回到该函数,则停止关闭。

我想知道是否有一种从程序中捕获返回值的方法,并确定Windows XP没有关闭的原因。

由于 菲尔

2 个答案:

答案 0 :(得分:3)

枚举所有顶级窗口(使用EnumWindows())并向每个窗口发送WM_QUERYENDSESSION。对于返回阻止值的窗口,检测它是哪个进程。要做后者调用GetWindowThreadProcessId(),枚举所有进程并找到具有该id的进程。

答案 1 :(得分:1)

是。我在this question中发布了代码,但这是代码的改进版本:

void CQes_testDlg::OnBtnTest()  
{  
   // enumerate all the top-level windows.  
   m_ctrl_ListMsgs.ResetContent();  
   EnumWindows (EnumProc, 0);  
}  

BOOL CALLBACK EnumProc (HWND hTarget, LPARAM lParam)
{
   CString csTitle;
   CString csMsg;
   CWnd *  pWnd = CWnd::FromHandle (hTarget);
   BOOL    bRetVal = TRUE;
   DWORD   dwPID;

   if (pWnd)
      pWnd->GetWindowText (csTitle);
   else
      csTitle = TEXT("<unknown>");

   GetWindowThreadProcessId (hTarget, &dwPID);

   if (pWnd->SendMessage (WM_QUERYENDSESSION, 0, ENDSESSION_LOGOFF))
   {
      csMsg.Format ("window 0x%X (PID=%d, Title='%s') returned TRUE", 
                    hTarget, dwPID, csTitle);
   }
   else
   {
      csMsg.Format ("window 0x%X (PID=%d, Title='%s') returned FALSE *******", 
                    hTarget, dwPID, csTitle);
      bRetVal = FALSE;
   }

   mg_pThis->m_ctrl_ListMsgs.AddString (csMsg);
   return bRetVal;
}

mg_p这是一个指向对话框对象的模块全局指针,因此枚举器可以访问它的控件。