2014-09-20 116 views
-2

基本信息:「攔截」Windows關閉並執行命令

語言爲C++(visual C++ 2013)。我的程序是一個win32應用程序,多線程(3線程),並且它的設計作爲關鍵進程運行(使用RtlSetProcessIsCritical,它可以完成這項工作)。我可以編程方式打開和關閉(兩個函數,一個將當前進程設置爲關鍵,第二個將當前進程轉換回非關鍵進程)。

如果我只需點擊開始 - >關閉Windows系統顯然有藍屏死機,你得到同樣的BSOD如果手動終止一個關鍵過程。

我怎麼能當窗口正在關閉/重新啓動檢測?所以我可以執行「轉向非關鍵」功能,導致乾淨的關閉。 :)

一個線程由運行每5秒或10秒的循環,加入Windows關機檢測在這裏的聲音是唯一可行的選擇。

我想的只有一件事,WM_ENDSESSION如下所示http://msdn.microsoft.com/en-us/library/aa376889%28v=VS.85%29.aspx。但它無法檢測到os關閉,並以一個bsod結束。

我會發現一些非常有用的例子或信息。如果需要添加細節,請告訴我,我將在幾個小時內訪問存儲程序的計算機。 謝謝。

編輯:爲什麼downvote?即時學習,並想問一些我不能修復的問題。

編輯:你能提供在哪裏/如何添加實際檢查在我的循環消息的例子嗎?我不能克服這一點,我已經在switch語句中的情況WM_QUERYENDSESSION ..謝謝。

---------------編輯:

我不能得到它的工作,不管什麼我嘗試它不會工作.. 我的僞代碼的程序:

thread 1 
{ 
    functionx(); 
    functiony(); 
} 


thread 2 
{ 
    functionz(); 
    functionf(); 
} 


thread 3 
{ 
    for (;;) 
    { 
     functiong(); 
     functionh(); 
    } 
} 

int main() 
{ 
    thread 1; 
    thread 2; 
    thread 3; 
} 

的部分的GetMessage香港專業教育學院使用的代碼從這裏http://www.winprog.org/tutorial/window_click.html和重新調整,以適合我的需要:

HWND hwnd; 
MSG Msg; 

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 
{ 
    switch (msg) 
    { 
    case WM_QUERYENDSESSION: 
     function_to_turn_critical_process_OFF(); 
     return 0; 
     break; 

    case WM_ENDSESSION: 
     function_to_turn_critical_process_OFF(); 
     return 0; 
     break; 
    } 

    return 0; 
} 

消息循環:

while (GetMessage(&Msg, NULL, 0, 0) > 0) 
{ 
    TranslateMessage(&Msg); 
    DispatchMessage(&Msg); 
} 
return Msg.wParam; 

好吧,如果我在main()中插入消息循環作爲執行的第一件事,我碰到第一個問題,GetMessage似乎把整個事情都放到了睡眠中,所以我的程序甚至不會開始做他的東西。

如果我插入主消息循環()的(在線程3)執行的最後一件事,我碰到的問題2號,因爲線程3永不落幕(永遠循環)的消息循環可能永遠不會發生。此外,線程3循環包含一個小睡幾秒鐘,我試圖把獲取消息循環在那裏,但它無法捕捉它,我不能刪除原來的代碼,不能改變循環或刪除小睡眠功能。

如果我在線程3循環中插入消息循環,它只是無法檢測到WM_QUERYENDSESSION,我最終在Windows關閉BSOD,所以我的「關閉關閉」功能沒有被執行。

我該怎麼辦?谷歌沒有幫助這個特殊的事情。我知道在一個簡單的程序中,我應該把消息循環放在main中,並且它會在最後使用,但是在這裏試圖在我的代碼中找到一個位置來處理這個消息循環。

任何幫助表示讚賞..

+0

您是否在消息循環中收到任何消息?下面的WM_QUERY_ENDSESSION消息答案是正確的。你的程序主要應該創建一個窗口,啓動工作線程,然後執行消息處理循環。當你處理WM_ENDSESSION時,改變應用程序的優先級,也許可以讓線程正常結束(SetEvent或類似的東西)。 – lordjeb 2014-09-23 21:28:40

回答

3

有兩個消息是窗口發送到應用程序:WM_QUERY_ENDSESSIONWM_ENDSESSION

你可以對此作出反應正常退出應用程序。

就你的情況而言,WM_ENDSESSION發生可能已經太遲而無法讓你改變應用的優先級。

在WM_QUERY_ENDSESSION中,系統尚未關閉。所以你可以調整你的設置,然後返回「是的,當然!」。