启动两个进程并使用Delphi中的管道连接它们

前端之家收集整理的这篇文章主要介绍了启动两个进程并使用Delphi中的管道连接它们前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我需要在程序中启动两个外部程序,并将第一个程序的STDOUT连接到第二个程序的STDIN.如何在Delphi中实现这一目标(RAD Studio 2009,如果重要的话)?我在 Windows环境中运行.

作为命令行命令,我的情况看起来像这样:

dumpdata.exe | encrypt.exe "mydata.dat"

解决方法

一个似乎有效的快速测试(受到 JCL的重大启发):

child1:说’你好,世界!’ 3倍至标准输出

program child1;

{$APPTYPE CONSOLE}

uses
  SysUtils;

procedure Main;
var
  I: Integer;
begin
  for I := 0 to 2 do
    Writeln('Hello,world!');
  Write(^Z);
end;

begin
  try
    Main;
  except
    on E: Exception do
    begin
      ExitCode := 1;
      Writeln(ErrOutput,Format('[%s] %s',[E.ClassName,E.Message]));
    end;
  end;
end.

child2:回显OutputDebugString的标准输入(可以通过DebugView查看)

program child2;

{$APPTYPE CONSOLE}

uses
  Windows,SysUtils,Classes;

procedure Main;
var
  S: string;
begin
  while not Eof(Input) do
  begin
    Readln(S);
    if S <> '' then
      OutputDebugString(PChar(S));
  end;
end;

begin
  try
    Main;
  except
    on E: Exception do
    begin
      ExitCode := 1;
      Writeln(ErrOutput,E.Message]));
    end;
  end;
end.

parent:启动child1重定向到child2

program parent;

{$APPTYPE CONSOLE}

uses
  Windows,Classes,SysUtils;

procedure ExecutePiped(const CommandLine1,CommandLine2: string);
var
  StartupInfo1,StartupInfo2: TStartupInfo;
  ProcessInfo1,ProcessInfo2: TProcessInformation;
  SecurityAttr: TSecurityAttributes;
  PipeRead,PipeWrite: THandle;
begin
  PipeWrite := 0;
  PipeRead := 0;
  try
    SecurityAttr.nLength := SizeOf(SecurityAttr);
    SecurityAttr.lpSecurityDescriptor := nil;
    SecurityAttr.bInheritHandle := True;
    Win32Check(CreatePipe(PipeRead,PipeWrite,@SecurityAttr,0));

    FillChar(StartupInfo1,SizeOf(TStartupInfo),0);
    StartupInfo1.cb := SizeOf(TStartupInfo);
    StartupInfo1.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
    StartupInfo1.wShowWindow := SW_HIDE;
    StartupInfo1.hStdInput := GetStdHandle(STD_INPUT_HANDLE);
    StartupInfo1.hStdOutput := PipeWrite;
    StartupInfo1.hStdError := GetStdHandle(STD_ERROR_HANDLE);

    FillChar(StartupInfo2,0);
    StartupInfo2.cb := SizeOf(TStartupInfo);
    StartupInfo2.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
    StartupInfo2.wShowWindow := SW_HIDE;
    StartupInfo2.hStdInput := PipeRead;
    StartupInfo2.hStdOutput := GetStdHandle(STD_OUTPUT_HANDLE);
    StartupInfo2.hStdError := GetStdHandle(STD_ERROR_HANDLE);

    FillChar(ProcessInfo1,SizeOf(TProcessInformation),0);
    FillChar(ProcessInfo2,0);

    Win32Check(CreateProcess(nil,PChar(CommandLine2),nil,True,NORMAL_PRIORITY_CLASS,StartupInfo2,ProcessInfo2));

    Win32Check(CreateProcess(nil,PChar(CommandLine1),StartupInfo1,ProcessInfo1));

    WaitForSingleObject(ProcessInfo2.hProcess,INFINITE);
  finally
    if PipeRead <> 0 then
      CloseHandle(PipeRead);
    if PipeWrite <> 0 then
      CloseHandle(PipeWrite);
    if ProcessInfo2.hThread <> 0 then
      CloseHandle(ProcessInfo2.hThread);
    if ProcessInfo2.hProcess <> 0 then
      CloseHandle(ProcessInfo2.hProcess);
    if ProcessInfo1.hThread <> 0 then
      CloseHandle(ProcessInfo1.hThread);
    if ProcessInfo1.hProcess <> 0 then
      CloseHandle(ProcessInfo1.hProcess);
  end;
end;

procedure Main;
begin
  ExecutePiped('child1.exe','child2.exe');
end;

begin
  try
    Main;
  except
    on E: Exception do
    begin
      ExitCode := 1;
      Writeln(Error,E.Message]));
    end;
  end;
end.

猜你在找的Delphi相关文章