Hola y perdón por la intromisión.
Yo hace tiempo que utilicé esa técnica con varios motores de ajedrez, a los que les mandaba diferentes comandos , esperaba su respuesta y teniendo un control absoluto sobre la entrada y salida...
Código Delphi
[-]
procedure TFormMain.Launch(cmdline : string; ShowWindow : integer);
var ProcessInfo : TProcessInformation;
StartupInfo : TStartupInfo;
begin
CreatePipe(hOutReadPipe, hOutWritePipe, nil, 2024);
DuplicateHandle(GetCurrentProcess(),
hOutWritePipe, GetCurrentProcess(),
@hDupWritePipe, 0, True,
DUPLICATE_CLOSE_SOURCE or DUPLICATE_SAME_ACCESS);
CreatePipe(hInReadPipe, hInWritePipe, nil, 2024);
DuplicateHandle(GetCurrentProcess(),
hInReadPipe,GetCurrentProcess(),
@hDupReadPipe, 0, True, DUPLICATE_CLOSE_SOURCE or
DUPLICATE_SAME_ACCESS);
FillChar(StartupInfo,Sizeof(StartupInfo),#0);
StartupInfo.cb := Sizeof(StartupInfo);
StartupInfo.hStdOutput := hDupWritePipe;
StartupInfo.hStdError := hDupWritePipe;
StartupInfo.hStdInput := hDupReadPipe;
StartupInfo.wShowWindow := ShowWindow;
StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
CreateProcess(nil, PChar(cmdline), nil, nil, True, NORMAL_PRIORITY_CLASS, nil, nil,StartupInfo, ProcessInfo);
end;
Luego un par de funciones accesorias de control
Código Delphi
[-]
function TFormMain.ReadPipe(var S : string): Boolean;
var
dwAvail, dwRead : Cardinal;
PipeHandle : THandle;
begin
Result := False;
PipeHandle := hOutReadPipe;
dwAvail := 0;
PeekNamedPipe(PipeHandle, nil, 0, nil, @dwAvail, nil);
if dwAvail > 0 then
begin
SetLength(S, dwAvail);
ReadFile(PipeHandle, Pointer(S)^, dwAvail, dwRead, nil);
Result := True;
end;
Application.ProcessMessages;
end;
procedure TFormMain.WritePipe(s: string);
var Pstr : array[0..255] of char;
len : cardinal;
PipeHandle : THandle;
begin
PipeHandle := hInWritePipe;
StrPCopy(Pstr, s);
len := length(s);
WriteFile(PipeHandle, Pstr, len, len, nil);
Sleep(10);
end;
Otra alternativa es esta:
Código Delphi
[-]
function TFormMain.CreateDOSProcessRedirected(const CommandLine, InputFile,OutputFile: string): boolean;
var OldCursor: TCursor;
pCommandLine: array[0..MAX_PATH] of char;
pInputFile, pOutPutFile: array[0..MAX_PATH] of char;
StartupInfo: TStartupInfo;
ProcessInfo: TProcessInformation;
SecAtrrs: TSecurityAttributes;
hAppProcess, hAppThread, hInputFile, hOutputFile: THandle;
begin
result := false;
if ((InputFile <> '') and (not fileexists(InputFile))) then exit;
hAppProcess := 0;
hAppThread := 0;
hInputFile := 0;
hOutputFile := 0;
OldCursor := Screen.Cursor;
Screen.Cursor := crHourglass;
try
StrPCopy(pCommandLine, CommandLine);
StrPCopy(pInputFile, InputFile);
StrPCopy(pOutPutFile, OutputFile);
FillChar(SecAtrrs, SizeOf(SecAtrrs), #0);
SecAtrrs.nLength := SizeOf(SecAtrrs);
SecAtrrs.lpSecurityDescriptor := nil;
SecAtrrs.bInheritHandle := true;
if (InputFile <> '') then
begin
hInputFile := CreateFile(pInputFile, GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE, @SecAtrrs, OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL or FILE_FLAG_WRITE_THROUGH, 0);
if (hInputFile = INVALID_HANDLE_VALUE) then exit;
end else hInputFile := 0;
hOutputFile := CreateFile(pOutPutFile, GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE, @SecAtrrs, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL or FILE_FLAG_WRITE_THROUGH, 0);
if (hOutputFile = INVALID_HANDLE_VALUE) then exit;
FillChar(StartupInfo, SizeOf(StartupInfo), #0);
StartupInfo.cb := SizeOf(StartupInfo);
StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
StartupInfo.wShowWindow := SW_HIDE;
StartupInfo.hStdOutput := hOutputFile;
StartupInfo.hStdInput := hInputFile;
Application.ProcessMessages;
result := CreateProcess(nil, pCommandLine, nil, nil, TRUE,
HIGH_PRIORITY_CLASS ,
nil, nil, StartupInfo, ProcessInfo);
Application.ProcessMessages;
if (result) then
begin
WaitforSingleObject(ProcessInfo.hProcess, INFINITE);
hAppProcess := ProcessInfo.hProcess;
hAppThread := ProcessInfo.hThread;
end else exit;
finally
Application.ProcessMessages;
if (hOutputFile <> 0) then CloseHandle(hOutputFile);
if (hInputFile <> 0) then CloseHandle(hInputFile);
if (hAppThread <> 0) then CloseHandle(hAppThread);
if (hAppProcess <> 0) then CloseHandle(hAppProcess);
Screen.Cursor := OldCursor;
end;
end;
Uno de los casos en los que también lo utilicé, fue para ejecutar y leer el comando
NETSTAT. Pena que cuando me hacía falta, seoane todavía no había insertado su código
su post, y a mí me hacía falta
hace tiempo