从XP到Win7的变化(在XP中程序可以阻止关机,但是在Win7中程序无法阻止关机,可

时间:2021-12-24 06:50:07

之前写了一个软件用于实验室的打卡提醒,其中一个重要的功能是在关机之前提醒当天晚上是否已经打卡。之前我是在WM_ENDSESSION中弹出一个模态对话框来提醒,在XP中基本工作正常,在Win7中大多数时候工作正常,但是有时候会出现不提醒现象。我想这中间是不是有什么玄机,Windows的关机方案从XP到Win7到底发生了什么变化,如何进行有效的截获Windows关机消息。对此,我搜寻了MSDN和网上论坛结合自己的测评给出一个完善的描述和解决方案,如果你有类似的需求,可以参考这篇文章。

在MSDN中对于Windows关机行为的变化描述只有对比Vista和XP(这是链接),但是实际评测,显示这个描述文档对于大家有强的误导性,因为他只有部分是正确的,也不用奇怪,微软的文档错误多多,XX微软,请的实习生写的文档吗?如果你不想看这篇误导性文章,直接往下面看即可。

为了反映实际的关机行为,我写了一个小的截获软件,部分代码如下

[cpp]  

 

 

从XP到Win7的变化(在XP中程序可以阻止关机,但是在Win7中程序无法阻止关机,可

从XP到Win7的变化(在XP中程序可以阻止关机,但是在Win7中程序无法阻止关机,可

BOOL CEndSessionDlg::OnQueryEndSession()   

{  

//  if (!CDialog::OnQueryEndSession())  

//      return FALSE;  

      

    //记录关机选项和时间  

    CTime time = CTime::GetCurrentTime();  

    CString csTemp;  

    csTemp.Format(TEXT(".\\%d.txt"), m_hWnd);  

    CFile f( csTemp, CFile::modeCreate | CFile::modeWrite );  

    m_csOutput.Format(TEXT("%d-%d-%d\tWM_QUERYENDSESSION\tTIME:%d-%d-%d-%d-%d-%d\r\n"),  

        m_queryBlock,  

        m_returnTrue,  

        m_endBlock,  

        time.GetYear(),  

        time.GetMonth(),  

        time.GetDay(),  

        time.GetHour(),  

        time.GetMinute(),  

        time.GetSecond());  

    f.Write(m_csOutput.GetBuffer(256), m_csOutput.GetLength()*sizeof(TCHAR));  

  

    if (m_queryBlock == TRUE)  

    {  

        MessageBox(TEXT("WM_QUERYENDSESSION中Block Shutdown"));  

    }  

  

    if (m_returnTrue == TRUE)  

    {  

        return TRUE;  

    }  

    else  

    {  

        return FALSE;  

    }  

}  

  

void CEndSessionDlg::OnEndSession(BOOL bEnding)   

{  

    //CDialog::OnEndSession(bEnding);  

  

    //记录关机选项和时间  

    CTime time = CTime::GetCurrentTime();  

    CString csTemp;  

    csTemp.Format(TEXT(".\\%d.txt"), m_hWnd);  

    CFile f( csTemp, CFile::modeCreate | CFile::modeWrite );  

    csTemp.Format(TEXT("%d-%d-%d\tWM_ENDSESSION\t\tTIME:%d-%d-%d-%d-%d-%d\r\n"),  

        m_queryBlock,  

        m_returnTrue,  

        m_endBlock,  

        time.GetYear(),  

        time.GetMonth(),  

        time.GetDay(),  

        time.GetHour(),  

        time.GetMinute(),  

        time.GetSecond());  

    m_csOutput += csTemp;  

    f.Write(m_csOutput.GetBuffer(256), m_csOutput.GetLength()*sizeof(TCHAR));  

      

    if (m_endBlock == TRUE)  

    {  

        csTemp.Format(TEXT("WM_ENDSESSION中Block Shutdown---bEnding=%d"), bEnding);  

        MessageBox(csTemp);  

    }  

}  

软件界面如下