织梦CMS - 轻松建站从此开始!

罗索

当前位置: 主页>杂项技术>VC(MFC)>

如何关闭另一个进程?

jackyhwei 发布于 2011-02-09 14:23 点击:次 
Windows下在一个进程里去关闭另一个进程的几种方法(含源码实现)
TAG:

结束进程的函数为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那么就可以执行结束进程的操作了。参考函数如下:

 

  1. DWORD GetProcessIdFromName(LPCTSTR name) 
  2.        PROCESSENTRY32 pe; 
  3.        DWORD id = 0; 
  4. //请参考msdn,主要是获得windows当前的任务的一个snap(快照)。 
  5.        HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); 
  6.        pe.dwSize = sizeof(PROCESSENTRY32); 
  7.        //检索上一步获得的windows的快照的每个进程。First ,next 函数 
  8.        if(!Process32First(hSnapshot,&pe)) 
  9.               return 0; 
  10.        CString name1,name2; 
  11.  
  12.        do 
  13.        { 
  14.               pe.dwSize = sizeof(PROCESSENTRY32); 
  15.               name1=pe.szExeFile; 
  16.               name2=name; 
  17.               name1.MakeUpper(); 
  18.               name2.MakeUpper(); 
  19. //其中参数pe里面有进程信息如name,即在任务管理器里面看到的名字,如qq.exe 
  20. if(strcmp(name1.GetBuffer(0),name2.GetBuffer(0))   ==   0) 
  21.               { 
  22.                      //记下这个ID,也及时我们要得到的进程的ID 
  23.                      id   =   pe.th32ProcessID; 
  24.                      break
  25.               } 
  26.  
  27.               if(Process32Next(hSnapshot,&pe)==FALSE)  
  28.                      break
  29.        } while(1); 
  30.        CloseHandle(hSnapshot); 
  31.        return id; 

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

 

  1. BOOL KillProcessById(DWORD pID) 
  2.        HANDLE Hwnd; 
  3.        bool ret = FALSE; 
  4.        Hwnd = OpenProcess(PROCESS_TERMINATE | SYNCHRONIZE,0,pID); 
  5.        if (Hwnd) 
  6.        { 
  7.               if (TerminateProcess(Hwnd, 0)) 
  8.               { 
  9.                      ret = true
  10.               } 
  11.        } 
  12.        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为:  

 

  1. BOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM lparam) 
  2. CString strPrompt; 
  3. DWORD ProcId; 
  4. DWORD ThreadId; 
  5. ThreadId=GetWindowThreadProcessId(hwnd,&ProcId) 
  6. if(ProcId==ProcessInfo.dwProcessId) 
  7. HWND targetWin; 
  8. targetWin=hwnd; 
  9. while(true
  10. HWND hTemp; 
  11. hTemp=GetParent(targetWin); 
  12. if(hTemp==NULL) break
  13. else targetWin=hTemp; 
  14.  
  15. char szTemp[255]; 
  16. sprintf(szTemp,"%x",ProcId); 
  17. CString strTemp=szTemp; 
  18. GetWindowText(targetWin,strTemp.GetBuffer(255),255); 
  19. return FALSE; 
  20. else 
  21. return true
(renjwjx)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201102/10845.html]
本文出处:CSDN博客 作者:renjwjx
顶一下
(2)
100%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容