讀者朋友們可能經(jīng)常會(huì)碰到這樣一個(gè)問題,想對(duì)某些進(jìn)行操作時(shí),發(fā)現(xiàn)這些文件正在被其它程序使用,處于打開狀態(tài),而且是被獨(dú)占打開,這時(shí)是沒法對(duì)文件進(jìn)行操作的。因此,要想操作這些文件,必須將打開這些文件的進(jìn)程清除掉。那么如何干凈地清除進(jìn)程呢?其實(shí),在Windows2000操作系統(tǒng)版本中有一個(gè)工具程序叫tskill.exe,用它就可以清除掉某個(gè)程序的進(jìn)程,在輸入“tskill 程序名”后就可以清除其運(yùn)行實(shí)例。但是如何要在代碼里實(shí)現(xiàn)tskill的功能該如何做呢?針對(duì)這一問題,本實(shí)例介紹了在Windows2000下實(shí)現(xiàn)的方法。
一、實(shí)現(xiàn)方法
在VisualC++編程中,最安全的殺死進(jìn)程的方法是向運(yùn)行程序的主窗口發(fā)送WM_CLOSE消息,其實(shí)現(xiàn)代碼如下:
HWND hwnd =this.m_hWnd; // 獲得主窗口PostMessage(hwnd, WM_CLOSE, 0, 0);
發(fā)送此消息后,通常應(yīng)該等待直到進(jìn)程確實(shí)終止,當(dāng)進(jìn)程終止時(shí),它發(fā)出狀態(tài)信號(hào),并且 WaitForSingleObject 返回WAIT_OBJECT_0。如果返回別的值,進(jìn)程要么掛起了,要么仍然在進(jìn)行處理。在這種情況下,殺死這個(gè)進(jìn)程的方法是用功能更強(qiáng)大的API函數(shù):TerminateProcess()。如果想干得漂亮一點(diǎn),可以在關(guān)閉之前向主窗口發(fā)送一個(gè)WM_QUERYENDSESSION消息,當(dāng)用戶結(jié)束會(huì)話(log out)或者調(diào)用ExitWindows()函數(shù)時(shí),應(yīng)用程序會(huì)收到這個(gè)消息,然后準(zhǔn)備退出進(jìn)程,此時(shí)一般都會(huì)彈出一個(gè)確認(rèn)對(duì)話框,告訴用戶:"程序要推出了,如果要保存修改的東西,現(xiàn)在是時(shí)機(jī),想保存嗎?"有三種選擇(Yes/No/Cancel)。此外,發(fā)送WM_QUERYENDSESSION消息可以拒絕推出進(jìn)程(按下"Cancel鍵"),如果是這樣,進(jìn)程將會(huì)延續(xù)。
如果想要關(guān)閉的進(jìn)程被掛起,使用SendMessageTimeout()函數(shù)就非常重要,而不是用SendMessage()函數(shù),其參數(shù)SMTO_NOTIMEOUTIFNOTHUNG是一個(gè)只有Windows 2000 和Windows XP才有的標(biāo)志。其意義是"如果線程沒有掛起,不要超時(shí)",換句話說就是如果線程正在進(jìn)行正常處理,那么永遠(yuǎn)等待,以便用戶能看到對(duì)話框并決定做什么,當(dāng)用戶最終做出決定后,SendMessageTimeout()將帶著相應(yīng)的bOKToKill值返回。
本例為了增強(qiáng)代碼的可重用性,將實(shí)現(xiàn)細(xì)節(jié)都封裝在一個(gè)叫CFindKillProcess的類中,包括查找和殺死進(jìn)程,詳情請(qǐng)參見EnumProc.h和EnumProc.cpp文件。文件中還有另外兩個(gè)可重用類,一個(gè)是CProcessIterator,另一個(gè)是CWindowIterator。這在實(shí)例《獲取進(jìn)程的主窗口以及創(chuàng)建進(jìn)程的程序名》中有過詳細(xì)的敘述。
CfindKillProcess類的成員函數(shù)FindProcess()查找某個(gè)進(jìn)程序,如果找到這個(gè)進(jìn)程,它返回此進(jìn)程的ID,然后將此ID傳給CFindKillProcess::KillProcess()函數(shù),KillProcess()函數(shù)封裝了關(guān)閉窗口以及終止邏輯,它利用CmainWindowIterator類對(duì)象來枚舉進(jìn)程的主窗口(可能不止一個(gè),見"如何獲取某個(gè)進(jìn)程的主窗口以及創(chuàng)建進(jìn)程的程序名?"),并發(fā)送WM_CLOSE到每一個(gè)窗口,然后等待進(jìn)程死亡。它有一個(gè)布爾型參數(shù)用來指示當(dāng)應(yīng)用程序進(jìn)程不愿意退出時(shí)是否執(zhí)行TerminateProcess()函數(shù)。詳細(xì)細(xì)節(jié)請(qǐng)參見下載的代碼。
二、編程步驟
1、啟動(dòng)Visual C++6.0,生成一個(gè)控制臺(tái)應(yīng)用程序,將該程序命名為"kp";
2、在程序代碼中添加CfindKillProcess、CProcessIterator類的定義;
3、添加代碼,編譯運(yùn)行程序。
一、實(shí)現(xiàn)方法
在VisualC++編程中,最安全的殺死進(jìn)程的方法是向運(yùn)行程序的主窗口發(fā)送WM_CLOSE消息,其實(shí)現(xiàn)代碼如下:
HWND hwnd =this.m_hWnd; // 獲得主窗口PostMessage(hwnd, WM_CLOSE, 0, 0);
發(fā)送此消息后,通常應(yīng)該等待直到進(jìn)程確實(shí)終止,當(dāng)進(jìn)程終止時(shí),它發(fā)出狀態(tài)信號(hào),并且 WaitForSingleObject 返回WAIT_OBJECT_0。如果返回別的值,進(jìn)程要么掛起了,要么仍然在進(jìn)行處理。在這種情況下,殺死這個(gè)進(jìn)程的方法是用功能更強(qiáng)大的API函數(shù):TerminateProcess()。如果想干得漂亮一點(diǎn),可以在關(guān)閉之前向主窗口發(fā)送一個(gè)WM_QUERYENDSESSION消息,當(dāng)用戶結(jié)束會(huì)話(log out)或者調(diào)用ExitWindows()函數(shù)時(shí),應(yīng)用程序會(huì)收到這個(gè)消息,然后準(zhǔn)備退出進(jìn)程,此時(shí)一般都會(huì)彈出一個(gè)確認(rèn)對(duì)話框,告訴用戶:"程序要推出了,如果要保存修改的東西,現(xiàn)在是時(shí)機(jī),想保存嗎?"有三種選擇(Yes/No/Cancel)。此外,發(fā)送WM_QUERYENDSESSION消息可以拒絕推出進(jìn)程(按下"Cancel鍵"),如果是這樣,進(jìn)程將會(huì)延續(xù)。
如果想要關(guān)閉的進(jìn)程被掛起,使用SendMessageTimeout()函數(shù)就非常重要,而不是用SendMessage()函數(shù),其參數(shù)SMTO_NOTIMEOUTIFNOTHUNG是一個(gè)只有Windows 2000 和Windows XP才有的標(biāo)志。其意義是"如果線程沒有掛起,不要超時(shí)",換句話說就是如果線程正在進(jìn)行正常處理,那么永遠(yuǎn)等待,以便用戶能看到對(duì)話框并決定做什么,當(dāng)用戶最終做出決定后,SendMessageTimeout()將帶著相應(yīng)的bOKToKill值返回。
本例為了增強(qiáng)代碼的可重用性,將實(shí)現(xiàn)細(xì)節(jié)都封裝在一個(gè)叫CFindKillProcess的類中,包括查找和殺死進(jìn)程,詳情請(qǐng)參見EnumProc.h和EnumProc.cpp文件。文件中還有另外兩個(gè)可重用類,一個(gè)是CProcessIterator,另一個(gè)是CWindowIterator。這在實(shí)例《獲取進(jìn)程的主窗口以及創(chuàng)建進(jìn)程的程序名》中有過詳細(xì)的敘述。
CfindKillProcess類的成員函數(shù)FindProcess()查找某個(gè)進(jìn)程序,如果找到這個(gè)進(jìn)程,它返回此進(jìn)程的ID,然后將此ID傳給CFindKillProcess::KillProcess()函數(shù),KillProcess()函數(shù)封裝了關(guān)閉窗口以及終止邏輯,它利用CmainWindowIterator類對(duì)象來枚舉進(jìn)程的主窗口(可能不止一個(gè),見"如何獲取某個(gè)進(jìn)程的主窗口以及創(chuàng)建進(jìn)程的程序名?"),并發(fā)送WM_CLOSE到每一個(gè)窗口,然后等待進(jìn)程死亡。它有一個(gè)布爾型參數(shù)用來指示當(dāng)應(yīng)用程序進(jìn)程不愿意退出時(shí)是否執(zhí)行TerminateProcess()函數(shù)。詳細(xì)細(xì)節(jié)請(qǐng)參見下載的代碼。
二、編程步驟
1、啟動(dòng)Visual C++6.0,生成一個(gè)控制臺(tái)應(yīng)用程序,將該程序命名為"kp";
2、在程序代碼中添加CfindKillProcess、CProcessIterator類的定義;
3、添加代碼,編譯運(yùn)行程序。