2009-09-21 35 views
21

我需要从Delphi软件执行Windows“查找”命令。我试过使用ShellExecute命令,但它似乎不起作用。在C中,我会使用system程序,但在这里......我不知道。我想要做这样的事情:如何在Delphi中运行命令行程序?

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

编辑:感谢您的回答:) 我试图运行“查找”作为一个可执行的,而不是作为论据的cmd.exe。

+2

ShellExecute应该工作。它在干什么,不干什么或者干什么? – 2009-09-21 13:30:50

回答

26

使用ShellExecute()一个例子:

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 2009-09-21 13:38:27

+0

的确,感谢您的发现。 – mghie 2009-09-21 13:40:14

+0

呃,如果窗口被隐藏(SW_HIDE),为什么我们应该在ShellExecute之后放置一个Sleep(1000)? – gramm 2009-09-21 13:58:35

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:

捕获控制台输出在[实时],以及它如何在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