zoukankan      html  css  js  c++  java
  • 监控指定进程

    对于守护中间件是非常有用的。中间件不可能绝对的稳定而不出问题,中间件有可能因比较严重的错误导致当机或者进程被人为地错误地关闭了中间件。

    有了这个自动守护进程的存在,这一切的问题都可以迎刃而解。

    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.

  • 相关阅读:
    jQuery插件之jqzoom
    python数据分析画图体验
    python正则表达式,以及应用[下载图片]
    Python 程序如何高效地调试?
    从汉诺塔游戏理解python递归函数
    Python文本文件的输入输出操作学习
    Windows搭建python开发环境
    python循环综合运用
    Python参数传递,既不是传值也不是传引用
    使用python实现用微信远程控制电脑
  • 原文地址:https://www.cnblogs.com/hnxxcxg/p/2920453.html
Copyright © 2011-2022 走看看