3

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 を使用しています - ビルド 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;
4

1 に答える 1

4

を呼び出すときは、実行可能ファイルを提供する必要がありますCreateProcess。私はあなたがShellExecuteより緩い呼び出しに慣れていると思います。

あなたは明らかに電話をかけようとしているcmd.exeので、それをコマンドラインに追加する必要があります。cmd.exeの起動後に作業ディレクトリを変更するのではなく、 のlpCurrentDirectoryパラメータを使用してくださいCreateProcess。コマンドが完了したら閉じるには、/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フラグを結合するために使用する方が意味的には よりクリーンです。+

注意すべきことの 1 つは、2 番目のパラメータが書き込み可能なメモリを指している必要があることです。これCreateProcessは、そのパラメーターを変更する可能性があるためです。たまたま、あなたの設定はinputその要件を満たします。いずれにせよ、UniqueString私の見解では、あなたがその要件を満たしていることを明確にするために電話することをお勧めします。

他に欠けているのは、 によって返されるハンドルを閉じるコードですCreateProcess。最後にこれを実行して、これらのハンドルを閉じます。

//WaitForSingleObject(ProcInfo.hProcess, INFINITE); //in case you want to wait for Process to terminate
CloseHandle(ProcInfo.hProcess);
CloseHandle(ProcInfo.hThread);
于 2013-08-02T09:30:04.133 に答える