【问题标题】:Starting a process and listening for exit event启动进程并监听退出事件
【发布时间】:2010-01-05 19:32:15
【问题描述】:

我有一些代码可以启动一个进程并连接一个事件处理程序以在进程退出时进行处理,我的代码是用 C# 编写的,我想知道 Delphi 是否可以实现类似的功能。

System.Diagnostics.Process myProcess = new System.Diagnostics.Process();
myProcess.StartInfo.FileName = "notepad.exe";
myProcess.EnableRaisingEvents = true;
myProcess.Exited += new System.EventHandler(Process_OnExit);
myProcess.Start();

public void Process_OnExit(object sender, EventArgs e)
{
    //Do something when the process ends
}

我对 Delphi 了解不多,因此不胜感激,谢谢。

【问题讨论】:

    标签: delphi code-conversion


    【解决方案1】:

    是的,你可以用 Delphi 做类似的事情。我没有见过使用事件处理程序,但是您可以创建一个进程,等待它完成,然后在发生这种情况时做一些事情。如果你想在此期间做点什么,把它放在另一个线程中。

    这是一些用于创建进程并等待我从网上刮下来的代码:

    procedure ExecNewProcess(const ProgramName : String; Wait: Boolean);
    var
      StartInfo : TStartupInfo;
      ProcInfo : TProcessInformation;
      CreateOK : Boolean;
    begin
      { fill with known state } 
      FillChar(StartInfo, SizeOf(TStartupInfo), 0);
      FillChar(ProcInfo, SizeOf(TProcessInformation), 0);
      StartInfo.cb := SizeOf(TStartupInfo);
      CreateOK := CreateProcess(nil, PChar(ProgramName), nil, nil, False,
                  CREATE_NEW_PROCESS_GROUP or NORMAL_PRIORITY_CLASS,
                  nil, nil, StartInfo, ProcInfo);
       { check to see if successful } 
      if CreateOK then
        begin
          //Note: This will wait forever if the process never ends! 
          // You are better off using a loop with a timeout, or WaitForMultipleObject 
          if Wait then
            WaitForSingleObject(ProcInfo.hProcess, INFINITE);
        end
      else
        begin
          RaiseLastOSError;
          //SysErrorMessage(GetLastError());
        end;
    
      CloseHandle(ProcInfo.hProcess);
      CloseHandle(ProcInfo.hThread);
    end;
    

    【讨论】:

    • 我不会使用 INFINITE,而是使用超时和循环来在需要时中断等待,或者使用带有事件的 WaitForMultipleObject() 来退出等待。否则可能无法干净地终止等待线程。此外,如果 CreateProcess() 失败,不要隐藏发出通用、无用消息的错误,而是调用 RaiseLasOSError 来显示真正的错误。
    • 另一个提示:FilLChar 最后一个参数不需要是一个字符——它可以是一个字节。为避免 Unicode 问题,如果您只是用零填充二进制结构,请传递 0,而不是 #0。
    • 两个好建议@ldsandon。我在生产代码中都做过。
    • @Jim:在标志中组合位时,应始终使用 OR 而不是 +。您在位标志级别进行操作,加法可能会得到与二进制 OR 不同的结果。
    • 我会在参数列表中的 ProgramName 前面加上“const”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-26
    • 2021-02-25
    • 2016-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多