繁体   English   中英

Delphi - CreateProcess - 执行多个命令

[英]Delphi - CreateProcess - Execute multiple commands

我想用CreateProcess()实现以下功能 - 调用:

  1. 更改为svn工作副本
  2. 执行svn命令
  3. 将输出传递给文件

我尝试使用以下功能

procedure TQPortMainForm.CmdMigrationClick(Sender: TObject);
var
  StartInfo: TStartupInfo;
  ProcInfo: TProcessInformation;
  CreateOk: boolean;
  input: String;
begin
  { fill with known state }
  FillChar(StartInfo, SizeOf(TStartupInfo), #0);
  FillChar(ProcInfo, SizeOf(TProcessInformation), #0);
  StartInfo.cb := SizeOf(TStartupInfo);

  //debug
  input := 'D: && cd D:\Qport\trunk\Qport\ && ' + SVN_PATH + ' log > C:\users\PhilippKober\UNIQUE_NAME_BLUB.txt';

  CreateOk := CreateProcess(nil, PChar(input), nil, nil, false, CREATE_NEW_PROCESS_GROUP + NORMAL_PRIORITY_CLASS, nil,
    nil , StartInfo, ProcInfo);
  { check to see if successful }
  if CreateOk then
    // may or may not be needed. Usually wait for child processes
    WaitForSingleObject(ProcInfo.hProcess, INFINITE);
end;

没有任何反应。 有谁知道如何实现这一目标?

谢谢,

菲利普

编辑1:我正在使用Delphi XE - Build 7601:Service Pack 1

编辑2:这是解决方案:

var
  StartInfo: TStartupInfo;
  ProcInfo: TProcessInformation;
  CreateOk: boolean;
  input: String;
  path : String;
  cmd : String;
begin
  { fill with known state }
  FillChar(StartInfo, SizeOf(TStartupInfo), #0);
  FillChar(ProcInfo, SizeOf(TProcessInformation), #0);
  StartInfo.cb := SizeOf(TStartupInfo);

  path := 'D:\Qport\trunk\Qport\';
  cmd := 'C:\Windows\System32\cmd.exe';
  //debug
  input := '/C' + SVN_PATH + ' help > C:\users\PhilippKober\UNIQUE_NAME_BLUB.txt';

  CreateOk := CreateProcess(PChar(cmd), PChar(input), nil, nil, false, CREATE_NEW_PROCESS_GROUP + NORMAL_PRIORITY_CLASS, nil,
     Pchar(path), StartInfo, ProcInfo);
  { check to see if successful }
  if CreateOk then
    // may or may not be needed. Usually wait for child processes
    WaitForSingleObject(ProcInfo.hProcess, INFINITE);
end;

调用CreateProcess时需要提供可执行文件。 我猜你习惯调用ShellExecute ,这更松懈。

您显然希望调用cmd.exe因此您应该将其添加到命令行。 而不是在cmd.exe启动后更改工作目录,而是使用CreateProcesslpCurrentDirectory参数来执行此操作。 您还需要将/C选项传递给cmd.exe ,以便在命令完成后将其关闭。

所以你需要改变input

input := GetEnvironmentVariable('COMSPEC') + ' /C ' + SVN_PATH + 
  ' log > C:\users\PhilippKober\UNIQUE_NAME_BLUB.txt';

我使用GetEnvironmentVariable('COMSPEC')作为获取命令解释器路径的方法。

然后像这样调用CreateProcess

CreateProcess(
  nil, 
  PChar(input), 
  nil, 
  nil, 
  False, 
  CREATE_NEW_PROCESS_GROUP or NORMAL_PRIORITY_CLASS, 
  nil,
  'D:\Qport\trunk\Qport', 
  StartInfo, 
  ProcInfo
);

尽管它对这些标志具有相同的效果,但使用or组合标志比使用+更加语义清晰。

需要注意的是,第二个参数必须指向可写内存。 那是因为CreateProcess可能会修改该参数。 碰巧,您的input设置将满足该要求。 在任何情况下,我都建议在我的视图中调用UniqueString ,以明确表示您满足该要求。

我看到的另一件事是缺少关闭CreateProcess返回的句柄的代码。 最后通过执行此操作来关闭这些句柄:

//WaitForSingleObject(ProcInfo.hProcess, INFINITE); //in case you want to wait for Process to terminate
CloseHandle(ProcInfo.hProcess);
CloseHandle(ProcInfo.hThread);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM