最近在写程序时碰到这样一个问题:我想将文件备份到网络驱动器上,但是有一些文件正在被其它程序使用,处于打开状态,而且是被独占打开,这时是没法对文件进行备份操作的。因此,要想备份这些文件,必须将打开它们的那些进程kill掉。那么如何干净地杀死这些打开文件的进程呢?相信看完本文后,自然会有办法解决! 其实,在较新的Windows操作系统版本中有一个工具程序叫tskill.exe,用它就可以解决问题。如图一所示: 11.gif (9.91 KB) 2008-6-30 14:38 图一 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) { // 发送WM_CLOSE 并等待 } 如果想要关闭的进程被挂起。使用SendMessageTimeout就非常重要,而不是用SendMessage。 SMTO_NOTIMEOUTIFNOTHUNG是一个只有Windows 2000 和Windows XP才有的标志。其意义是“如果线程没有挂起,不要超时。”换句话说就是:如果线程正在进行正常处理,那么永远等待,以便用户能看到对话框并决定做什么。当用户最终做出决定后,SendMessageTimeout将带着相应的bOKToKill值返回。所有这些的前提是其它的应用程序运行正常并且 WM_QUERYENDSESSION也得到正常处理。 本文提供了一个小例子程序kp.exe,下面是关键代码: ///////////////////////////////////////////// kp.exe程序代码 //////////////////////////////////////////// #include "stdafx.h" #include "EnumProc.h" typedef list CStringList; // 使用STL,与MFC的类似 inline BOOL isswitch(TCHAR c) { return c==L''''''''/'''''''' || c==L''''''''-''''''''; } int main(int argc, TCHAR* argv[], TCHAR* envp[]) { CStringList cmdargs; // 命令行参数 (要杀死的进程,可以多个) BOOL bDisplayOnly=FALSE; // 不杀,只是显示 BOOL bQuiet=FALSE; // 禁止出错信息 BOOL bZap=FALSE; // 强行杀死 // 解析命令行开关,开关顺序可以任意 for (int i=1; i

评论