Skip to content

Instantly share code, notes, and snippets.

@sum2012
Last active May 9, 2023 21:20
Show Gist options
  • Save sum2012/0891864a43a5ab90b1386e48ff459537 to your computer and use it in GitHub Desktop.
Save sum2012/0891864a43a5ab90b1386e48ff459537 to your computer and use it in GitHub Desktop.
FixedPipeWithWindowsConsole.dpr
program PipeWithWindowsConsole;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils, System.Classes, Winapi.Windows;
type
TOutputThread = class(TThread)
private
FReadPipe: THandle;
protected
procedure Execute; override;
public
constructor Create(ReadPipe: THandle);
end;
constructor TOutputThread.Create(ReadPipe: THandle);
begin
inherited Create(False);
FReadPipe := ReadPipe;
end;
procedure TOutputThread.Execute;
var
Buffer: array[0..1023] of AnsiChar;
BytesRead: DWORD;
begin
while not Terminated do
begin
if ReadFile(FReadPipe, Buffer, SizeOf(Buffer)-1, BytesRead, nil) then
begin
if BytesRead > 0 then
begin
Buffer[BytesRead] := #0;
Write(AnsiString(Buffer));
end;
end
else
Break;
end;
end;
procedure RunProcess;
var
StartupInfoA: TStartupInfoA;
ProcessInfo: TProcessInformation;
SecurityAttributes: TSecurityAttributes;
ReadPipe, WritePipe: THandle;
OutputThread: TOutputThread;
CommandLine: string;
Input: string;
BytesRead: DWORD;
begin
SecurityAttributes.nLength := SizeOf(TSecurityAttributes);
SecurityAttributes.bInheritHandle := True;
SecurityAttributes.lpSecurityDescriptor := nil;
if not CreatePipe(ReadPipe, WritePipe, @SecurityAttributes, 0) then
RaiseLastOSError;
FillChar(StartupInfoA, SizeOf(StartupInfoA), 0);
StartupInfoA.cb := SizeOf(StartupInfoA);
StartupInfoA.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
StartupInfoA.wShowWindow := SW_HIDE;
StartupInfoA.hStdInput := GetStdHandle(STD_INPUT_HANDLE);
StartupInfoA.hStdOutput := WritePipe;
StartupInfoA.hStdError := WritePipe;
CommandLine := 'cmd.exe';
if not CreateProcessA(nil, PAnsiChar(AnsiString(CommandLine)), nil, nil, True, 0, nil, nil, StartupInfoA, ProcessInfo) then
RaiseLastOSError;
CloseHandle(WritePipe);
// Input := 'dir';
// Input := #13#10;
// WriteFile(ProcessInfo.hThread, PChar(Input)^, Length(Input), BytesRead, nil);
OutputThread := TOutputThread.Create(ReadPipe);
try
while True do
begin
// ReadLn(Input);
if SameText(Input, 'exit') then
Break;
// Input := Input + #13#10
// WriteFile(ProcessInfo.hThread, PChar(Input)^, Length(Input), BytesRead, nil);
end;
finally
OutputThread.Terminate;
OutputThread.WaitFor;
OutputThread.Free;
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
CloseHandle(ReadPipe);
end;
end;
begin
try
RunProcess;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
en
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment