从 Delphi 通过命令行启动应用程序后关闭 CMD Window
Closing a CMD Window after launching an application through command line from Delphi
我正在尝试执行以下操作。它有效,但 cmd window 等待 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);
有多种方法可以改善这一点:
- 不要使用
ShellExecute
。这样做很诱人,因为调用起来很简单。但是,它不是很灵活。请改用 CreateProcess
。
- 如果您必须隐藏控制台 window,请将
CREATE_NO_WINDOW
标志传递给 CreateProcess
。
- 也就是说,在这里使用
cmd
没有意义。您不需要创建一个进程来创建另一个进程。这样做实际上使传递论点变得更加困难。直接创建 Acrobat 进程。切掉中间人。
正如 David 所回答的那样,在回答了一些关于 CreateProcess
的其他问题之后,解决方案代码最终如下所示。放在这里是为了像我这样的初学者。想想看这段代码可以做些什么!谢谢,Delphi。
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;
我正在尝试执行以下操作。它有效,但 cmd window 等待 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);
有多种方法可以改善这一点:
- 不要使用
ShellExecute
。这样做很诱人,因为调用起来很简单。但是,它不是很灵活。请改用CreateProcess
。 - 如果您必须隐藏控制台 window,请将
CREATE_NO_WINDOW
标志传递给CreateProcess
。 - 也就是说,在这里使用
cmd
没有意义。您不需要创建一个进程来创建另一个进程。这样做实际上使传递论点变得更加困难。直接创建 Acrobat 进程。切掉中间人。
正如 David 所回答的那样,在回答了一些关于 CreateProcess
的其他问题之后,解决方案代码最终如下所示。放在这里是为了像我这样的初学者。想想看这段代码可以做些什么!谢谢,Delphi。
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;