写一个C++程序,监控另一个进程,发现该进程关掉了就自动把它重启。
#include <iostream>
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
using namespace std;
int _tmain(int argc, TCHAR *argv[])
{
STARTUPINFO si;
PROCESS_INFORMATION pi; //进程信息:
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
do{
// 创建子进程,判断是否执行成功
if(!CreateProcess( NULL,"cmd /c d://1.jpg",NULL,NULL,FALSE,0,NULL,NULL,&si,&pi))
{
cout << "创建进程失败.." << GetLastError() << endl;
system("pause"); //用于测试
return 0;
}
//进程执行成功,打印进程信息
cout << "以下是子进程的信息:" << endl;
cout << "进程ID pi.dwProcessID: " << pi.dwProcessId << endl;
cout << "线程ID pi.dwThreadID : " << pi.dwThreadId << endl;
// 等待知道子进程退出...
WaitForSingleObject( pi.hProcess, INFINITE);//检测进程是否停止
// while (WAIT_TIMEOUT == WaitForSingleObject( pi.hProcess, 50)) //检测进程是否停止 (INFINITE)
// {
// //检查进程当前状态,返回0表示正在运行,返回非0,表示暂停
// if (0 != ResumeThread(pi.hProcess))
// {
// break;
// }
// }
//WaitForSingleObject()函数检查对象的状态,如果是未确定的则等待至超时
//子进程退出
cout << "子进程已经退出..." << endl;
//关闭进程和句柄
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
//system("pause");//执行完毕后等待
}while(true);//如果进程推出就再次执行方法
exit(0);
return 0;
}
//GetThreadPriority(); //获得进程状态
//ResumeThread()
在程序中启动另外一个进程
#include "stdafx.h"
#include <iostream>
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <ShellAPI.h>
using namespace std;
int _tmain(int argc, TCHAR *argv[])
{
//#include <ShellAPI.h>
//wchar_t lpFile[] = L"E://Test//Test.exe";
SHELLEXECUTEINFO ExeInfo;
ZeroMemory ( &ExeInfo, sizeof( SHELLEXECUTEINFO) );
ExeInfo.cbSize = sizeof( SHELLEXECUTEINFO );
ExeInfo.lpFile = L"E://Test//Test.exe";
ExeInfo.lpDirectory = NULL;
ExeInfo.lpParameters = NULL;
ExeInfo.fMask = SEE_MASK_NOCLOSEPROCESS ;
ExeInfo.nShow = SW_MAXIMIZE;//SW_HIDE;
//try
//{
ShellExecuteEx ( &ExeInfo );
//this->Enabled = false;
//}
//catch (Exception &exception)
//{
// //this->Enabled = true;
// Application->ShowException(&exception);
//}
//this->Hide();
for ( ; ; )
{
//Application->ProcessMessages();
if ( WAIT_TIMEOUT != WaitForSingleObject ( ExeInfo.hProcess, INFINITE ) ) break;
//if ( g_blExit ) break; // Exit the Application
}
//this->Show();
//this->Enabled = true;
//this->SetFocus();
//this->BringToFront();
}
windows下监控进程的脚本
相信大家都有这样的需求,某程序(进程)在运行的时候可能挂掉,需要去监控该程序,并在它挂掉的时候重启之,确保该程序能一直运行。比如土net就经常挂,需要监控程序去监控。Linux下面似乎有守护进程的概念,Windows下面其实也很简单,dos批处理就可以搞定 :-)
需要了解如下几个命令,tasklist + find,ping。tasklist是列出所有进程,可以指定只列出某用户的进程,用/FI参数过滤。find /C可以去tasklist的结果中查找指定进程名,并输出个数。
还有个问题是如何设置每隔一段时间去检测进程是否在运行,我用的是ping命令自带的延迟参数-w,将IP地址设置成一个空地址,比如0.0.0.1,这样该命令会一直ping,直到一定n*w 毫秒后才返回(n和w分别是参数-n和-w指定的值)。
示例程序如下,红色部分需要根据需求进行替换,enjoy it!
:RESTART
tasklist /FI "username eq bigtree" | find /C "java" > temp.txt
set /p num= < temp.txt
del /F temp.txt
echo %num%
if "%num%" == "0" start /D "E:/User/bigtree/program/comparison/" pos
ping -n 10 -w 2000 0.0.0.1 > temp.txt
del /F temp.txt
goto RESTART
注意1:goto语句是将监控程序设置成死循环,哇咔咔。
注意2:可以用start /D path program去异步调用program程序,也就是不等program指定完毕就执行下面的语句,因此可以设置固定间隔(n*w毫秒)去监测。
如果用call program则是同步调用,会等待program执行完毕,这样延迟就用不着了。
最近几天加班加疯掉了,天天晚上没法睡。开发部的一个核心程序总是会自己宕机,然后需要手工去起,而这个服务的安全级别又很高,只有我可以操作,搞得我晚上老没法睡,昨晚实在受不了了,想起以前在hp-ux下写的shell守护进程,这回搞个windows下的bat版守护程序吧,当时晚上思路已经很迟钝了,就叫了个兄弟让他写了,上去后运行效果不错,至少昨晚我安心睡了7小时。
早上来把程序改完善一些,增加了记录等功能。
实现:
检查是否有notepad,要用的话就算成自己的进程名,如果进程宕了就过会自动重启(会在当前目录下生成一个start.bat)
@echo off
set _task=notepad.exe
set _svr=c:/windows/notepad.exe
set _des=start.bat
:checkstart
for /f "tokens=5" %%n in ('qprocess.exe ^| find "%_task%" ') do (
if %%n==%_task% (goto checkag) else goto startsvr
)
:startsvr
echo %time%
echo ********程序开始启动********
echo 程序重新启动于 %time% ,请检查系统日志 >> restart_service.txt
echo start %_svr% > %_des%
echo exit >> %_des%
start %_des%
set/p=.<nul
for /L %%i in (1 1 10) do set /p a=.<nul&ping.exe /n 2 127.0.0.1>nul
echo .
echo Wscript.Sleep WScript.Arguments(0) >%tmp%/delay.vbs
cscript //b //nologo %tmp%/delay.vbs 10000
del %_des% /Q
echo ********程序启动完成********
goto checkstart
:checkag
echo %time% 程序运行正常,10秒后继续检查..
echo Wscript.Sleep WScript.Arguments(0) >%tmp%/delay.vbs
cscript //b //nologo %tmp%/delay.vbs 10000
goto checkstart
怎么实现一个:判断指定进程有无响应的功能函数.
已知条件为:一个进程ID,求这个进程有无响应;用VC平台实现.
我在网络查找一些资料,copy后得出以下一个程序,但不能检测出结果,运行时会出错.
接触C++不是很长时间,希望大家能帮帮我,解决这个问题,谢谢.
如果还有其它方法,请给予提示.谢谢.
///////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <stdio.h>
typedef struct tagWNDINFO
{
DWORD dwProcessId;
HWND hWnd;
} WNDINFO, *LPWNDINFO;
BOOL CALLBACK YourEnumProc(HWND hWnd,LPARAM lParam)
{
DWORD dwProcessId;
GetWindowThreadProcessId(hWnd, &dwProcessId);
LPWNDINFO pInfo = (LPWNDINFO)lParam;
if(dwProcessId == pInfo->dwProcessId)
{
pInfo->hWnd = hWnd;
return FALSE;
}
return TRUE;
}
HWND GetProcessMainWnd(DWORD dwProcessId)
{
WNDINFO wi;
wi.dwProcessId = dwProcessId;
wi.hWnd = NULL;
EnumWindows(YourEnumProc,(LPARAM)&wi);
return wi.hWnd;
}
//如果这个进程没有窗口,函数返回NULL
/** /*/
//////////////////////////////////////////////////////////////////////////
int GetProcessAnswer(DWORD iProcessid)
{
HWND hwnd = GetProcessMainWnd(iProcessid);
//不存在/
if(NULL == hwnd)return(-1);
typedef BOOL (WINAPI *PROCISHUNGAPPWINDOW)(HWND);
typedef BOOL (WINAPI *PROCISHUNGTHREAD)(DWORD);
//然后定义
PROCISHUNGAPPWINDOW m_pIsHungAppWindow;
PROCISHUNGTHREAD m_pIsHungThread;
//定义一个bool型,来判断当前操作系统是否是Windows NT/2000以上
// 因为不同的操作系统,判断程序是否运行正常的方式是不一样的
BOOL m_bIsNT;
BOOL bRetVal;
//获取版本信息
OSVERSIONINFO osver = {0};
osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (!GetVersionEx(&osver))
{
bRetVal = FALSE;
}
if(bRetVal == TRUE)
{
if (osver.dwPlatformId&VER_PLATFORM_WIN32_NT)
{
m_bIsNT = TRUE;
}
else
{
m_bIsNT = FALSE;
}
}
//获取那两个函数指针
HMODULE hUser32 = ::GetModuleHandle("user32");
if (!hUser32)
{
bRetVal = FALSE;
}
if(bRetVal == TRUE)
{
m_pIsHungAppWindow = (PROCISHUNGAPPWINDOW)
GetProcAddress( hUser32,
"IsHungAppWindow" );
m_pIsHungThread = (PROCISHUNGTHREAD) GetProcAddress( hUser32,
"IsHungThread" );
if (!m_pIsHungAppWindow && !m_pIsHungThread)
{
bRetVal = FALSE;
}
}
//于是判断,窗口是否是正常运行,还是未响应
// 代码如下
if(m_bIsNT == TRUE)
{
BOOL bIsHung = m_pIsHungAppWindow(hwnd);
if(bIsHung)
{
return(-2);//没有响应
}
else
{
return(0);//正在运行
}
}
else
{
BOOL bIsHung =m_pIsHungThread(GetWindowThreadProcessId(hwnd,NULL));
if(bIsHung)
{
return(-2);//没有响应
}
else
{
return(0);//正在运行
}
}
}
//////////////////////////////////////////////////////////////////////////
int main()
{
// int iSum = int(GetProcessMainWnd(3616));//3616是进程ID
// printf("%d",isum);
int isum = GetProcessAnswer(3616/*这里输入进程ID*/);
printf("%d",isum);
return(0);
}
请问怎么判断一个进程是否停止响应?
DWORD dwResult;
BOOL fResponding = SendMessageTimeout(hwndInQuestion,
WM_NULL, 0, 0, SMTO_ABORTIFHUNG, 5000, &dwResult);
// fResponding is TRUE if the thread is responding and
// FALSE if not.
整个过程是这样:
有一个Server,Server一直运行,理想状态不会失去响应,同时有一个应用程序也在运行,当Server接到指令要检测那个应用程序是否还有响应,如果没有响应就Kill这个应用程序的进程,并重启这个应用程序。
现在关键是如何检测应用程序是否还有响应,怎么样Kill掉它,怎么样重启它这三个问题。
大家帮帮忙,这样的问题帖子很多,但都没有提供完整的例子代码,我是菜鸟,告诉我方法自己写还不太可能,需要看代码学习! 谢谢了! 问题点数:100、回复次数:30Top
1 楼vcleaner(我没当大哥很久了.......)回复于 2004-11-10 09:47:11 得分 0
应该是如何判断进程的活动状态,呵呵,写注册表,查询注册表,然后判断其值,如果和上次比较没有改变,那么就重启。这样做有滞后,但是既然能重启系统,滞后也应该能接受吧。呵呵,如果楼主能有相关的函数或者办法实时判断状态,请告诉我!
Top
2 楼laiyiling(陌生人[MVP])回复于 2004-11-10 09:51:16 得分 25
ZT:
用SendMessageTimeout函数向目的窗口发一个消息,如果返回0,而且GetLastError得到0,就表示该窗口线程无响应.Top
3 楼vcleaner(我没当大哥很久了.......)回复于 2004-11-10 09:52:15 得分 0
你可以让程序运行起来的时候写一个字符串(GetModuleFileName得到的是现在的名字和一个数字值)到注册表中的固定位置,每隔一段时间更新一下数据值,不管别人将Exe改名为什么,只要你想知道是不是你写的程序在运行,只要查询注册表就行了,如果查询的数据值多次没有改变,即说明那个程序已经当掉了,你可以重启之,呵呵,记得程序退出的时候删除注册表项。这样就可以判断是否在运行了!可以将两个程序都这么做,那么他们就能相互监控了!Top
4 楼DentistryDoctor(不在无聊中无奈,就在沉默中变态)回复于 2004-11-10 09:52:38 得分 0
最简单的方法是函数
IsHungAppWindowTop
5 楼DentistryDoctor(不在无聊中无奈,就在沉默中变态)回复于 2004-11-10 09:53:28 得分 5
IsHungAppWindow Function
--------------------------------------------------------------------------------
You call the IsHungAppWindow function to determine if Microsoft Windows considers that a specified application is not responding, or "hung". An application is considered to be not responding if it is not waiting for input, is not in startup processing, and has not called PeekMessage within the internal timeout period of 5 seconds.
Syntax
BOOL IsHungAppWindow( HWND hWnd
);
Parameters
hWnd
[in] Handle to the window.
Return Value
Returns TRUE if the window stops responding, otherwise returns FALSE. Ghost windows always return TRUE.
Remarks
The Windows timeout criteria of 5 seconds is subject to change.
Although you can access this function by using LoadLibrary and GetProcAddress combined in Windows versions prior to Windows XP, the function is not accessible using the standard Include file and library linkage. The header files included in Windows XP Service Pack 1 (SP1) and Windows Server 2003 document this function and make it accessible using the appropriate Include file and library linkage. However, this function is not intended for general use. It is recommended that you do not use it in new programs because it might be altered or unavailable in subsequent versions of Windows.
Function Information
Minimum DLL Version user32.dll
Header Declared in Winuser.h, include Windows.h
Import library User32.lib
Minimum operating systems Windows 2000
Top
6 楼oyljerry(【勇敢的心】→ ㊣提拉米苏√㊣)回复于 2004-11-10 10:04:31 得分 10
WaitForSingleObject等待句柄返回
Terminate终止进程
CreateProcess启动进程Top
7 楼mixtrue(忽报人间曾伏虎,泪飞顿作倾盆雨。)回复于 2004-11-10 10:09:36 得分 0
To DentistryDoctor :
The function of IsHungAppWindow is testing the application (specified application ), not The process. I think that the IsHungAppWindow will not works to PROCESS.Top
8 楼ppssdd()回复于 2004-11-10 10:18:04 得分 0
DentistryDoctor(雅克医生<改行做程序员了>) :
BOOL IsHungAppWindow(HWND hWnd);参数hWnd怎么取呢?你发个例子可以吗?Top
9 楼ppssdd()回复于 2004-11-10 10:19:36 得分 0
大家的意见都很好,就是没有例子啊! 俺是菜鸟!Top
10 楼ppssdd()回复于 2004-11-10 10:23:21 得分 0
mixtrue:
一个正在执行的exe文件可以叫一个应用吧, 也是一个进程啊,这两个有什么区别吗?Top
11 楼DentistryDoctor(不在无聊中无奈,就在沉默中变态)回复于 2004-11-10 13:21:38 得分 0
FindWindow or EnumWindows to get the process's main window.Top
12 楼kingzai(stevenzhu)回复于 2004-11-10 13:35:53 得分 0
http://www.vckbase.com/bbs/prime/viewprime.asp?id=334
Windows 任务管理器如何确定应用程序"没有响应"
(hangwire发表于2001-12-26 15:46:46)
最近参加的一个项目要求实现远程任务管理功能,也就是"Remote Task Manager"(RTM)。我把它与Windows NT的任务管理器进行了比较,发现标准的任务管理器显示应用程序的状态(正在运行或者没有响应)。标准的任务管理器发送(通过SendMessageTimeout函数)一个消息到主应用窗口,如果函数调用失败或者超时--则应用程序的状态就是"没有响应",否则状态为"正在运行"。
但我发现还有一个更好的解决方法。本文将通过实例程序进行示范。这个方法的思路是通过调用User32.dll中一个未公开的函数来实现的。这个函数存在于Windows 9x和Windows NT/2000系统中,但在两个系统中的名字是不同的。Windows 9x系统中的名字为:IsHungThread,在Windows NT/2000系统中的名字为IsHungAppWindow。下面是它们的原型:
BOOL IsHungAppWindow (
HWND hWnd, // 主应用窗口句柄
);
和
BOOL IsHungThread (
DWORD dwThreadId, // 主应用窗口的线程ID
);
不幸的是,微软在User32.lib中没有提供这两个函数的输出。也就是说,这两个函数是未公开函数,如果要在程序中使用它们,则必须通过GetProcAddress和GetModuleHandle函数动态加载:
typedef BOOL (WINAPI *PROCISHUNGAPPWINDOW) (HWND);
typedef BOOL (WINAPI *PROCISHUNGTHREAD) (DWORD);
PROCISHUNGAPPWINDOW IsHungAppWindow;
PROCISHUNGTHREAD IsHungThread;
HMODULE hUser32 = GetModuleHandle("user32");
IsHungAppWindow = (PROCISHUNGAPPWINDOW)
GetProcAddress(hUser32,"IsHungAppWindow");
IsHungThread = (PROCISHUNGTHREAD)
GetProcAddress(hUser32,"IsHungThread");Top
13 楼kingzai(stevenzhu)回复于 2004-11-10 13:37:18 得分 10
1。hwo to kill process?
GetWindowThreadProcessId得到进程id,再OpenProcess得到进程句柄,调用TerminateProcess
2.hwo to create process?
CreateProcess
Top
14 楼DentistryDoctor(不在无聊中无奈,就在沉默中变态)回复于 2004-11-10 13:37:43 得分 20
HWND g_hWndToProcess=NULL;
BOOL CALLBACK EnumWindowsProc(HWND hwnd,
LPARAM nProcessID
)
{
DWORD dwProcessID=0;
GetWindowThreadProcessId(hwnd,&dwProcessID);
if(dwProcessID==nProcessID)
{
char szTitle[256];
TCHAR szBuf[256];
ZeroMemory(szTitle,256);
GetClassName(hwnd, szBuf, 256 );
GetWindowText(hwnd,szTitle,256);
if(lstrlen(szTitle) && IsWindowVisible(hwnd) && lstrcmp("Program",szBuf))
{
OutputDebugString(szTitle);
g_hWndToProcess=hwnd;
return FALSE;
}
}
return TRUE;
}
...
g_hWndToProcess=NULL;
EnumWindows(EnumWindowsProc,nID);//nID:目的进程的ID,必须有主窗口
if(NULL!=g_hWndProcess && IsHungAppWindow(g_hWndToProcess))
{
...
}Top
15 楼gooyan(超级替补)回复于 2004-11-10 19:30:55 得分 0
createmutex
Top
16 楼mixtrue(忽报人间曾伏虎,泪飞顿作倾盆雨。)回复于 2004-11-11 10:36:00 得分 0
To : ppssdd()
应用程序和进程当然有差别了,详情参见os 书籍 。
Top
17 楼Magnus(小楼一夜听春雨)回复于 2004-11-11 10:38:45 得分 0
典型的WatchDog,
讓被監視的進程定時發消息給WatchDog,
超時就認定為失去響應,
就resetTop
18 楼linxy2002(BugSlayer)回复于 2004-11-11 15:39:55 得分 30
呵呵,是啊,对于菜鸟来说,例子才是正道!
你把要求说清楚写,我帮你写一个,我的: [email protected]Top
19 楼blastzgd(悟道)回复于 2004-11-11 17:21:04 得分 0
楼主这个不知算不算无理要求。
你的没响应是什么意思?阻塞了?还是死循环了?
Top
20 楼linxy2002(BugSlayer)回复于 2004-11-11 20:19:56 得分 0
我写了个小例子不知道符不符合你的需要,你来向我要吧Top
21 楼NNBWOLF(叫花子)回复于 2004-11-11 22:00:07 得分 0
阿狼也贴点代码看看...Top
22 楼ppssdd()回复于 2004-11-12 14:23:32 得分 0
TO:
blastzgd(边城浪子) :
当window任务管理器中应用程序的状态被判为无响应时,你知道是阻塞了?还是死循环了?也是无理要求?
Top
23 楼ppssdd()回复于 2004-11-12 14:29:35 得分 0
TO:
linxy2002(阿郎) :
还是你理解我啊!
我给你发了消息了,多谢,你可以发给我了!~ :)Top
24 楼linxy2002(BugSlayer)回复于 2004-11-13 13:15:31 得分 0
已经发给你了,不知道是否满足你的要求Top
25 楼hjunxu(hjun)回复于 2004-11-13 14:39:05 得分 0
楼主你的应用好奇怪啊。
如果程序在很忙的干活,比如处理一个消息响应很久,messagepump没有动静系统就会认为你的程序没有响应的,所以可能杀错。Top
26 楼hjunxu(hjun)回复于 2004-11-13 14:41:29 得分 0
你可以说说你这样应用理由吗?Top
27 楼zhouhuaikun(怀空)回复于 2004-11-13 14:48:06 得分 0
学习!Top
28 楼ppssdd()回复于 2004-11-15 13:53:39 得分 0
To: hjunxu(hjun):
“如果程序在很忙的干活,比如处理一个消息响应很久,messagepump没有动静系统就会认为你的程序没有响应的,所以可能杀错。”
你说得很有道理,但我要实现的目的与这个没什么大的关系,因为有个重要应用是不能长时间失去响应,也就是说宁可错杀,不可漏杀,反正要重启的!
Top
29 楼ppssdd()回复于 2004-11-15 13:55:17 得分 0
TO:
linxy2002(阿郎) :
已经收到,谢谢! 我已经看了,帮助很大!
Top
30 楼lnp()回复于 2004-12-21 18:36:44 得分 0
mark
软件名称:AlwaysUp
软件版本:v6.5.9.28
软件大小:3.77 MB
适用平台:Windows ALL
软件主页:http://www.coretechnologies.com/products/AlwaysUp/
软件简介:
能将可执行文件、批处理文件及快捷方式作为windows系统服务,并且进行管理和监视确保100%运行。当程序崩溃、挂起、弹出错误对话框时,AlwaysUp 能自动重启程序,并运行自定义的检查功能确保程序一直可用。AlwaysUp 能发送详细的email使你清楚地了解崩溃、重启等事件。
下载地址:http://www.coretechnologies.com/products/alwaysup/AlwaysUp_Installer.exe