用VisualC 干干净净地清除进程
2008-04-09 04:10:36来源:互联网 阅读 ()
一、实现方法
在Visual C 编程中,最安全的杀死进程的方法是向运行程序的主窗口发送WM_CLOSE消息,其实现代码如下:
HWND hwnd =this.m_hWnd; // 获得主窗口
PostMessage(hwnd, WM_CLOSE, 0, 0);
发送此消息后,通常应该等待直到进程确实终止,当进程终止时,它发出状态信号,并且 WaitForSingleObject 返回WAIT_OBJECT_0。如果返回别的值,进程要么挂起了,要么仍然在进行处理。在这种情况下,杀死这个进程的唯一方法是用功能更强大的API函数:TerminateProcess()。如果想干得漂亮一点,可以在关闭之前向主窗口发送一个WM_QUERYENDSESSION消息,当用户结束会话(log out)或者调用ExitWindows()函数时,应用程序会收到这个消息,然后准备退出进程,此时一般都会弹出一个确认对话框,告诉用户:"程序要推出了,如果要保存修改的东西,现在是最佳时机,想保存吗?"有三种选择(Yes/No/Cancel)。此外,发送WM_QUERYENDSESSION消息可以拒绝推出进程(按下"Cancel键"),如果是这样,进程将会延续。
如果想要关闭的进程被挂起,使用SendMessageTimeout()函数就非常重要,而不是用SendMessage()函数,其参数SMTO_NOTIMEOUTIFNOTHUNG是一个只有Windows 2000 和Windows XP才有的标志。其意义是"如果线程没有挂起,不要超时",换句话说就是如果线程正在进行正常处理,那么永远等待,以便用户能看到对话框并决定做什么,当用户最终做出决定后,SendMessageTimeout()将带着相应的bOKToKill值返回。
本例为了增强代码的可重用性,将实现细节都封装在一个叫CFindKillProcess的类中,包括查找和杀死进程,详情请参见EnumProc.h和EnumProc.cpp文件。文件中还有另外两个可重用类,一个是CProcessIterator,另一个是CWindowIterator。这在实例《获取进程的主窗口以及创建进程的程序名》中有过详细的叙述。
CfindKillProcess类的成员函数FindProcess()查找某个进程序,如果找到这个进程,它返回此进程的ID,然后将此ID传给CFindKillProcess::KillProcess()函数,KillProcess()函数封装了关闭窗口以及终止逻辑,它利用CmainWindowIterator类对象来枚举进程的主窗口(可能不止一个,见"如何获取某个进程的主窗口以及创建进程的程序名?"),并发送WM_CLOSE到每一个窗口,然后等待进程死亡。它有一个布尔型参数用来指示当应用程序进程不愿意退出时是否执行TerminateProcess()函数。详细细节请参见下载的代码。
二、编程步骤
1、 启动Visual C 6.0,生成一个控制台应用程序,将该程序命名为"kp";
2、 在程序代码中添加CfindKillProcess、CProcessIterator类的定义;
3、 添加代码,编译运行程序。
//////////////////////////////////////////////////////
#pragma once
//////////////////
// Process iterator -- iterator over all system processes
// Always skips the first (IDLE) process with PID=0.
class CProcessIterator {
protected:
DWORD* m_pids; // array of procssor IDs
DWORD m_count; // size of array
DWORD m_current; // next array item
public:
CProcessIterator();
~CProcessIterator();
DWORD First();
DWORD Next() {
return m_pids && m_current < m_count ? m_pids[m_current ] : 0;
}
DWORD GetCount() {
return m_count;
}
};
//////////////////
// Handy class to facilitate finding and killing a process by name.
class CFindKillProcess {
public:
CFindKillProcess();
~CFindKillProcess();
DWORD FindProcess(LPCTSTR lpModname, BOOL bAddExe=TRUE);
BOOL KillProcess(DWORD pid, BOOL bZap);
};
////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "EnumProc.h"
// CProcessIterator - Iterates all processes
CProcessIterator::CProcessIterator()
{
m_pids = NULL;
}
CProcessIterator::~CProcessIterator()
{
delete [] m_pids;
}
//////////////////
// Get first process: Call EnumProcesses to init array. Return first one.
DWORD CProcessIterator::First()
{
m_current = (DWORD)-1;
m_count = 0;
DWORD nalloc = 1024;
do {
delete [] m_pids;
m_pids = new DWORD [nalloc];
if (EnumProcesses(m_pids, nalloc*sizeof(DWORD), &m_count)) {
m_count /= sizeof(DWORD);
m_current = 1; // skip IDLE process
}
} while (nalloc <= m_count);
return Next();
}
////////////////////////////////////////////////////////////////
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash