【问题标题】:Closing a CMD Window after launching an application through command line from Delphi从 Delphi 通过命令行启动应用程序后关闭 CMD 窗口
【发布时间】:2017-05-21 14:10:14
【问题描述】:

我正在尝试执行以下操作。它可以工作,但 cmd 窗口在退出之前等待 acrobat.exe 完成执行。我必须使用这种启动方法,因为我打算将来传递某些命令行参数。

cmdLineString := Format('/c ""%s" "%s""',['C:\Program Files (x86)\Adobe\Acrobat 11.0\Acrobat\Acrobat.exe', 'F:\Android-interview\Packt.Android.3.0.Application.Development.Cookbook.Jul.2011.ISBN.1849512949.pdf']);
ShellExecute(Handle, 'open', 'cmd.exe', PChar(CmdLineString), nil, SW_SHOWNORMAL);

【问题讨论】:

    标签: delphi delphi-xe5


    【解决方案1】:

    有很多方法可以改善这一点:

    1. 不要使用ShellExecute。这样做很诱人,因为它很容易调用。但是,它不是很灵活。请改用CreateProcess。
    2. 如果您必须隐藏控制台窗口,请将CREATE_NO_WINDOW 标志传递给CreateProcess。
    3. 也就是说,在这里使用cmd 是没有意义的。您不需要创建一个创建另一个进程的进程。这样做实际上使传递论点变得更加困难。直接创建 Acrobat 进程。剪掉中间人。

    【讨论】:

      【解决方案2】:

      正如 David 所回答的,在关注了一些关于 CreateProcess 的其他问题之后,解决方案代码最终如下所示。为像我这样的其他初学者放在这里。想想用这段代码可以实现什么!谢谢你,德尔福。

      procedure TForm.btnCMDLaunchClick(Sender: TObject);
      var
         commandLine: string;
         si: TStartupInfo;
         pi: TProcessInformation;
      begin
         commandLine := Format('%s %s',['C:\Program Files (x86)\Adobe\Acrobat 11.0\Acrobat\Acrobat.exe', 'F:\Android-interview\Packt.Android.3.0.Application.Development.Cookbook.Jul.2011.ISBN.1849512949.pdf']);
         UniqueString(commandLine);
         si := Default(TStartupInfo);
         si.cb := sizeof(si);
      
            if CreateProcess(
              PChar(nil),         //no module name (use command line)
              PChar(commandLine), //Command Line
              nil,                //Process handle not inheritable
              nil,                //Thread handle not inheritable
              False,              //Don't inherit handles
              0,                  //No creation flags
              nil,                //Use parent's environment block
              PChar(nil),         //Use parent's starting directory
              si,                 //Startup Info
              pi                  //Process Info
            ) then begin
             CloseHandle(pi.hProcess);
             CloseHandle(pi.hThread);
            end;
      end;
      

      【讨论】:

      • 此代码不检查错误并泄漏两个句柄。
      • si,pi需要freeandnil到底是fileexist错误吗?
      • 没有。您需要检查返回值是否有错误,如果成功则将进程和线程句柄传递给 CloseHandle。文档中对此进行了解释。
      • 是的,就是这样。
      猜你喜欢
      • 1970-01-01
      • 2016-06-10
      • 1970-01-01
      • 2018-03-01
      • 1970-01-01
      • 2012-01-21
      • 1970-01-01
      • 1970-01-01
      • 2011-01-13
      相关资源
      最近更新 更多