Hoi,
zie referentie: http://www.nldelphi.com/forum/showth...9743#post29743
Blijkbaar blokkeert de functie in bovenstaande thread soms helemaal de verdere uitvoering van het programma. Dit gebeurt tijdens de uitvoering van 'ReadFile'. Deze blijft nl wachten indien er zero bytes te lezen zijn. Eén oplossing is er dus voor zorgen dat het console programma waarvan de output moet 'gevangen' worden altijd ook een output levert, ongeacht wat het resultaat is.
Is het niet mogelijk om het consoleprogramma altijd een output te laten leveren, dan bestaat er een andere oplossing: v????r de 'ReadFile' even kijken in de 'pipe' of er al iets instaat. Dit wordt gedaan met de 'PeekNamedPipe' functie. Door enkel 'ReadFile' aan te roepen als er inderdaad iets te lezen valt kan "CaptureConsoleOutput" nu dus ook console-applicaties aan die helemaal geen output geven.
De code is nu dus:
Code:
function CaptureConsoleOutput(const ACommand: string): string;
const
CReadBuffer = 2400;
var
saSecurity: TSecurityAttributes;
hRead: THandle;
hWrite: THandle;
suiStartup: TStartupInfo;
piProcess: TProcessInformation;
pBuffer: array[0..CReadBuffer] of Char;
dRead: DWord;
total, pending: DWord;
dRunning: DWord;
begin
Result := '';
with saSecurity do
begin
nLength := SizeOf(TSecurityAttributes);
bInheritHandle := True;
lpSecurityDescriptor := nil;
end;
if CreatePipe(hRead, hWrite, @saSecurity, 0) then
begin
FillChar(suiStartup, SizeOf(TStartupInfo), #0);
with suiStartup do
begin
cb := SizeOf(TStartupInfo);
hStdInput := hRead;
hStdOutput := hWrite;
hStdError := hWrite;
dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
wShowWindow := SW_HIDE;
if CreateProcess(nil, PChar(ACommand), @saSecurity, @saSecurity, True,
NORMAL_PRIORITY_CLASS, nil, nil, suiStartup,
piProcess) then
begin
WaitForInputIdle(piProcess.hProcess, 2000);
repeat
dRunning := WaitForSingleObject(piProcess.hProcess, 100);
Application.ProcessMessages();
repeat
PeekNamedPipe(hRead, nil, 0, nil, @total, nil);
if (total > 0) then
begin
ReadFile(hRead, pBuffer[0], CReadBuffer, dRead, nil);
pBuffer[dRead] := #0;
OemToAnsi(pBuffer, pBuffer);
Result := Result + string(pBuffer);
end;
until (total = 0);
until (dRunning <> WAIT_TIMEOUT);
CloseHandle(piProcess.hProcess);
CloseHandle(piProcess.hThread);
end;
CloseHandle(hRead);
CloseHandle(hWrite);
end;
end;
end;
Bookmarks