Ausgabe der Konsole in meinem Programm anzeigen
Es ist möglich, aus Delphi heraus einen Kommandozeilenbefehl auszuführen und die Ausgabe, die normalerweise in DOS- bzw. Eingabezeilenfenster erscheint, abzufangen und in einer Stringliste zu speichern.Zentraler Befehl dieses Codes ist CreateProcess. Dieser Win32-API-Befehl erlaubt es, eine Anwendung so detailliert zu starten, dass auch die Ausgabe konfiguriert werden kann (über die Parameter-Struktur StartupInfo). Sie wird hier in eine Pipe (eine Art Datenröhre) umgeleitet, auf die im Beispiel über PipeOutputWrite zugegriffen wird. PipeOutputRead dient anschließend dazu, die dort aufgelaufenen Daten auszulesen und in einen Stream zu schreiben.
function GetConsoleOutput(Command : string; Output, Errors : TStringList) : Boolean; var Buffer : array[0..255] of Char; CreationFlags : DWORD; NumberOfBytesRead : DWORD; PipeErrorsRead : THandle; PipeErrorsWrite : THandle; PipeOutputRead : THandle; PipeOutputWrite : THandle; ProcessInfo : TProcessInformation; SecurityAttr : TSecurityAttributes; StartupInfo : TStartupInfo; Stream : TMemoryStream; begin //Initialisierung ProcessInfo FillChar(ProcessInfo, SizeOf(TProcessInformation), 0); //Initialisierung SecurityAttr FillChar(SecurityAttr, SizeOf(TSecurityAttributes), 0); SecurityAttr.nLength := SizeOf(TSecurityAttributes); 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(TStartupInfo); StartupInfo.hStdInput := 0; StartupInfo.hStdOutput := PipeOutputWrite; StartupInfo.hStdError := PipeErrorsWrite; StartupInfo.wShowWindow := SW_HIDE; StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES; CreationFlags := CREATE_DEFAULT_ERROR_MODE or CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS; // Folgende Zeile ist nur für Delphi ab 2009 erforderlich: UniqueString(Command); if CreateProcess(nil, PChar(Command), nil, nil, True, CreationFlags, nil, nil, StartupInfo, ProcessInfo) then begin Result := True; //Write-Pipes schließen CloseHandle(PipeOutputWrite); CloseHandle(PipeErrorsWrite); //Ausgabe Read-Pipe auslesen Stream := TMemoryStream.Create; try while ReadFile(PipeOutputRead, Buffer, 255, NumberOfBytesRead, nil) do begin Stream.Write(Buffer, NumberOfBytesRead); end; Stream.Position := 0; Output.LoadFromStream(Stream); finally Stream.Free; end; CloseHandle(PipeOutputRead); //Fehler Read-Pipe auslesen Stream := TMemoryStream.Create; try while ReadFile(PipeErrorsRead, Buffer, 255, NumberOfBytesRead, nil) do begin Stream.Write(Buffer, NumberOfBytesRead); end; Stream.Position := 0; Errors.LoadFromStream(Stream); finally Stream.Free; 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;
Aufrufbeispiel:
Für die Ausgabe und die Fehler wird zunächst eine Stringliste erzeugt. Anschließend wird obige Funktion aufgerufen. Wurde sie erfolgreich ausgeführt (Rückgabewert ist True), wird die Output-Stringliste in einem Memo angezeigt.Um Kommandozeilenbefehle ausführen zu können, die keine eigenständigen Anwendungen sind (wie der DOS-Befehl „dir“ im folgenden Beispiel), muss der Name des Kommandozeileninterpreters davor stehen. „cmd.exe“ ist das unter Windows NT/2000/XP und „command.com“ unter Windows 9x. Der Parameter /c sorgt dafür, dass der Kommandozeilenbefehl ausgeführt und die Kommandozeile anschließend wieder geschlossen wird.
procedure TForm1.Button1Click(Sender: TObject); var Output : TStringList; Errors : TStringList; begin Output := TStringList.Create; Errors := TStringList.Create; try if GetConsoleOutput('cmd /c dir c:', Output, Errors) then Memo1.Lines.AddStrings(Output); finally Output.free; Errors.free; end; end;
Ein Gedanke zu „Ausgabe der Konsole in meinem Programm anzeigen“
Kommentare sind geschlossen.
Vielen Dank für das Beispiel! Das war genau das, was ich gesucht habe. Funktionierte auf Anhieb.