Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.625 Beiträge
Delphi 12 Athens
|
AW: Doskonsole nutzen und Rückgabewerte einlesen
10. Nov 2011, 08:16
Japp, so geht' s. Ich habe die Funktion mal schnell umgeschrieben(TStringlist -> TStrings, UniqueString, etc.), Fehler vorbehalten.
Delphi-Quellcode:
function GetConsoleOutput(Command: string; Output, Errors: TStrings): Boolean;
var
StartupInfo: TStartupInfo;
ProcessInfo: TProcessInformation;
SecurityAttr: TSecurityAttributes;
PipeOutputRead: THandle;
PipeOutputWrite: THandle;
PipeErrorsRead: THandle;
PipeErrorsWrite: THandle;
Succeed: Boolean;
Buffer: array [0 .. 255] of Char;
NumberOfBytesRead: DWORD;
Stream: TMemoryStream;
begin
// Initialisierung ProcessInfo
FillChar(ProcessInfo, SizeOf(TProcessInformation), 0);
// Initialisierung SecurityAttr
FillChar(SecurityAttr, SizeOf(TSecurityAttributes), 0);
SecurityAttr.nLength := SizeOf(SecurityAttr);
SecurityAttr.bInheritHandle := true;
SecurityAttr.lpSecurityDescriptor := nil;
// Pipes erzeugen
CreatePipe(PipeOutputRead, PipeOutputWrite, @SecurityAttr, 0);
CreatePipe(PipeErrorsRead, PipeErrorsWrite, @SecurityAttr, 0);
// Initialisierung StartupInfo
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;
UniqueString(Command);
if CreateProcess(nil, PChar(Command), nil, nil, true,
CREATE_DEFAULT_ERROR_MODE or CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS,
nil, nil, StartupInfo, ProcessInfo) then
begin
result := true;
// Write-Pipes schließen
CloseHandle(PipeOutputWrite);
CloseHandle(PipeErrorsWrite);
if Assigned(Output) then
begin
// Ausgabe Read-Pipe auslesen
Stream := TMemoryStream.Create;
try
while true do
begin
Succeed := ReadFile(PipeOutputRead, Buffer, 255,
NumberOfBytesRead, nil);
if not Succeed then
break;
Stream.Write(Buffer, NumberOfBytesRead);
end;
Stream.Position := 0;
Output.LoadFromStream(Stream);
finally
Stream.Free;
end;
end;
CloseHandle(PipeOutputRead);
if Assigned(Errors) then
begin
// Fehler Read-Pipe auslesen
Stream := TMemoryStream.Create;
try
while true do
begin
Succeed := ReadFile(PipeErrorsRead, Buffer, 255,
NumberOfBytesRead, nil);
if not Succeed then
break;
Stream.Write(Buffer, NumberOfBytesRead);
end;
Stream.Position := 0;
Errors.LoadFromStream(Stream);
finally
Stream.Free;
end;
end;
CloseHandle(PipeErrorsRead);
WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
CloseHandle(ProcessInfo.hProcess);
end
else
begin
result := false;
CloseHandle(PipeOutputRead);
CloseHandle(PipeOutputWrite);
CloseHandle(PipeErrorsRead);
CloseHandle(PipeErrorsWrite);
end;
end;
Damit kann der Aufruf vereinfacht werden:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
GetConsoleOutput('cmd /c dir c:\', Memo1.Lines, nil);
end;
Detlef "Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
|