2009-09-21 20 views
21

私はDelphiソフトウェアからWindowsの "find"コマンドを実行する必要があります。私はShellExecuteコマンドを使用しようとしましたが、動作しないようです。 Cでは、私はsystem手続きを使いますが、ここに...私は知らない。私はこのような何かをしたいと思います:Delphiでコマンドラインプログラムを実行するにはどうすればよいですか?

System('find "320" in.txt > out.txt'); 

編集:私はないcmd.exeのための引数として、実行可能ファイルとして「検索」を実行しようとしていた答え:) てくれてありがとう。

ShellExecute()
+2

ShellExecuteが動作するはずです。何をやっているのか、何もしていないのか? –

答えて

26

を使用した例:

procedure TForm1.Button1Click(Sender: TObject); 
begin 
    ShellExecute(0, nil, 'cmd.exe', '/C find "320" in.txt > out.txt', nil, SW_HIDE); 
    Sleep(1000); 
    Memo1.Lines.LoadFromFile('out.txt'); 
end; 

CreateProcess()代わりにShellExecute()を使用するプロセスのより良い制御を可能にすること。

これはセカンダリスレッドでも呼び出すのが理想的で、プロセスハンドルのWaitForSingleObject()を呼び出してプロセスが完了するまで待ちます。この例のSleep()は、ShellExecute()によって開始されたプログラムが終了するまでに少し時間がかかります。ShellExecute()はそれをしません。たとえば、ファイルを編集するためにnotepadインスタンスを単に開くことができなかった場合、ShellExecute()はエディタが閉じられるまで親アプリケーションをブロックします。

+0

これはMemo1.Lines.LoadFromFile( 'out.txt')ではありません。 – IanH

+0

本当に、それを見つけていただきありがとうございます。 – mghie

+0

ウィンドウが隠れている場合(SW_HIDE)、なぜShellExecuteの後にスリープ(1000)を入れるべきですか? – gramm

12

Variant1:

これは 'DOS' プログラムを実行し、その出力を取得します:

function GetDosOutput(CommandLine: string; Work: string = 'C:\'): string; { Run a DOS program and retrieve its output dynamically while it is running. } 
var 
    SecAtrrs: TSecurityAttributes; 
    StartupInfo: TStartupInfo; 
    ProcessInfo: TProcessInformation; 
    StdOutPipeRead, StdOutPipeWrite: THandle; 
    WasOK: Boolean; 
    pCommandLine: array[0..255] of AnsiChar; 
    BytesRead: Cardinal; 
    WorkDir: string; 
    Handle: Boolean; 
begin 
    Result := ''; 
    with SecAtrrs do begin 
    nLength := SizeOf(SecAtrrs); 
    bInheritHandle := True; 
    lpSecurityDescriptor := nil; 
    end; 
    CreatePipe(StdOutPipeRead, StdOutPipeWrite, @SecAtrrs, 0); 
    try 
    with StartupInfo do 
    begin 
     FillChar(StartupInfo, SizeOf(StartupInfo), 0); 
     cb := SizeOf(StartupInfo); 
     dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES; 
     wShowWindow := SW_HIDE; 
     hStdInput := GetStdHandle(STD_INPUT_HANDLE); // don't redirect stdin 
     hStdOutput := StdOutPipeWrite; 
     hStdError := StdOutPipeWrite; 
    end; 
    WorkDir := Work; 
    Handle := CreateProcess(nil, PChar('cmd.exe /C ' + CommandLine), 
          nil, nil, True, 0, nil, 
          PChar(WorkDir), StartupInfo, ProcessInfo); 
    CloseHandle(StdOutPipeWrite); 
    if Handle then 
     try 
     repeat 
      WasOK := windows.ReadFile(StdOutPipeRead, pCommandLine, 255, BytesRead, nil); 
      if BytesRead > 0 then 
      begin 
      pCommandLine[BytesRead] := #0; 
      Result := Result + pCommandLine; 
      end; 
     until not WasOK or (BytesRead = 0); 
     WaitForSingleObject(ProcessInfo.hProcess, INFINITE); 
     finally 
     CloseHandle(ProcessInfo.hThread); 
     CloseHandle(ProcessInfo.hProcess); 
     end; 
    finally 
    CloseHandle(StdOutPipeRead); 
    end; 
end; 

バリアント2:[リアルタイム]で

キャプチャコンソール出力とどのようにin a a TMemo:

procedure CaptureConsoleOutput(const ACommand, AParameters: String; AMemo: TMemo); 
const 
    CReadBuffer = 2400; 
var 
    saSecurity: TSecurityAttributes; 
    hRead: THandle; 
    hWrite: THandle; 
    suiStartup: TStartupInfo; 
    piProcess: TProcessInformation; 
    pBuffer: array[0..CReadBuffer] of AnsiChar;  <----- update 
    dRead: DWord; 
    dRunning: DWord; 
begin 
    saSecurity.nLength := SizeOf(TSecurityAttributes); 
    saSecurity.bInheritHandle := True; 
    saSecurity.lpSecurityDescriptor := nil; 

    if CreatePipe(hRead, hWrite, @saSecurity, 0) then 
    begin  
    FillChar(suiStartup, SizeOf(TStartupInfo), #0); 
    suiStartup.cb := SizeOf(TStartupInfo); 
    suiStartup.hStdInput := hRead; 
    suiStartup.hStdOutput := hWrite; 
    suiStartup.hStdError := hWrite; 
    suiStartup.dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;  
    suiStartup.wShowWindow := SW_HIDE; 

    if CreateProcess(nil, PChar(ACommand + ' ' + AParameters), @saSecurity, 
     @saSecurity, True, NORMAL_PRIORITY_CLASS, nil, nil, suiStartup, piProcess) 
     then 
    begin 
     repeat 
     dRunning := WaitForSingleObject(piProcess.hProcess, 100);   
     Application.ProcessMessages(); 
     repeat 
      dRead := 0; 
      ReadFile(hRead, pBuffer[0], CReadBuffer, dRead, nil);   
      pBuffer[dRead] := #0; 

      OemToAnsi(pBuffer, pBuffer); 
      AMemo.Lines.Add(String(pBuffer)); 
     until (dRead < CReadBuffer);  
     until (dRunning <> WAIT_TIMEOUT); 
     CloseHandle(piProcess.hProcess); 
     CloseHandle(piProcess.hThread);  
    end; 

    CloseHandle(hRead); 
    CloseHandle(hWrite); 
    end; 
end; 

出典:delphi.wikia.com

関連する問題