2009-10-06 2 views
4

В отличие от Windows Vista, когда Windows XP завершает работу - это не говорит вам, какая программа запрашивает не останавливаться. Это приводит к тому, что Windows все еще работает и не сообщает, какая программа предотвращает выключение.Определите, какое приложение предотвращает выключение

Как я понимаю, Windows отправляет WM_QUERYENDSESSION во все приложения. Если какое-либо из приложений возвращает 0 в функцию, остановка приостанавливается.

Мне интересно, есть ли способ захватить возвращаемые значения из программ и определить, почему Windows XP не отключается.

Благодаря Фил

+0

Проблемы с курицей и яйцом. Любая программа, которая попытается выяснить, какой процесс предотвращает выключение, сама предотвратит выключение. –

ответ

3

Перечислить все окна верхнего уровня (используйте EnumWindows()) и отправить WM_QUERYENDSESSION каждому. Для окна, которое возвращает значение предотвращения, определяет, какой процесс он выполняет. Чтобы сделать последний вызов GetWindowThreadProcessId(), перечислите все процессы и найдите процесс с этим идентификатором.

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_pThis представляет собой модуль глобального указателя на объект диалога, так что переписчик может получить доступ к его контролирует.

+0

Обратите внимание, что за каждой 'WM_QUERYENDSESSION' должна следовать' WM_ENDSESSION' (в данном случае, говоря, что сеанс не заканчивается). –

Смежные вопросы