// Konsolen-kommando ausführen und Ergebnis/Fehler zurückliefern
function ExecConsoleCommand(
const ACommand:
String;
var AOutput, AErrors:
String;
var AExitCode: Cardinal): Boolean;
var
StartupInfo: TStartupInfo;
ProcessInfo: TProcessInformation;
SecurityAttr: TSecurityAttributes;
PipeOutputRead, PipeOutputWrite,
PipeErrorsRead, PipeErrorsWrite: THandle;
// Pipe in einen String auslesen
procedure ReadPipeToString(
const hPipe: THandle;
var Result:
String);
var
AvailableBytes,
ReadBytes: Cardinal;
Buffer:
String;
begin
PeekNamedPipe(hPipe,
NIL, 0,
NIL, @AvailableBytes,
NIL);
// wieviel ist da
while (AvailableBytes > 0)
do begin // überhaupt was da?
SetLength(Buffer,AvailableBytes);
// Buffer
if ReadFile(hPipe,PChar(Buffer)^,AvailableBytes,ReadBytes,
NIL)
then // Lesen hat geklappt
if (ReadBytes > 0)
then begin // Daten angekommen?
SetLength(Buffer,ReadBytes);
// falls weniger kam, als da ist (warum auch immer)
Result := Result +Buffer;
// an den Ergebnis-String
end;
PeekNamedPipe(hPipe,
NIL, 0,
NIL, @AvailableBytes,
NIL);
// noch was da?
end;
end;
begin
AOutput := '
';
AErrors := '
';
// Win-API-Strukturen initialisieren/füllen
FillChar(ProcessInfo,SizeOf(TProcessInformation),0);
FillChar(SecurityAttr,SizeOf(TSecurityAttributes),0);
SecurityAttr.nLength := SizeOf(SecurityAttr);
SecurityAttr.bInheritHandle := TRUE;
SecurityAttr.lpSecurityDescriptor :=
NIL;
CreatePipe(PipeOutputRead,PipeOutputWrite,@SecurityAttr,0);
CreatePipe(PipeErrorsRead,PipeErrorsWrite,@SecurityAttr,0);
FillChar(StartupInfo,SizeOf(TStartupInfo),0);
StartupInfo.cb := SizeOf(StartupInfo);
StartupInfo.hStdInput := 0;
StartupInfo.hStdOutput := PipeOutputWrite;
StartupInfo.hStdError := PipeErrorsWrite;
StartupInfo.wShowWindow := SW_HIDE;
StartupInfo.dwFlags := STARTF_USESHOWWINDOW
or STARTF_USESTDHANDLES;
// http://msdn2.microsoft.com/en-us/library/ms682425.aspx
Result := CreateProcess(
NIL,PChar(ACommand),
NIL,
NIL,TRUE, <--Hier
CREATE_DEFAULT_ERROR_MODE
or CREATE_NEW_CONSOLE
or NORMAL_PRIORITY_CLASS,
NIL,
NIL,StartupInfo,ProcessInfo);
if Result
then begin // Prozess erfolgreich gestartet?
repeat
GetExitCodeProcess(ProcessInfo.hProcess,AExitCode);
// http://msdn2.microsoft.com/en-us/library/ms683189.aspx
ReadPipeToString(PipeOutputRead,AOutput);
// Ausgaben lesen
ReadPipeToString(PipeErrorsRead,AErrors);
// Fehler lesen
if (AExitCode = STILL_ACTIVE)
then
Sleep(1);
until (AExitCode <> STILL_ACTIVE);
// bis der Prozess sich selbst beendet hat
CloseHandle(ProcessInfo.hThread);
// Handles freigeben
CloseHandle(ProcessInfo.hProcess);
end;
CloseHandle(PipeOutputWrite);
// Pipes schließen
CloseHandle(PipeErrorsWrite);
CloseHandle(PipeOutputRead);
CloseHandle(PipeErrorsRead);
end;