用VisualC++干干净净地清除进程
读者可能经常会遇到这样的问题。当他们想操作某个东西时,发现这些文件正在被其他程序使用,处于打开状态,被独占打开。此时,他们无法操作文件。因此,为了操作这些文件,必须清除打开这些文件的过程。那么如何清理流程呢?其实在Windows2000操作系统版本中有一个叫tskill.exe的工具,可以用来清除某个程序的进程,输入“tskill程序名”就可以清除它的运行实例。但是如何在代码中实现tskill的功能呢?为了解决这个问题,本例介绍了在Windows2000下实现的方法。
一、实施方法
在VisualC++编程中,终止一个进程最安全的方法是向程序运行的主窗口发送WM_CLOSE消息。其实现代码如下:
HWND hwnd = this.m _ hWnd//获取主窗口postmessage (hwnd,wm _ close,0,0);
发送此消息后,通常应该等到进程终止。当进程终止时,它发送一个状态信号,WaitForSingleObject返回WAIT_OBJECT_0。如果返回另一个值,进程要么被挂起,要么仍在处理中。在这种情况下,杀死这个进程的方法是使用一个更强大的API函数:TerminateProcess()。如果你想做得更好,你可以在关闭前发送一个WM_QUERYENDSESSION消息到主窗口。当用户完成会话(注销)或调用ExitWindows()函数时,应用程序将收到此消息,然后准备退出该进程。这时候一般会弹出一个确认对话框,告诉用户:“程序要启动了。如果你想保存修改过的东西,现在正是时候。要不要救?”有三个选项(是/否/取消)。另外,发送WM_QUERYENDSESSION消息可以拒绝推出进程(按“取消键”),如果是,进程将继续。
如果要关闭的进程被挂起,使用SendMessageTimeout()函数而不是SendMessage()函数是非常重要的。它的参数SMTO_NOTIMEOUTIFNOTHUNG是一个仅在Windows 2000和Windows XP中可用的符号。它的意思是“如果线程没有挂起,就不要超时”。换句话说,如果线程正在正常处理,就永远等待,以便用户可以看到对话框并决定做什么。当用户最终做出决定时,SendMessageTimeout()将返回相应的bOKToKill值。
为了增强代码的可重用性,这个例子将实现细节封装在一个名为CFindKillProcess的类中,包括查找和杀死进程。详细内容请参考EnumProc.h和EnumProc.cpp文件。文件中还有另外两个可重用的类,一个是CProcessIterator,另一个是CWindowIterator。这在示例“获取进程的主窗口并创建进程的程序名”中有详细描述。
CfindKillProcess类的成员函数FindProcess()查找传入的程序。如果找到了这个进程,它将返回这个进程的ID,然后将这个ID传递给CFindKillProcess::KillProcess()函数,该函数封装了关闭窗口和终止逻辑。它使用CmainWindowIterator类对象来枚举一个进程的主窗口(可能不止一个,参见“如何获取一个进程的主窗口并创建一个进程的程序名?”),并向每个窗口发送WM_CLOSE,然后等待进程死亡。它有一个布尔参数,用来指示当应用程序进程不愿意退出时,是否执行TerminateProcess()函数。有关详细信息,请参见下载的代码。
二、编程步骤
1.启动Visual C++6.0,生成一个控制台应用程序,将程序命名为“KP”;
2.在程序代码中添加CfindKillProcess和CProcessIterator类的定义;
3.添加代码,编译并运行程序。
0条评论