用Visual C 干干净净地清除进程

2008-02-23 05:39:29来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

  读者朋友们可能经常会碰到这样一个问题,想对某些进行操作时,发现这些文档正在被其他程式使用,处于打开状态,而且是被独占打开,这时是没法对文档进行操作的。因此,要想操作这些文档,必须将打开这些文档的进程清除掉。那么如何干净地清除进程呢?其实,在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消息,当用户结束会话(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);

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇: C语言编程易犯毛病集合

下一篇: C 词汇解析集锦 编程研发人员必备[6]