本文要实现的功能就是在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函数用法示例:
long __stdcall callback(EXCEPTION_POINTERS *excp) { return EXCEPTION_EXECUTE_HANDLER; } int main() { SetUnhandledExceptionFilter(callback); //只是为了让程序崩溃 _asm int 3; return 0; }
如何获取进程ID呢?
因为在这里我是用一个程序来监视另一个exe程序的,所以我可以通过exe程序的名字来获取这个进程的进程ID,方法如下,GetProcessIdFromName函数输入的就是exe程序的名字,例如"test.exe"。
DWORD GetProcessIdFromName(const char*processName) { PROCESSENTRY32 pe; DWORD id = 0; HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); pe.dwSize = sizeof(PROCESSENTRY32); if( !Process32First(hSnapshot,&pe) ) return 0; char pname[300]; do { pe.dwSize = sizeof(PROCESSENTRY32); if( Process32Next(hSnapshot,&pe)==FALSE ) break; //把WCHAR*类型转换为const char*类型 sprintf(pname,"%ws",pe.szExeFile); //比较两个字符串,如果找到了要找的进程 if(strcmp(pname,processName) == 0) { id = pe.th32ProcessID; break; } } while(1); CloseHandle(hSnapshot); return id; }
如果这个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>
本文参考:
http://blog.163.com/danshiming@126/blog/static/10941274820154763227578/点击打开链接
https://zhidao.baidu.com/question/570807313.html点击打开链接
