する必要があったのでとりあえずつくってみた。
停止させるプロセスは、仕様上一意性が保障されている
ので、コマンドライン引数に起動するプロセスの絶対パスを
与えて、そこからプロセスIDを求めています。
プロセスに停止メッセージ(メインウインドウのクローズ)を
ポストし、5秒まっても終了していなかったら
強制終了しています。
プロセスの起動には、JvCreateProcessコンポーネントを
使っています。
このコンポーネントは、非常に便利ですね。
program RestartProcess; {$APPTYPE CONSOLE} uses SysUtils,Windows,TLHELP32,Messages,JvCreateProcess; function GetProcessFromName(ProcessName :String) : Cardinal; var ProcEntry : TProcessEntry32; SanpshotHandle : THandle; ListProcName : String; begin //Toolhelp32を使用する例 Result := 0; SanpshotHandle := TlHelp32.CreateToolhelp32Snapshot(TlHelp32.TH32CS_SNAPPROCESS,0); if (SanpshotHandle <> -1) then begin ProcEntry.dwSize := Sizeof(TProcessEntry32W); if (TlHelp32.Process32First(SanpshotHandle,ProcEntry)) Then begin repeat ListProcName := ProcEntry.szExeFile; if CompareText(ListProcName,ProcessName) = 0 then begin Result := ProcEntry.th32ProcessID; end; //WriteLn(ListProcName); until (TlHelp32.Process32Next(SanpshotHandle,ProcEntry) = false); end; end; CloseHandle(SanpshotHandle); end; function EnumWindowsProc(hwindow :HWnd; lparam :LPARAM):BOOL; stdcall; var ProcessID : Cardinal; ThreadID : Cardinal; begin Result := True; ThreadID := GetWindowThreadProcessId(hwindow, ProcessID); If (ProcessID = lParam) Then begin PostMessage(hwindow, WM_CLOSE, 0, 0); Result := true; End; End; function SendClose(ProcID : Cardinal) : Boolean; begin Result := EnumWindows(@EnumWindowsProc, ProcID) End; function StopProcess(ProcessName : String; Force : Boolean = false) : Integer; var ProcessID : Cardinal; hProcess : THandle; begin ProcessID := GetProcessFromName(ProcessName); if ProcessID = 0 then begin Result := -1; end else begin if (ProcessID > 0) Then begin if Force then begin hProcess := OpenProcess(PROCESS_TERMINATE, False, ProcessID); TerminateProcess(hProcess , 0 ); CloseHandle(hProcess); Result := 0; end else begin Result := 1; if SendClose(ProcessID) then begin Result := 0; end; end; end; end; end; var StopResult : Integer; JvCreateProcess: TJvCreateProcess; ExeName : String; ProcessID : Cardinal; begin try { TODO -oUser -cConsole Main : ここにコードを記述してください } if ParamCount > 0 then begin ExeName := ExtractFileName(ParamStr(1)); StopResult := StopProcess(ExeName); //五秒まって停止イしたかどうかを確認する Sleep(5000); ProcessID := GetProcessFromName(ExeName); //プロセスが正常に停止できなかったので' + //強制終了する if ProcessID > 0 Then begin StopResult := StopProcess(ExeName,true); Sleep(10000); end; if StopResult <> 1 then begin JvCreateProcess := TJvCreateProcess.Create(nil); try JvCreateProcess.CommandLine := ParamStr(1); JvCreateProcess.WaitForTerminate := false; JvCreateProcess.Run; finally JvCreateProcess.Free; end; end; end; //ReadLn; except on E:Exception do Writeln(E.Classname, ': ', E.Message); end; end.
0 件のコメント:
コメントを投稿