MFC关闭另一个程序(杀死另一个进程)

#一、关闭一个进程比较麻烦,方法有好几种
对网上的进行了整理和代码注释
##1.获得窗口的句柄之后,那么可以使用向该窗体发送消息的进行进程的关闭。
###1.1直接给目标窗口发送WM_CLOSE

/*
向该窗体发送WM_CLOSE消息的进行进程的关闭。 关闭这个程序

*/
 HWND h =::FindWindow(NULL,"C://Temp//ABC.exe");//找到应用程序,利用路径和程序名
::SendMessage(h,WM_CLOSE,0,0);//发送关闭信号

原文链接:https://blog.csdn.net/zouzhberk/article/details/5217853

###1.2有的程序会修改此消息,变成程序最小化。不行就发送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; 
}
原文链接:https://blog.csdn.net/skdkjzz/article/details/17072439

#2.下面是一个关闭进程的函数
(要添加头文件#include “tlhelp32.h”(一开始没有添加头文件,报错了,各种懵逼))

##2.1前言

结束进程的函数为BOOL TerminateProcess(
  HANDLE hProcess,
  UINT uExitCode
);
TerminateProcess函数要求一个进程的handle。
而进程的handle可以用进程的ID通过OpenProcess函数来得到。

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

而OpenProcess函数又需要进程的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
);
原文链接:https://blog.csdn.net/skdkjzz/article/details/17072439

###2.1.1编程实例如下
####2.1.1.1示例1
在.H文件中声明函数

#include "tlhelp32.h"

void KillProcess(CString sExeName);

在.CPP中定义函数

/*
可进行调试,查看进程的名字
在需要关闭进程的地方调用KillProcess(_T("要关闭的进程的名字"));即可。
*/

void KillProcess(CString sExeName)
{

//CreateToolhelp32Snapshot()得到系统进程的一个快照
HANDLE hSnapShot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); 


if(hSnapShot == 0) 
    return; 
PROCESSENTRY32 thePE; 
thePE.dwSize = sizeof(PROCESSENTRY32); 


//遍历正在运行的第一个系统进程
bool Status = Process32First(hSnapShot,&thePE); 

bool bHaveFlag = false; //找到进程名状态
DWORD ProcessID = 0;

while(Status) 
{
//遍历正在运行的下一个系统进程  
Status = Process32Next(hSnapShot,&thePE);  

//找到相应的进程 **.exe
    // if(0 == wcscmp(thePE.szExeFile,L""))
CString sFindName = thePE.szExeFile;//进程中的进程名
CString sTemp = sExeName.Mid(0,sFindName.GetLength());//要关闭的进程名


if(sFindName == sTemp)
{ 
    bHaveFlag = true; 
    ProcessID = thePE.th32ProcessID; 
    
    //结束指定的进程 ProcessID
    if(!TerminateProcess(OpenProcess 
    (PROCESS_TERMINATE||PROCESS_QUERY_INFORMATION,false,ProcessID),0)) 
    
    {
        AfxMessageBox(L"无法终止指定的进程!",MB_ICONWARNING||MB_OK);
    }
    else
    {
        AfxMessageBox(L"进程结束!",MB_ICONWARNING||MB_OK);
        break; 
    }
} 
} 
CloseHandle(hSnapShot);
}

原文链接:https://blog.csdn.net/laiyinping/article/details/39493457

#####2.1.1.2示例2(我采用的这种方法,成功了)
在.H文件中声明函数

#include "tlhelp32.h"//加上头文件

DWORD GetProcessIdFromName(LPCTSTR name);//根据进程名字获得进程ID
BOOL KillProcessById(DWORD pID); //根据进程的ID,结束进程的函数

在.CPP中定义函数

DWORD CSpeedstartDlg::GetProcessIdFromName(LPCTSTR name)
{//根据进程名字获得进程ID
	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;
			}	
           检索下一个获得的windows的快照的进程		
		if(Process32Next(hSnapshot,&pe)==FALSE)
			break;
	} while(1);

	CloseHandle(hSnapshot);
	return id;

}

BOOL CSpeedstartDlg::KillProcessById(DWORD pID)
{//由进程的ID,结束进程的函数
	HANDLE Hwnd;
	bool ret=FALSE;
	Hwnd=OpenProcess(PROCESS_TERMINATE|SYNCHRONIZE,0,pID);//得到句柄
	if(Hwnd)
	{
		if(TerminateProcess(Hwnd,0))
		{
			ret=true;
		}
	}
	else
	{
		CString str = "没有发现**程序,请确认**是否启动";
		AfxMessageBox(str);
		ret=FALSE;
	}
	return ret;
}

原文链接:https://blog.csdn.net/skdkjzz/article/details/17072439

参考:
[1]MFC开启与关闭外部进程
https://blog.csdn.net/laiyinping/article/details/39493457
[2]MFC 关闭另一个指定的进程问题
https://blog.csdn.net/skdkjzz/article/details/17072439

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值