windows C/C++ 在一个程序中打开,关闭和监视其它的exe程序

本文要实现的功能就是在windows下,实现用一个程序来打开,关闭和监视其它的exe程序,我这里的的exe程序是我自己实现的。

1.监视exe是否崩溃

首先如果一个进程不在了,它的进程ID就是0, 那么通过检测进程ID是否为0,就可以知道进程是否还在运行。

假设程序崩溃了,它的进程ID会变成0,那么通过检测进程ID是否为0,就可以知道程序是否崩溃。

但是在windows下,情况并不是假设的那样,程序崩溃了,它就弹出一个错误对话框,如下图所示,并且如果不关掉掉这个框,程序就永远死在这个窗口上,不会退出,进程ID也不会变成0,那么就不能通过检测进程ID来判断程序是否崩溃。所以现在必须让程序崩溃后直接退出而不是死在错误窗口上。
 

 

解决办法就是SetUnhandledExceptionFilter函数,使用这个函数就可以让程序崩溃后直接退出,而不是死在错误窗口上。这个函数的返回值有三种情况:

EXCEPTION_EXECUTE_HANDLER     表示下面执行__except块内及其后面的代码

EXCEPTION_CONTINUE_SEARCH     表示回到抛出异常处继续向下执行

EXCEPTION_CONTINUE_EXECUTION    表示查找下一个异常处理例程入口

 

SetUnhandledExceptionFilter函数用法示例:

 

 
  1. long __stdcall callback(EXCEPTION_POINTERS *excp)

  2. {

  3. return EXCEPTION_EXECUTE_HANDLER;

  4. }

  5.  
  6. int main()

  7. {

  8. SetUnhandledExceptionFilter(callback);

  9. //只是为了让程序崩溃

  10. _asm int 3;

  11. return 0;

  12. }

 

如何获取进程ID呢?

因为在这里我是用一个程序来监视另一个exe程序的,所以我可以通过exe程序的名字来获取这个进程的进程ID,方法如下,GetProcessIdFromName函数输入的就是exe程序的名字,例如"test.exe"。

 

 
  1. DWORD GetProcessIdFromName(const char*processName)

  2. {

  3. PROCESSENTRY32 pe;

  4. DWORD id = 0;

  5.  
  6. HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);

  7. pe.dwSize = sizeof(PROCESSENTRY32);

  8. if( !Process32First(hSnapshot,&pe) )

  9. return 0;

  10. char pname[300];

  11. do

  12. {

  13. pe.dwSize = sizeof(PROCESSENTRY32);

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

  15. break;

  16. //把WCHAR*类型转换为const char*类型

  17. sprintf(pname,"%ws",pe.szExeFile);

  18. //比较两个字符串,如果找到了要找的进程

  19. if(strcmp(pname,processName) == 0)

  20. {

  21. id = pe.th32ProcessID;

  22. break;

  23. }

  24.  
  25. } while(1);

  26.  
  27. CloseHandle(hSnapshot);

  28.  
  29. return id;

  30. }

 

如果这个exe程序崩溃了,如何重新打开exe呢?

这里我采用最简单的WinExec()函数:

WinExec("C:\\exams\\test.exe",SW_SHOW);


如何主动关闭exe程序呢?

//通过进程名获取进程ID
DWORD pid = GetProcessIdFromName("test.exe");
//获取进程的最大权限
HANDLE token = OpenProcess(PROCESS_ALL_ACCESS,FALSE,pid);
//关闭进程
TerminateProcess(token, 0);


注意啦!!!!!!!!!

在上面获取进程ID的时候,一定是"test.exe",只是exe程序的名字,没有路径!没有路径!没有路径!重要的事情说三遍!否则获取不到进程ID。但是WinExec打开的时候就要加上路径了,当然如果控制程序和exe程序在相同目录下,就不必啦。

我写的时候是char filename[] = "C:\\exams\\test.exe",然后后面打开和获取进程ID的时候都用的是filename,导致我在关exe的时候一直关不掉,困扰了我好久。

 我添加的头文件有:

#include<windows.h>

#include<tlhelp32.h>

#include<comdef.h>

 

关于windows关闭窗口的API

刚开始以为是 CLoseWindow(句柄);  然而这个接口只是窗口最小化

百度后以为是 DestroyWindow(句柄) : 然后这接口运行没有任何效果,不知为何

正确的应该是 ::SendMessage(句柄,WM_CLOSE,0,0,)

 
  1. HWND m_handle = 0;

  2. int num = 0;

  3. while(m_handle == 0 && num < 60){

  4. m_handle = ::FindWindowA(NULL, "untitled1");

  5. ++num;

  6. Sleep(100);

  7. }

  8. if(m_handle != 0)

  9. {

  10. ::SendMessageA(m_handle,WM_CLOSE,0,0);

  11. }

 

转载于:https://my.oschina.net/u/4000302/blog/3062356

  • 0
    点赞
  • 3
    收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值