【问题标题】:Determine which application is preventing shutdown确定哪个应用程序阻止关机
【发布时间】:2012-08-18 20:53:36
【问题描述】:

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

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

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

谢谢 菲尔

【问题讨论】:

  • 鸡和蛋的问题。任何试图找出阻止关机的进程的程序本身都会阻止关机。

标签: c# c++ shutdown


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    是的。我在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这是一个指向对话框对象的模块全局指针,因此枚举器可以访问它的控件。

    【讨论】:

    • 请注意,每个WM_QUERYENDSESSION 后面必须跟一个WM_ENDSESSION(在这种情况下,表示“会话没有结束”。)
    猜你喜欢
    • 2015-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-09
    • 2015-04-21
    • 2015-11-15
    • 1970-01-01
    相关资源
    最近更新 更多