如何「乾淨地」終止 Win32 中的應用程式

2021-04-20 05:31:44 字數 2683 閱讀 1861

如何「乾淨地」終止 win32 中的應用程式

編譯:northtibet摘要

32 位程序(和 windows 95 下的 16 位程序)

16 位問題(在 windows nt 下)

示例**

摘要

在理想環境中,某一程序可能會通過某種形式的程序間通訊要求另一程序關閉。不過,如果你對希望其關閉的應用程式沒有源**級控制權,可能就沒有辦法做這樣的選擇。儘管沒有哪種方法能保證「乾淨地」關閉 win32 中的應用程式,但你可以採取一些步驟來確保應用程式使用最佳方法清除資源。

32 位程序(和 windows 95 下的 16 位程序)

在 win32 下,作業系統可保證在程序關閉時清除程序所擁有的資源。但是,這並不意味著程序本身將有機會對磁碟執行任何最後的資訊重新整理或通過遠端連線執行任何最後的通訊,也不意味著程序的 dll 將有機會執行其 process_detach **。這就是通常最好避免在 windows 95 和 windows nt 下終止應用程式的原因。

如果你必須關閉程序,請按照下列步驟操作:

向你打算關閉的程序所擁有的所有頂級視窗傳送一條 wm_close 訊息。許多 windows 應用程式會通過關閉它自身來響應此訊息。

注意:控制台應用程式對 wm_close 的響應取決於它是否安裝了控制處理程式。

使用 enumwindows() 找到目標視窗的控制代碼。在**函式中,檢查該視窗的程序 id 是否與要關閉的程序相匹配。你可以通過呼叫 getwindowthreadprocessid() 來執行此操作。確定匹配項後,使用 postmessage() 或 sendmessagetimeout() 向該視窗傳送 wm_close 訊息。

使用 waitforsingleobject() 等待程序的控制代碼。確保你使用超時值等待,因為在很多情況下 wm_close 不會關閉應用程式。記住,應使超時值足夠長(通過 waitforsingleobject() 或 sendmessagetimeout()),以便使用者可以響應為了 處理 wm_close 訊息而建立的任何對話方塊。

如果返回值為 wait_object_0,則應用程式已乾淨地將其自身關閉。如果返回值為 wait_timeout,則必須使用 terminateprocess() 關閉應用程式。

注意:如果從 waitforsingleobject() 得到的返回值不是 wait_object_0 或 wait_timeout,則應使用 getlasterror() 找出原因。

通過執行上述這些步驟,你便完全有可能乾淨地關閉應用程式(無需 ipc 或使用者干預)。

16 位問題(在 windows nt 下)

上述步驟適用於 windows 95 下的 16 位應用程式,而 windows nt 下的 16 位應用程式與 windows 95 下的 16 位應用程式的工作方式差別非常大。

在 windows nt 下,所有 16 位應用程式都在虛擬 dos 機 (vdm) 中執行。此 vdm 是作為 windows nt 下的乙個 win32 程序 (ntvdm) 執行的。ntvdm 程序具有程序 id。你可以通過 openprocess() 獲取該程序的控制代碼,就像處理其它任何 win32 程序一樣。不過,在 vdm 中執行的 16 位應用程式都沒有程序 id,因此你無法從 openprocess() 獲取程序控制代碼。vdm 中的每個 16 位應用程式都有乙個 16 位任務控制代碼和乙個 32 位執行執行緒。可通過呼叫函式 vdmenumtaskwowex() 找到該任務控制代碼和執行緒 id。有關這方面的其它資訊,請參見:「

如何用 win32 apis 列舉應用程式視窗和程序」。

關閉 windows nt 下的 16 位應用程式的首選和最直接的方法是關閉整個 ntvdm 程序。你可以通過執行前面所描述的步驟來完成此操作。你只需知道 ntvdm 的程序 id 即可,參考「

如何用 win32 apis 列舉應用程式視窗和程序」所講的方法來查詢 ntvdm 的程序 id。此方法的缺點是它會關閉在該 vdm 中執行的所有 16 位應用程式。如果這不是你想要的結果,則需要採取其它方法。

如果你希望關閉 ntvdm 程序中的單個 16 位應用程式,需要按照下列步驟操作:

向該程序所擁有的以及與你要關閉的 16 位任務具有相同執行緒 id 的所有頂級視窗傳送一條 wm_close 訊息。執行此操作最有效的方法是使用 enumwindows()。在**函式中,檢查視窗的程序 id 和執行緒 id 是否與要關閉的 16 位任務相匹配。請記住,該程序 id 將成為在其中執行 16 位應用程式的 ntvdm 的程序 id。

儘管你有執行緒 id,但無法等待 16 位程序的終止。因此,你必須等待任意時間長度(以允許乾淨關閉),然後嘗試關閉應用程式。如果應用程式已關閉,則此操作無效。如果應用程式尚未關閉,則它將終止應用程式。

使用稱為 vdmterminatetaskwow() 的函式終止應用程式,該函式可在 vdmdbg.dll 中找到。它採用 vdm 的程序 id 和 16 位任務的任務編號。

此方法允許你關閉 windows nt 下 vdm 中的單個 16 位應用程式。不過,16 位 windows 以及 vdm 中執行的 wowexec 都不能有效地清除已終止任務的資源。如果你要尋找最有可能乾淨地終止 windows nt 下的 16 位應用程式的方法,應考慮終止整個 vdm 程序。注意:如果你要啟動以後可能會終止的 16 位應用程式,請將 create_separate_wow_vdm 與 createprocess() 結合使用。

示例**

Win32中的listbox學習

列表框樣式 visual studio 2013 其他版本 當列表框不包含足夠的項滾動時,lbs disablenoscroll列表框顯示乙個禁用的垂直滾動條。若無此樣式,當列表框不包含足夠的項時,滾動條將隱藏。使用 shift 鍵和滑鼠或特定組合鍵lbs extendedsel,使用者可以選擇多個...

win32中對「控制代碼」的理解

1 win32中的控制代碼在數值上表示乙個32位的數,用來標識應用程式 程序中不同物件以及同類物件中的不同例項,而所謂例項就是指被例項化的物件,例項化的過程就是通過類建立物件的過程。例項化物件的目地是為物件開闢記憶體空間。所以控制代碼是指向一片記憶體空間的。乙個視窗,按鈕,圖示,滾動條,輸出裝置,控...

對WIN32中視窗的理解

寫這篇文章記錄下對win32程式設計視窗的理解。寫這篇文章的時候我正在使用mfc編寫乙個適合我自己使用的任務清單軟體。是的你沒聽錯,就是十幾年前你就已經聽到的mfc,現在都老掉牙的mfc,新開發的程式已經沒人用的mfc,還有一大堆基於其開發並且現在還需要維護的mfc。以前一直不太理解視窗的概念,直白...