delphi 程序重新启动自身


本文整理自网络,侵删。

 
=======================
用于重启动的进程,等到传入的进程确实退出后,再执行传入的命令行
=======================
program tmRestart;

//{$APPTYPE CONSOLE}

uses
  Windows,
  Dialogs,
  Classes,
  SysUtils;

procedure StopProcess(ProcessID : DWORD);
var
  Handle: THandle;
begin
  Handle := OpenProcess(PROCESS_TERMINATE or PROCESS_VM_READ, False, ProcessID);
  if Handle <> 0 then
    try
      TerminateProcess(Handle,0);
      WaitForSingleObject(Handle,INFINITE);
    finally
      CloseHandle(Handle);
    end;
end;

var
  vProcessID:integer;
  vCommandLine:string;
  vList:TStringList;
  vHandle:THandle;
begin
  vList:=TStringList.Create;
  try
    vList.Delimiter:=' ';
    vList.CommaText:=Windows.GetCommandLine;
    if vList.Count<3 then exit;
    vProcessID:=StrToInt(vList[1]);
    vCommandLine:=vList[2];
  finally
    vList.Free;
  end;
  //ParamStr函数有bug,会去掉任何的双引号,当文件夹有空格会出问题
  //'"D:\Shanghai China\A.exe" "D:\Shanhai China\A.ini"',会得到'D:\Shanghai China\A.exe D:\Shanhai China\A.ini'
  //vProcessID:=StrToInt(ParamStr(1));
  //vCommandLine:=ParamStr(2);
  repeat
    Sleep(100);
    vHandle := Windows.OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, vProcessID);
    if vHandle<>0 then CloseHandle(vHandle);
  until vHandle=0;

  //不要强制终止,会导致单元的finialization执行不到
  //StopProcess(vProcessID);
  Windows.WinExec(PChar(vCommandLine),SW_Show);
end.





=====================================
主程序
ExitProgram是一个boolean变量,主窗体的Logout功能把它设为false
=====================================
program ERP2009;
{$R *.RES}
function WinExecAndWait32(AExeFile,AParams:WideString;AIsShowGUI:Boolean;AIsWaitingResult:Boolean):cardinal;
var
  ExecInfo:   TShellExecuteInfoW;
  ucmdShow:integer;
begin
  Result:=$FFFF;
  if AIsShowGUI then ucmdShow:=SW_Show
  else ucmdShow:=SW_Hide;
  ZeroMemory(@ExecInfo,SizeOf(ExecInfo));
  ExecInfo.cbSize   :=   SizeOf(ExecInfo);
  ExecInfo.fMask    :=   SEE_MASK_NOCLOSEPROCESS;
  ExecInfo.lpVerb   :=   'open';
  ExecInfo.lpFile   :=   PWideChar(AExeFile);
  ExecInfo.lpParameters:=PWideChar(AParams);
  ExecInfo.Wnd      :=   0;
  ExecInfo.nShow    :=   ucmdShow;
  if ShellExecuteExW(@ExecInfo) then
  begin
    Result:=0;
    if AIsWaitingResult then
    begin
      if WaitforSingleObject(ExecInfo.hProcess,INFINITE)=WAIT_OBJECT_0 then
        GetExitCodeProcess(ExecInfo.hProcess,Result);
    end;
  end;
end;

procedure RestartProgramme(AMonitorFileName:WideString);
var
  i:integer;
  //S:string;
  CommandLine:WideString;
  vExeFile,vParam:WideString;
begin
  CommandLine:='';
  for i:=0 to ParamCount do
  begin
    if CommandLine<>'' then CommandLine:=CommandLine+' ';
    CommandLine:=CommandLine+AnsiQuotedStr(ParamStr(i),'"');
  end;
  {S:=AnsiQuotedStr(ExtractFilePath(Application.ExeName)+'KMonitor.exe','"')+' '+
     InttoStr(Windows.GetCurrentProcessID)+' '+
     AnsiQuotedStr(CommandLine,'"');
  }
  vExeFile:=AnsiQuotedStr(ExtractFilePath(Application.ExeName)+AMonitorFileName,'"');
  vParam:=InttoStr(Windows.GetCurrentProcessID)+' '+AnsiQuotedStr(CommandLine,'"');

  //用WinExec会感觉卡
  //Windows.WinExecW(PWideChar(S),SW_Hide);
  WinExecAndWait32(vExeFile,vParam,false,false);
end;

begin
  //也许这里有检查只能启动一个进程的代码
  //........
  ExitProgram:=true;
  Application.Initialize;
  Application.CreateForm(TIDEMainForm, IDEMainForm);
  Application.Run;
  if not ExitProgram then
    RestartProgramme('tmRestart.exe');
end.

相关阅读 >>

Delphi fmx 把内容复制到粘贴板上支持跨平台

Delphi2010 无法继承窗体的bug

Delphi 获得指定进程的id号

Delphi获取webbrowser中的元素的值

Delphi xe5 json

Delphi多线程学习:多线程数据库查询(ado)

delph记录输出日志

Delphi 提取字符串左侧内容

Delphi shellexecute多种用法

Delphi写入txt

更多相关阅读请进入《Delphi》频道 >>



打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...

    暂无评论...