Delphi - CreateProcess - Execute multiple commands

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

  1. Change to an svn working-copy
  2. Execute svn commands
  3. Pipe the output to a file

I try this with the following function

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?

Thanks,

Philipp

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

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;

Answers


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

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.

So you need to change input to be this:

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

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

And then call CreateProcess like this:

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.

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.

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);

Need Your Help

Stacks, queues and linked lists

data-structures stack queue

I have started learning data structures recently, and just had my own linked list implementation. Now I stumbled upon two new data structures: stack and queue.

XPath locators vs JQuery locators in Selenium

jquery selenium css-selectors xpath

I've found out that people use JQuery element-locators in Selenium. I like the idea and I'd like to ask about benefits from using JQuery selectors instead of XPath ones. Are they more "flexible" or...

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.