Mira a ver si esta unit te sirve:
Código Delphi
[-]
unit PipeShell3;
interface
uses
Windows, Messages, SysUtils, Classes;
const
BUFFERSIZE = 4*1024;
type
TPipeShell = class
private
PipeIn, PipeOut, PipeWrite, PipeRead: THANDLE;
hProcess: THANDLE;
Buffer: PAnsiChar;
protected
public
constructor Create;
destructor Destroy; override;
function Write(S: AnsiString): DWORD;
function Read: AnsiString;
end;
implementation
constructor TPipeShell.Create;
var
sd: SECURITY_DESCRIPTOR;
sa: SECURITY_ATTRIBUTES;
si: STARTUPINFOA;
pi: PROCESS_INFORMATION;
begin
PipeIn:= 0;
PipeOut:= 0;
PipeWrite:= 0;
PipeRead:= 0;
hProcess:= 0;
GetMem(Buffer, BUFFERSIZE);
InitializeSecurityDescriptor(@sd, SECURITY_DESCRIPTOR_REVISION);
sa.lpSecurityDescriptor:= @sd;
sa.nLength:= sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle:= TRUE;
if CreatePipe(PipeIn, PipeWrite, @sa, 0) then
begin
if CreatePipe(PipeRead, PipeOut, @sa, 0) then
begin
GetStartupInfoA(Si);
si.hStdOutput:= PipeOut;
si.hStdError:= PipeOut;
si.hStdInput:= PipeIn;
si.dwFlags:= STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
si.wShowWindow:= SW_HIDE;
ZeroMemory(Buffer, BUFFERSIZE);
GetEnvironmentVariableA('COMSPEC', Buffer, BUFFERSIZE - 1);
if CreateProcessA(nil, Buffer, nil, nil, TRUE, CREATE_NEW_CONSOLE, nil, nil, si, pi) then
begin
hProcess:= pi.hProcess;
CloseHandle(pi.hThread);
end;
end;
end;
end;
destructor TPipeShell.Destroy;
var
ExitCode: DWORD;
begin
repeat
Write('quit'); Read;
Write('q'); Read;
Write('exit'); Read;
GetExitCodeProcess(hProcess, ExitCode);
until ExitCode <> STILL_ACTIVE;
if PipeIn <> 0 then CloseHandle(PipeIn);
if PipeOut <> 0 then CloseHandle(PipeOut);
if PipeWrite <> 0 then CloseHandle(PipeWrite);
if PipeRead <> 0 then CloseHandle(PipeRead);
if hProcess <> 0 then CloseHandle(hProcess);
if Buffer <> nil then FreeMem(Buffer);
if WaitForSingleObject(hProcess, 9000) <> WAIT_OBJECT_0 then
TerminateProcess(hProcess, DWORD(-1));
end;
function TPipeShell.Write(S: AnsiString): DWORD;
begin
if PipeWrite = 0 then exit;
lstrcpyA(Buffer, PAnsiCHAR(S + #10));
WriteFile(PipeWrite, Buffer^, lstrlenA(Buffer), Result, nil);
end;
function TPipeShell.Read: AnsiString;
var
dwRead, dwBytesAvail: DWORD;
begin
if PipeRead = 0 then exit;
dwRead:= 0;
repeat
sleep(100);
PeekNamedPipe(PipeRead, Buffer, BUFFERSIZE, @dwRead, @dwBytesAvail, nil);
if dwRead > 0 then
begin
ZeroMemory(Buffer, BUFFERSIZE);
ReadFile(PipeRead, Buffer^, dwRead, PDWORD(0)^, nil);
OemToCharBuffA(Buffer, Buffer, dwRead);
Result:= Result + AnsiString(Buffer);
end;
until dwBytesAvail = 0;
end;
end.
Para más información el código original lo publiqué
aquí.
Saludos.