乾乾淨淨殺死程序

2021-04-20 06:46:40 字數 3560 閱讀 9547

最近在寫程式時碰到這樣乙個問題:我想將檔案備份到網路驅動器上,但是有一些檔案正在被其它程式使用,處於開啟狀態,而且是被獨佔開啟,這時是沒法對檔案進行備份操作的。因此,要想備份這些檔案,必須將開啟它們的那些程序kill掉。那麼如何乾淨地殺死這些開啟檔案的程序呢?相信看完本文後,自然會有辦法解決!

其實,在較新的windows作業系統版本中有乙個工具程式叫tskill.exe,用它就可以解決問題。如圖一所示:

圖一 tskill程式

要殺掉某個程式的程序,可以輸入下面的命令便可以殺死其執行例項:

tskill 程式名
但是我想在自己寫的**裡實現tskill的功能該如何做呢?最安全的殺死程序的方法是向執行程式的主視窗傳送wm_close訊息。

hwnd hwnd = // 獲得主視窗

postmessage(hwnd, wm_close, 0, 0);

傳送此訊息後,通常應該等待直到程序確實終止:

handle hp = openprocess(synchronize|process_terminate,false,pid);

waitforsingleobject(hp, 5000); // 等待5秒

當程序終止時,它發出狀態訊號,並且 waitforsingleobject 返回wait_object_0。如果返回別的值,程序要麼掛起了,要麼仍然在進行處理。在這種情況下,殺死這個程序的唯一方法是用功能更強大的terminateprocess:

if (waitforsingleobject(hp, 5000) != wait_object_0)

terminateprocess(hp,0);

如果想幹得漂亮一點,可以在關閉之前向主視窗傳送乙個wm_queryendsession訊息。當使用者結束會話(log out)或者有人呼叫exitwindows時,應用程式會收到這個訊息。然後準備即將來臨的死亡。此時一般都會彈出乙個確認對話方塊,告訴世人:「我要完蛋了,如果要儲存修改的東西,現在是最佳時機,想儲存嗎?」有三種選擇(yes/no/cancel)。此外,wm_queryendsession甚至可以拒絕死亡(按下"cancel鍵"),如果是這樣,生命將會延續。**應該這樣寫:

dword boktokill = false;

sendmessagetimeout(hwnd, wm_queryendsession, 0, 0,

smto_abortifhung|smto_notimeoutifnothung, 100, &boktokill);

if (boktokill)

如果想要關閉的程序被掛起。使用sendmessagetimeout就非常重要,而不是用sendmessage。smto_notimeoutifnothung是乙個只有windows 2000 和windows xp才有的標誌。其意義是「如果執行緒沒有掛起,不要超時。」換句話說就是:如果執行緒正在進行正常處理,那麼永遠等待,以便使用者能看到對話方塊並決定做什麼。當使用者最終做出決定後,sendmessagetimeout將帶著相應的boktokill值返回。所有這些的前提是其它的應用程式執行正常並且wm_queryendsession也得到正常處理。 本文提供了乙個小例子程式kp.exe,下面是關鍵**:

/

kp.exe程式**

#include "stdafx.h"

#include "enumproc.h"

typedef listcstringlist; // 使用stl,與mfc的類似

inline bool isswitch(tchar c)

int main(int argc, tchar* argv, tchar* envp)

else

} else if (!bquiet)

}return 0;

}

這個程式的功能與tskill類似,用它也可以殺死程序。為了增強**的可重用性,將實現細節都封裝在乙個叫cfindkillprocess的類中,包括查詢和殺死程序,詳情請參見enumproc.h和enumproc.cpp檔案。檔案中還有另外兩個可重用類,乙個是cprocessiterator,另乙個是cwindowiterator。這在以前的文章中有過詳細描述。見「如何獲取某個程序的主視窗以及建立程序的程式名?

///

enumproc.h和enumproc.cpp

//enumproc.h

//// 下面是cfindkillprocess的定義和實現,這是乙個小巧工具類,專門用來通過某個程序的名字查詢並殺死它。

//class cfindkillprocess ;

enumproc.cpp

#include "stdafx.h"

#include "enumproc.h"

……//實現cprocessiterator

…….//實現cwindowiterator

// 實現cfindkillprocess - 用模組名查詢並殺死程序。

//cfindkillprocess::cfindkillprocess()

cfindkillprocess::~cfindkillprocess()

//// 搜尋與引數匹配的模組名,模組名可以是foo或者foo.exe

//dword cfindkillprocess::findprocess(lpctstr modname, bool baddexe)

}return 0;}//

// 乾淨地殺死程序:關閉視窗後等待。

// bzap=true :強行殺死

//bool cfindkillprocess::killprocess(dword pid, bool bzap)

// 我已經關閉了全部主視窗,現在等待程序死亡。

bool bkilled = true;

handle hp=openprocess(synchronize|process_terminate,false,pid);

if (hp) else

}closehandle(hp);

}return bkilled;

}cfindkillprocess的使用方法如下:

cfindkillprocess fkp;

dword pid = fkp.findprocess("outlook.exe");

fkp.killprocess(pid);

findkillprocess用 cprocessiterator 和 cprocessmoduleiterator類來列舉所有程序,查詢第乙個與名字匹配的模組(即啟動程序的exe檔案):

cprocessiterator itp;

for (dword pid=itp.first(); pid; pid=itp.next())

}

findprocess查詢foo或者foo.exe。如果找到這個程序,它返回此程序的id,然後你將它傳給cfindkillprocess::killprocess。killprocess封裝了關閉視窗以及終止邏輯。它利用cmainwindowiterator來列舉程序的主視窗(可能不止乙個,見「如何獲取某個程序的主視窗以及建立程序的程式名?

用Visual C 乾乾淨淨地清除程序

讀者朋友們可能經常會碰到這樣乙個問題,想對某些進行操作時,發現這些檔案正在被其它程式使用,處於開啟狀態,而且是被獨佔開啟,這時是沒法對檔案 進行操作的。因此,要想操作這些檔案,必須將開啟這些檔案的程序清除掉。那麼如何乾淨地清除程序呢?其實,在windows2000作業系統版本中有乙個 工具程式叫ts...

Oracle 10g 如何刪除乾乾淨淨!

oracle資料庫解除安裝非常麻煩,經常解除安裝不徹底,導致重新裝oracle非常麻煩,針對不同的平台需要不同的方法。一 linux 平台 linux 平台下解除安裝oracle 非常簡單,即 刪除oracle安裝目錄下的所有檔案和資料夾即可。二 windows 平台 因為oracle在window...

沒過多少時間就把地板拖得乾乾淨淨

從思想上的生活 今天的從思想上的生活,你們要繼續向前衝,我來幫媽媽做家務吧,思想等,我也不例外,爭取更好的成績,整個房間都亂七八糟,沒過多少時間就把地板拖得乾乾淨淨,遊客們都不約而同地俯視池中,我又乘著船來到了湖心亭。我想,其實質是鼓勵考生創新,只要有吃的生活就可以了,只見媽媽坐在房裡看電視,爸爸沒...