Delphi - CreateProcess - 执行多个命令 [英] Delphi - CreateProcess - Execute multiple commands

查看:2256
本文介绍了Delphi - CreateProcess - 执行多个命令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想通过CreateProcess()来实现以下内容:调用:

I want to achieve the following with a CreateProcess() - call:


  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;

没有任何反应。有没有人知道如何实现这一点?

Simply nothing happens. Has anybody got an idea how to achieve this?

谢谢,

Philipp

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

EDIT 1: I am using Delphi XE - Build 7601: Service Pack 1

编辑2:这是解决方案:

EDIT 2: Here is the solution:

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;


推荐答案

您需要提供一个可执行文件, code> CreateProcess 。我想你习惯于调用 ShellExecute 这是更松散的。

You need to supply an executable file when you call CreateProcess. I guess you are used to calling ShellExecute which is more lax.

你显然要调用 cmd.exe 所以你应该添加到命令行。 cmd.exe 已经开始,而不是更改工作目录,请使用 lpCurrentDirectory 参数CreateProcess 来做到这一点。一旦命令完成,您还需要将 / C 选项传递给 cmd.exe

You are clearly looking to call cmd.exe so you should add that to the command line. Rather than changing the working directory after cmd.exe has started, use the lpCurrentDirectory parameter of CreateProcess to do that. You will also need to pass the /C option to cmd.exe to make it close once the command has completed.

所以您需要更改输入为:

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

我使用 GetEnvironmentVariable('COMSPEC')作为获取命令解释器路径的一种手段。

I use GetEnvironmentVariable('COMSPEC') as a means to obtain the path to the command interpretor.

然后调用 CreateProcess ,如下所示:

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

使用来语义更清晰组合标志比 + ,虽然它们对这些标志具有相同的效果。

It is semantically cleaner to use or to combine flags than +, although it has the same effect for these flags.

需要注意的一件事是第二个参数必须指向可写内存。这是因为 CreateProcess 可能会修改该参数。在这种情况下,您的设置输入将满足该要求。在任何情况下,我建议您调用 UniqueString ,以便明确表示您符合该要求。

One thing to watch out for is that the second parameter must point to writeable memory. That's because CreateProcess may modify that parameter. As it happens, your setting of input will meet that requirement. In any case, a call to UniqueString would be recommended in my view to make it explicit that you are meeting that requirement.

我看到的另一件事是缺少代码来关闭由 CreateProcess 返回的句柄。通过这样做来关闭这些句柄:

The other thing I see that is missing is code to close the handles that are returned by CreateProcess. Close those handles by doing this in the end:

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

这篇关于Delphi - CreateProcess - 执行多个命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆