작동하는 것 같다 빠른 테스트 (JCL에 의해 크게 영감) :
자식 1을 : 대답 '안녕하세요, 세계!' 표준 출력으로 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.
자식 2 : 어떤이 (DebugView 볼 수 있습니다) OutputDebugString로에 표준 입력에 제공 에코
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, Format('[%s] %s', [E.ClassName, E.Message]));
end;
end;
end.
부모 : 발사 자식 1은 여기
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, SizeOf(TStartupInfo), 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, SizeOf(TProcessInformation), 0);
Win32Check(CreateProcess(nil, PChar(CommandLine2), nil, nil, True, NORMAL_PRIORITY_CLASS, nil, nil, StartupInfo2,
ProcessInfo2));
Win32Check(CreateProcess(nil, PChar(CommandLine1), nil, nil, True, NORMAL_PRIORITY_CLASS, nil, nil, 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, Format('[%s] %s', [E.ClassName, E.Message]));
end;
end;
end.
정확히 찾고있는 모양입니다. 고맙습니다. 어떤 이유로 부모 프로그램을 실행하면 "모듈 kernel32.dll에서 액세스 위반"첫 번째 CreateProcess 줄에 제공합니다. 나는 모든 프로그램을 만들었습니다. 어쩌면 내가 뭔가를 놓치고있어 ... – Steve
A/V를 유발할 수있는 코드에는 아무것도 표시되지 않습니다. D2007을 사용했지만 D2009에서도 작동합니다. –
CreateProcess의 넓은 문자 버전 (Delphi 2009에서 호출하는 것)은 명령 줄 문자열을 수정할 수 있으므로 문자열 리터럴을 전달하면 안됩니다. 문자열 변수에 저장하고 UniqueString을 호출 한 다음 PChar에 형식 변환합니다. –