Delphi监控指定进程自动守护错误中间件
2013-04-16 00:31
295 查看
对于守护中间件是非常有用的。中间件不可能绝对的稳定而不出问题,中间件有可能因比较严重的错误导致当机或者进程被人为地错误地关闭了中间件。
有了这个自动守护进程的存在,这一切的问题都可以迎刃而解。
program Monitor;
// {$APPTYPE CONSOLE}
uses
Winapi.Windows,
System.SysUtils,
ProcLib in 'ProcLib.pas';
var
Mutex, h: HWND;
const
c_AppName = 'server.exe';
c_ClassName = 'Tf_MainForm';
begin
Mutex := Winapi.Windows.CreateMutex(nil, False, 'Monitor');
if (GetLastError = ERROR_ALREADY_EXISTS) or (Mutex = 0) then
Exit;
G_ExeFile := ExtractFilePath(ParamStr(0)) + c_AppName;
while True do
begin
Sleep(2000);
if ProcessRunning(c_AppName) then
begin
h := FindWindow(PChar(c_ClassName), nil);
if (not IsAppRespondig(h)) and (h <> 0) then
begin
KillTask(c_AppName);
Continue;
end
else
Continue;
end;
if G_ExeFile = '' then
Continue;
Exec(G_ExeFile);
end;
end.
unit ProcLib;
interface
uses
Winapi.Windows, System.SysUtils, Winapi.PsAPI,
Winapi.TlHelp32, Winapi.ShellAPI, Winapi.Messages, Vcl.Dialogs;
function ProcessRunning(ExeName: string): Boolean; // 指定进程是否正在运行
procedure Exec(FileName: string); // 开启指定进程
function KillTask(ExeFileName: String): Integer; // 关闭进程
function IsAppRespondig(wnd: HWND): Boolean; // 进程是否有反应
var
G_ExeFile: string = '';
implementation
function IsAppRespondig9X(dwThreadId: DWORD): Boolean;
type
TIsHungThread = function(dwThreadId: DWORD): BOOL; stdcall;
var
hUser32: THandle;
IsHungThread: TIsHungThread;
begin
Result := True;
hUser32 := GetModuleHandle('user32.dll');
if (hUser32 > 0) then
begin
@IsHungThread := GetProcAddress(hUser32, 'IsHungThread');
if Assigned(IsHungThread) then
begin
Result := not IsHungThread(dwThreadId);
end;
end;
end;
function IsAppRespondigNT(wnd: HWND): Boolean;
type
TIsHungAppWindow = function(wnd: HWND): BOOL; stdcall;
var
hUser32: THandle;
IsHungAppWindow: TIsHungAppWindow;
begin
Result := True;
hUser32 := GetModuleHandle('user32.dll');
if (hUser32 > 0) then
begin
@IsHungAppWindow := GetProcAddress(hUser32, 'IsHungAppWindow');
if Assigned(IsHungAppWindow) then
begin
Result := not IsHungAppWindow(wnd);
end;
end;
end;
function IsAppRespondig(wnd: HWND): Boolean;
begin
Result := False;
if not IsWindow(wnd) then
begin
ShowMessage('Incorrect window handle!');
Exit;
end;
if Win32Platform = VER_PLATFORM_WIN32_NT then
Result := IsAppRespondigNT(wnd)
else
Result := IsAppRespondig9X(GetWindowThreadProcessId(wnd, nil));
end;
function KillTask(ExeFileName: String): Integer;
const
PROCESS_TERMINATE = $0001;
var
ContinueLoop: Boolean;
FSnapshotHandle: THandle;
FProcessEntry32: TProcessEntry32;
begin
Result := 0;
FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
FProcessEntry32.dwSize := SizeOf(FProcessEntry32);
ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
while Integer(ContinueLoop) <> 0 do
begin
If ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile))
= UpperCase(ExeFileName)) Or (UpperCase(FProcessEntry32.szExeFile)
= UpperCase(ExeFileName))) then
Result := Integer(TerminateProcess(OpenProcess(PROCESS_TERMINATE, BOOL(0),
FProcessEntry32.th32ProcessID), 0));
ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
end;
CloseHandle(FSnapshotHandle);
end;
function ProcessFileName(PID: DWORD): string;
var
Handle: THandle;
begin
Result := '';
Handle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,
False, PID);
if Handle <> 0 then
try
SetLength(Result, MAX_PATH);
if GetModuleFileNameEx(Handle, 0, PChar(Result), MAX_PATH) > 0 then
SetLength(Result, StrLen(PChar(Result)))
else
Result := '';
finally
CloseHandle(Handle);
end;
end;
function ProcessRunning(ExeName: string): Boolean;
var
SnapProcHandle: THandle;
NextProc: Boolean;
ProcEntry: TProcessEntry32;
ProcFileName: string;
begin
Result := False;
SnapProcHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if SnapProcHandle = INVALID_HANDLE_VALUE then
Exit;
try
ProcEntry.dwSize := SizeOf(ProcEntry);
NextProc := Process32First(SnapProcHandle, ProcEntry);
while NextProc do
begin
if ProcEntry.th32ProcessID <> 0 then
begin
ProcFileName := ProcessFileName(ProcEntry.th32ProcessID);
if ProcFileName = '' then
ProcFileName := ProcEntry.szExeFile;
if SameText(ExtractFileName(ProcFileName), ExeName) then
begin
Result := True;
Break;
end;
end;
NextProc := Process32Next(SnapProcHandle, ProcEntry);
end;
finally
CloseHandle(SnapProcHandle);
end;
end;
procedure Exec(FileName: string);
var
StartupInfo: TStartupInfo;
ProcessInfo: TProcessInformation;
begin
FillChar(StartupInfo, SizeOf(StartupInfo), #0);
StartupInfo.cb := SizeOf(StartupInfo);
StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
StartupInfo.wShowWindow := SW_SHOWDEFAULT;
if not CreateProcess(PChar(FileName), nil, nil, nil, False,
CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil,
PChar(ExtractFilePath(FileName)), StartupInfo, ProcessInfo) then
Exit;
WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
end;
end.
有了这个自动守护进程的存在,这一切的问题都可以迎刃而解。
program Monitor;
// {$APPTYPE CONSOLE}
uses
Winapi.Windows,
System.SysUtils,
ProcLib in 'ProcLib.pas';
var
Mutex, h: HWND;
const
c_AppName = 'server.exe';
c_ClassName = 'Tf_MainForm';
begin
Mutex := Winapi.Windows.CreateMutex(nil, False, 'Monitor');
if (GetLastError = ERROR_ALREADY_EXISTS) or (Mutex = 0) then
Exit;
G_ExeFile := ExtractFilePath(ParamStr(0)) + c_AppName;
while True do
begin
Sleep(2000);
if ProcessRunning(c_AppName) then
begin
h := FindWindow(PChar(c_ClassName), nil);
if (not IsAppRespondig(h)) and (h <> 0) then
begin
KillTask(c_AppName);
Continue;
end
else
Continue;
end;
if G_ExeFile = '' then
Continue;
Exec(G_ExeFile);
end;
end.
unit ProcLib;
interface
uses
Winapi.Windows, System.SysUtils, Winapi.PsAPI,
Winapi.TlHelp32, Winapi.ShellAPI, Winapi.Messages, Vcl.Dialogs;
function ProcessRunning(ExeName: string): Boolean; // 指定进程是否正在运行
procedure Exec(FileName: string); // 开启指定进程
function KillTask(ExeFileName: String): Integer; // 关闭进程
function IsAppRespondig(wnd: HWND): Boolean; // 进程是否有反应
var
G_ExeFile: string = '';
implementation
function IsAppRespondig9X(dwThreadId: DWORD): Boolean;
type
TIsHungThread = function(dwThreadId: DWORD): BOOL; stdcall;
var
hUser32: THandle;
IsHungThread: TIsHungThread;
begin
Result := True;
hUser32 := GetModuleHandle('user32.dll');
if (hUser32 > 0) then
begin
@IsHungThread := GetProcAddress(hUser32, 'IsHungThread');
if Assigned(IsHungThread) then
begin
Result := not IsHungThread(dwThreadId);
end;
end;
end;
function IsAppRespondigNT(wnd: HWND): Boolean;
type
TIsHungAppWindow = function(wnd: HWND): BOOL; stdcall;
var
hUser32: THandle;
IsHungAppWindow: TIsHungAppWindow;
begin
Result := True;
hUser32 := GetModuleHandle('user32.dll');
if (hUser32 > 0) then
begin
@IsHungAppWindow := GetProcAddress(hUser32, 'IsHungAppWindow');
if Assigned(IsHungAppWindow) then
begin
Result := not IsHungAppWindow(wnd);
end;
end;
end;
function IsAppRespondig(wnd: HWND): Boolean;
begin
Result := False;
if not IsWindow(wnd) then
begin
ShowMessage('Incorrect window handle!');
Exit;
end;
if Win32Platform = VER_PLATFORM_WIN32_NT then
Result := IsAppRespondigNT(wnd)
else
Result := IsAppRespondig9X(GetWindowThreadProcessId(wnd, nil));
end;
function KillTask(ExeFileName: String): Integer;
const
PROCESS_TERMINATE = $0001;
var
ContinueLoop: Boolean;
FSnapshotHandle: THandle;
FProcessEntry32: TProcessEntry32;
begin
Result := 0;
FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
FProcessEntry32.dwSize := SizeOf(FProcessEntry32);
ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
while Integer(ContinueLoop) <> 0 do
begin
If ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile))
= UpperCase(ExeFileName)) Or (UpperCase(FProcessEntry32.szExeFile)
= UpperCase(ExeFileName))) then
Result := Integer(TerminateProcess(OpenProcess(PROCESS_TERMINATE, BOOL(0),
FProcessEntry32.th32ProcessID), 0));
ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
end;
CloseHandle(FSnapshotHandle);
end;
function ProcessFileName(PID: DWORD): string;
var
Handle: THandle;
begin
Result := '';
Handle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,
False, PID);
if Handle <> 0 then
try
SetLength(Result, MAX_PATH);
if GetModuleFileNameEx(Handle, 0, PChar(Result), MAX_PATH) > 0 then
SetLength(Result, StrLen(PChar(Result)))
else
Result := '';
finally
CloseHandle(Handle);
end;
end;
function ProcessRunning(ExeName: string): Boolean;
var
SnapProcHandle: THandle;
NextProc: Boolean;
ProcEntry: TProcessEntry32;
ProcFileName: string;
begin
Result := False;
SnapProcHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if SnapProcHandle = INVALID_HANDLE_VALUE then
Exit;
try
ProcEntry.dwSize := SizeOf(ProcEntry);
NextProc := Process32First(SnapProcHandle, ProcEntry);
while NextProc do
begin
if ProcEntry.th32ProcessID <> 0 then
begin
ProcFileName := ProcessFileName(ProcEntry.th32ProcessID);
if ProcFileName = '' then
ProcFileName := ProcEntry.szExeFile;
if SameText(ExtractFileName(ProcFileName), ExeName) then
begin
Result := True;
Break;
end;
end;
NextProc := Process32Next(SnapProcHandle, ProcEntry);
end;
finally
CloseHandle(SnapProcHandle);
end;
end;
procedure Exec(FileName: string);
var
StartupInfo: TStartupInfo;
ProcessInfo: TProcessInformation;
begin
FillChar(StartupInfo, SizeOf(StartupInfo), #0);
StartupInfo.cb := SizeOf(StartupInfo);
StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
StartupInfo.wShowWindow := SW_SHOWDEFAULT;
if not CreateProcess(PChar(FileName), nil, nil, nil, False,
CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil,
PChar(ExtractFilePath(FileName)), StartupInfo, ProcessInfo) then
Exit;
WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
end;
end.
相关文章推荐
- 以“秒”粒度自动监控指定进程
- 守护进程监控tomcat并自动重启
- 用php写的进程守护,进程管理,进程出错自动启动功能,适合服务器管理员使用
- delphi如何在form显示出来后处理指定的事件(例如自动登录)
- 【问题记录】standby MRP进程挂了 报IO错误 重启MRP仍会自动停掉
- 一个监控指定进程的脚本
- zabbix监控IIS进程内存、cpu、错误页面等
- python守护进程监控hive server
- 使用nagios监控指定进程
- Windows 64位操作系统安装mysql 绿色版 mysql安装常见问题(系统找不到指定的文件、发生系统错误 1067 进程意外终止)
- php等守护进程监控脚本(转载 http://www.9958.pw/post/php_script_scan)
- Delphi 如何让程序获取权限结束指定进程?
- C# 屏幕监控 自动截屏程序 主窗体隐藏,仅在进程中显示
- mysql安装常见问题(系统找不到指定的文件、发生系统错误 1067 进程意外终止)
- linux监控进程并且自动重启
- linux进程监控与自动重启实现
- linux shell脚本守护进程监控svn服务
- Android Studio错误:无法启动守护程序进程
- zabbix使用自己编写脚本模板和zabbix自带模板两种方法添加对指定进程和端口的监控
- zabbix结合shell实现自动发现占用内存最大top10进程并监控其资源