关闭指定进程的方法

方法有好几种:最简单的就是获得窗口的句柄之后,那么可以使用向该窗体发送WM_CLOSE消息的进行进程的关闭。

下面是几种比较强制杀死的方法:

结束进程的函数BOOL TerminateProcess( HANDLE hProcess, UINT uExitCode );

 这个函数要求一个进程的handle。而进程的handle可以用进程的ID通过下面的函数来得到。

  HANDLE OpenProcess( DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId );

而这个函数又需要进程的ID,而进程的ID可以通过进程name来的到,也即是通过任务管理器里面的进程的名字来得到。 至于如何通过进程的name,如,QQ.exe。来得到进程的ID则可以用如下方法。 思路如下,通过如下函数得到系统进程的一个快照。

HANDLE WINAPI CreateToolhelp32Snapshot( DWORD dwFlags, DWORD th32ProcessID );

通过如下的两个函数来遍历其中每个进程,比较他们的进程的name,最后得到进程的ID。

BOOL WINAPI Process32First( HANDLE hSnapshot, LPPROCESSENTRY32 lppe ); BOOL WINAPI Process32Next( HANDLE hSnapshot, LPPROCESSENTRY32 lppe );

 有了ID那么就可以执行结束进程的操作了。参考函数如下:

DWORD GetProcessIdFromName(LPCTSTR name) { PROCESSENTRY32 pe; DWORD id = 0;

 //请参考msdn,主要是获得windows当前的任务的一个snap(快照)。

HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); pe.dwSize = sizeof(PROCESSENTRY32);

 //检索上一步获得的windows的快照的每个进程。First ,next 函数

if(!Process32First(hSnapshot,&pe))

    return 0;

CString name1,name2;

do {

pe.dwSize = sizeof(PROCESSENTRY32);

 name1=pe.szExeFile;

name2=name;

name1.MakeUpper();

name2.MakeUpper(); //其中参数pe里面有进程信息如name,即在任务管理器里面看到的名字,如qq.exe

if(strcmp(name1.GetBuffer(0),name2.GetBuffer(0)) == 0)

{

//记下这个ID,也及时我们要得到的进程的

ID id = pe.th32ProcessID; break;

 }

if(Process32Next(hSnapshot,&pe)==FALSE)

break;

 } while(1);

 CloseHandle(hSnapshot);

 return id;

 } 由进程的ID,结束进程的函数

BOOL KillProcessById(DWORD pID)

{

 HANDLE Hwnd; bool ret = FALSE;

 Hwnd = OpenProcess(PROCESS_TERMINATE | SYNCHRONIZE,0,pID);

 if (Hwnd)

 {

 if (TerminateProcess(Hwnd, 0))

{

ret = true;

}

}

 return ret;

}

关于结束进程的方法也有其他的一些方法。 1. 上面所说的直接TerminateProcess() 这个方法比较野蛮。但是比较好用。TerminateProcess返回的时候进程已经结束。 2. 发送消息给目标窗口。直接给目标窗口发送WM_CLOSE,有的程序会修改此消息,变成程序最小化(QQ)。不行就发送WM_QUIT,这个一般都管用的。 BOOL PostMessage( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam ); 这里面有个难点就是,怎么知道目标窗口的hwnd,如果有VC的话,可以用自带的工具SPY++来获得窗口的hwnd,注意程序每次启动后的主窗口hwnd是不是一样的。 由于,发消息成功,并不代表程序也已经结束,所以如果想等目标进程(B)结束后,再继续运行源程序的话(A),要利用以下的方式WaitForSingleObject,参数是进程的handle,通过进程的ID得到。

 DWORD WaitForSingleObject( HANDLE hHandle, DWORD dwMilliseconds ); 而通过hwnd可以得到进程ID,方法如下。

DWORD GetWindowThreadProcessId( HWND hWnd, LPDWORD lpdwProcessId ); 参考code如下:

DWORD pID; //根据hwnd得到进程的ID,pid GetWindowThreadProcessId(hwnd, &pID) //得到进程的handle。

 HANDLE hp = OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE,FALSE,pid); //等待直到进程结束。进程结束会发出信号出来。并且 WaitForSingleObject 返回WAIT_OBJECT_0。 WaitForSingleObject(hp, INFINITE); 补充一个由进程Id得到窗口ID的方法,由于从网上找到的,没有实验。进程启动完毕,然后调用函数EnumWindows(EnumWindowsProc,0) //EnumWindowsProc是回调函数回调函数EnumWindowsProc为:

BOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM lparam)

{

CString strPrompt;

DWORD ProcId;

DWORD ThreadId;

ThreadId=GetWindowThreadProcessId(hwnd,&ProcId) if(ProcId==ProcessInfo.dwProcessId)

 {

 HWND targetWin; targetWin=hwnd;

 while(true)

{

HWND hTemp; hTemp=GetParent(targetWin);

if(hTemp==NULL) break; else targetWin=hTemp;

 }

char szTemp[255];

 sprintf(szTemp,"%x",ProcId);

CString strTemp=szTemp;

GetWindowText(targetWin,strTemp.GetBuffer(255),255);

return FALSE;

 }

else

return true;

 }

//MFC基于对话框的应用实例:

//Print.h头文件 #pragma once #include "tlhelp32.h"

 class CPrint : public CDialog

{

 DECLARE_DYNAMIC(CPrint) public: CPrint(CWnd* pParent = NULL);

// 标准构造函数 virtual ~CPrint();

// 对话框数据 enum { IDD = IDD_DIALOG_PRINT };

protected:

 virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP()

public:

 void ClosePrintTestProcess(); DWORD GetProcessIdFromName(LPCTSTR name); BOOL KillProcessById(DWORD pID);

 public:

afx_msg void OnBnClickedButtonPrintTestProcessClose();

}

//Print.c文件 #include "stdafx.h" #include "Print.h"

DWORD CPrint::GetProcessIdFromName(LPCTSTR name)

{

 PROCESSENTRY32 pe; DWORD id = 0; //请参考msdn,主要是获得windows当前的任务的一个snap(快照)。

HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); pe.dwSize = sizeof(PROCESSENTRY32); //检索上一步获得的windows的快照的每个进程。First ,next 函数

if(!Process32First(hSnapshot,&pe))

return 0; CString name1,name2;

do {

             pe.dwSize = sizeof(PROCESSENTRY32);

 name1=pe.szExeFile;

name2=name;

name1.MakeUpper();

name2.MakeUpper();

//其中参数pe里面有进程信息如name,即在任务管理器里面看到的名字,如qq.exe

 if(strcmp(name1.GetBuffer(0),name2.GetBuffer(0)) == 0)

 {

 //记下这个ID,也及时我们要得到的进程的

ID id = pe.th32ProcessID;

break;

 }

 if(Process32Next(hSnapshot,&pe)==FALSE)

 break;

} while(1);

CloseHandle(hSnapshot);

 return id;

 }

BOOL CPrint::KillProcessById(DWORD pID)

 {

HANDLE Hwnd;

 bool ret = FALSE;

 Hwnd = OpenProcess(PROCESS_TERMINATE | SYNCHRONIZE,0,pID);

 if (Hwnd) { if (TerminateProcess(Hwnd, 0))

{

 ret = true;

 }

 } return ret;

 }

 void CPrint::ClosePrintTestProcess()

 {

LPCTSTR ProcessName = "EmperorEpsonPrintTest.exe";

 DWORD pID = GetProcessIdFromName(ProcessName);

 bool ret = KillProcessById(pID); if (true == ret)

 {

 //关闭指定进程成功

 }

else

 {

 //关闭指定进程失败

 }

 }

void CPrint::OnBnClickedButtonPrintTestProcessClose()

 {

// TODO: 在此添加控件通知处理程序代码

ClosePrintTestProcess();

 }

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值