![]() |
[DOS] Ausgabe abfangen
Hallo,
ich rufe folgendermaßen meine Anwendung auf: Zitat:
der ParamStr() bringt mir hier leider nichts. Ich habe schon nach Pipes gesucht, allerdings glaub ich nicht das die Lösugnsansetze das gleiche verfolgen wie ich... Kann mir jemand helfen? |
Re: [DOS] Ausgabe abfangen
Es gibt hier im Forum mehrere Themen dies bezüglich, such eventuell mal nach Konsole abfangen oder ähnliches. Wenn ich heute Abend zu Hause bin kann ich dir eine Klasse mit Beispiel schicken, aber hier hab nichts zur Hand.
|
Re: [DOS] Ausgabe abfangen
wie hier beschreiben
![]() brignt mich nicht sonderlich weiter, da hier eine extra Console erzeugt wird in der die abgeschickten Befehle abgefangen werden... auch dieses beispiel brignt mich nciht weiter, da hier erst im eigendlich programm der dos befehl ausgeführt wird: ![]() |
Re: [DOS] Ausgabe abfangen
Was soll denn das werden ? :shock: Und das hier : | ? Brauchst du den Inhalt der Boot.INI im Programm ? Das wäre dann aber so was :
Code:
IMHO ist das egal wie alles Unfug. Lese die Datei aus und fertig. Zeilenweise mit readln oder lade sie in eine Stringliste.
type boot.ini > Text.exe
|
Re: [DOS] Ausgabe abfangen
Zitat:
|
Re: [DOS] Ausgabe abfangen
so funktioniert es in C++, aber wie in Delphi?
Zitat:
Zitat:
|
Re: [DOS] Ausgabe abfangen
Zitat:
|
Re: [DOS] Ausgabe abfangen
Vielleicht ist
![]() |
Re: [DOS] Ausgabe abfangen
Machts nicht zu kompliziert. Effektiv ist es doch ganz einfach. Die Pipe leitet die Standardausgabe des einen Programms zur Standardeingabe des anderen weiter. Man muss also nur die Standardeingabe auslesen. Und das funktioniert nach wie vor mit Read() und ReadLn(). Nebnbei schreibt man auf die Standradausgabe mit Write() und WriteLn(). Die Pipe an sich muss also gar nicht beachtet werden...
mfg Christian |
Re: [DOS] Ausgabe abfangen
ah das hat geholfen, allerdigns bekomme ich imemr nur die erste zeile der boot.ini :(
wie setze ich den Lesezeiger weiter?
Delphi-Quellcode:
var
sOutput: string; begin { TODO -oUser -cConsole Main : Hier Code einfügen } repeat read(sOutPut); Write(sOutPut); until sOutPut <> ''; end. |
Re: [DOS] Ausgabe abfangen
Ich hab sowas auch noch nie gemacht, aber müsste da nicht ein EOF am Dateiende kommen?
|
Re: [DOS] Ausgabe abfangen
Ich habe mal im Internet diese Funktion gefunden :
Delphi-Quellcode:
Damit kann ich den Output eines Konsolenfensters auslesen.
function GetConsoleOutput(const Command: String; var Output, Errors: TStringList): 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; 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); //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; CloseHandle(PipeOutputRead); //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; CloseHandle(PipeErrorsRead); WaitForSingleObject(ProcessInfo.hProcess, INFINITE); CloseHandle(ProcessInfo.hProcess); end else begin result:=false; CloseHandle(PipeOutputRead); CloseHandle(PipeOutputWrite); CloseHandle(PipeErrorsRead); CloseHandle(PipeErrorsWrite); end; end; |
Re: [DOS] Ausgabe abfangen
Zitat:
ReadLn liest die Zeile und setzt den Zeiger auf die nächste Zeile, während Read nur die Zeile einliest. |
Re: [DOS] Ausgabe abfangen
Hi
Delphi-Quellcode:
Grüße vom marabu
var
line: string; begin AssignFile(input, ''); //stdin AssignFile(output, ''); //stdout Reset(input); Rewrite(output); while not Eof do begin ReadLn(line); WriteLn(line); end; CloseFile(output); CloseFile(input); end. |
Re: [DOS] Ausgabe abfangen
Zitat:
|
Re: [DOS] Ausgabe abfangen
So simpel? Wer hätte das gedacht :lol:
|
Re: [DOS] Ausgabe abfangen
Zitat:
vielen Dank an alle die mir geholfen haben! :) [closed] |
Re: [DOS] Ausgabe abfangen
Der Code aus den Beiträgen sollte natürlich angepasst werden. Wenn Du readln verwendest, sollte auch writeln verwendet werden. Un selbstverständlich hört man nicht auf wenn man irgendwas nichtleeres gelesen hat! (Also kein Wunder, daß Du nur die erste Zeile liest). Also ingesamt etwa so:
Delphi-Quellcode:
Gruß Gammatester
var
sOutput: string; begin while not eof(input) do begin readln(sOutPut); Writeln(sOutPut); end; end. |
Re: [DOS] Ausgabe abfangen
mir ist aber noch etwas aufgefallen:
wenn ich nun meine exe normal aufrufe ohne Type C:\boot.ini | dann bleibt er bei EOF hängen :( |
Re: [DOS] Ausgabe abfangen
Wiseo geht das hier nicht ?
Delphi-Quellcode:
Oder muss es komplizierter sein ? :shock:
var s : TStringList;
begin s.LoadFromFile ('C:\boot.ini'); |
Re: [DOS] Ausgabe abfangen
Dein Programm erwartet Daten auf STDIN. Wenn diese Daten nicht über eine Pipe angeliefert werden, dann kannst du sie per input redirection "prog < filename" bereit stellen. Oder per command line parameter:
Delphi-Quellcode:
Das Ende der Eingabe kannst du über die Tastatur mit Strg+Z signalisieren, wenn du keine Eingabe-Umleitung verwendet hast.
begin
AssignFile(input, ParamStr(1)); // ... end; |
Re: [DOS] Ausgabe abfangen
Zitat:
entweder hab ich den Aufruf meiner exe mit einem PIPE davor oder nicht... wenn meine Exe normal aufgerufen wird... soll sie den quellcode (siehe oben) nicht ausführen.. ah das ist aber schlecht, kann man nicht abfragen ob "aufruf mit pipe oder ohne" ? also
Delphi-Quellcode:
WENN PIPE DANN
AssignFile(input, ''); //stdin AssignFile(output, ''); //stdout Reset(input); Rewrite(output); while not Eof do begin ReadLn(line); WriteLn(line); end; CloseFile(output); CloseFile(input); END |
Re: [DOS] Ausgabe abfangen
Zitat:
Gammatester |
Re: [DOS] Ausgabe abfangen
Zitat:
|
Re: [DOS] Ausgabe abfangen
Zitat:
Zitat:
|
Re: [DOS] Ausgabe abfangen
aber das Programm soll ohne die Manuelle Eingabe des Benutzern laufen...
wenn ich dich jetzt richtig verstehe.. das heißt ich muss das Quellcodetechnisch abfangen... nur wie... |
Re: [DOS] Ausgabe abfangen
Zitat:
Du wolltest doch wissen, wie man ein EOF eingibt, wenn man das Programm interaktiv ohne Redirection startet! (Genauer Du hast behauptet "er hängt wenn ..."). Und nur darauf habe ich geantwortet. Wenn Du die ganze Zeit meinst, wie man feststellen kann, ob input umgeleitet ist oder eine Konsole ist: Es muß irgendwo eine API-Funktion geben, die in etwa sagt "handle is console" (jedenfalls gibt's das im DOS-API, und es würde mich wundern wenn's so eine Fkt. nicht für WIN32 gibt). Als Handle dann entweder TTextRec(input).Handle oder GetStdHandle(STD_INPUT_HANDLE) verwenden. (Ungetestet! Also ausprobieren, bzw. selbstfinden oder auf Hinweise von anderen DP-Usern warten). Gammatester Zusatz via Edit: Ein kurzer Test zeigt, daß
Delphi-Quellcode:
je nach Aufrufart unterschiedliche Werte liefert, hier für die Werte siehe Delphihilfe zu GetFileType
GetFileType(GetStdHandle(STD_INPUT_HANDLE))
|
Re: [DOS] Ausgabe abfangen
Zitat:
cool, danke^^ |
Re: [DOS] Ausgabe abfangen
Zitat:
|
Re: [DOS] Ausgabe abfangen
So was wie hier, das sind Threads, wo es schon fast zu blöd wird, zu antworten. :lol: @Fragesteller : warum ist LoadFromFile bei dir nicht möglich ? Nur, um Daten aus einer Textdatei im Programm auszuwerten ? :wall: Ja, echt sagenhaft. :mrgreen:
|
Re: [DOS] Ausgabe abfangen
Hallo zusammen,
naja man kann es schon steuern. 1) wenn Parameter übergeben werden, dann darf das Programm einlesen (von STDIN) ansonsten wird nur eine Fehlermeldung ausgegeben. 2) wenn Parameter übergeben werden, dann liest das Programm aus der übergebenen Datei ansonsten von STDIN. Wenn ich mich richtig erinnere liefert Paramamstr(1) bei solchen Konstrukten Meinprog.exe >papierkorb.txt dann '>papierkorb.txt' zurück. Das Umleiten muß also vom Programm selbst erledigt werden. Die andere Möglichkeit wäre es mit zwei Threads zu versuchen. Einer lauscht, und der andere dreht den Saft ab wenn nach x Sekunden keine Eingabe erfolgte. Die Fragestellung erinnert mich ein wenig an meine Tochter. Wenn etwas machbar war, mußte es auch gemacht werden. Das ist jetzt allerdings auch schon 18 Jahre her. Grüße K-H |
Re: [DOS] Ausgabe abfangen
Zitat:
Meinprog.exe > papierkorb.txt |
Re: [DOS] Ausgabe abfangen
Hallo,
unabhängig von den mir unbekannten Absichten des Thread Owners möchte ich noch folgendes zu bedenken geben: Jede Konsolenanwendung sollte so geschrieben werden, dass Power-User nicht behindert werden. Eigentlich ist die Unterstützung der Standard I/O-Kanäle eine Entwurfsentscheidung, die aus verschiedenen Verarbeitungsszenarien folgt, z.B. eine Eingabedatei soll verändert werden und das Resultat soll als neue Datei weggeschrieben werden - die von Unix her bekannten filter tools arbeiten genau so. In diesem Fall erwarte ich die Verwendung von STDIN und STDOUT einfach. Da hier eine INI-Datei verarbeitet werden soll und Delphi die entsprechenden Klassen zur bequemen Verarbeitung solcherart strukturierter Textdateien anbietet, gilt es beides unter einen Hut zu bringen.
Delphi-Quellcode:
So wird ein im Programm festgeschriebener Dateiname vermieden, die Datei kann über piping oder redirection verarbeitet werden und auf den Inhalt kann bequem zugegriffen werden. Alternativ kann die Eingabedatei auch als Parameter übergeben werden.
uses
Classes, IniFiles, Windows, SysUtils; var stream: TStream; strings: TStrings; ini: TMemIniFile; begin ini := TMemIniFile.Create(''); strings := TStringList.Create; if ParamCount = 0 then stream := THandleStream.Create(GetStdHandle(STD_INPUT_HANDLE)) else stream := TFileStream.Create(ParamStr(1), fmOpenRead); strings.LoadFromStream(stream); stream.Free; ini.SetStrings(strings); strings.Free; if ini.SectionExists(SECTION) then begin { ... roll your own dice ... } end; ini.Free; end; Bei einem einfachen StringList.LoadFromFile('C:\BOOT.INI') wird die Einbettung in die Ablaufumgebung nicht berücksichtigt. Freundliche Grüße |
Re: [DOS] Ausgabe abfangen
Zitat:
Gammatester |
Re: [DOS] Ausgabe abfangen
Moin,
ich hatte meinen Code in Beitrag #33 als unabhängig von Mogtars konkreten Anforderungen deklariert und mich nur auf das Problem der INI-Daten und deren Verarbeitung konzentriert, da das zeilenweise Verarbeiten ja schon früher im Thread gezeigt wurde, aber okay - hier die Verknüpfung der beiden Code-Teile, damit niemand stolpert:
Delphi-Quellcode:
Freundliche Grüße
program Demo;
{$APPTYPE CONSOLE} uses Classes, IniFiles, Windows, SysUtils; var stream: TStream; strings: TStrings; ini: TMemIniFile; h: THandle; ft: Cardinal; line: string; const SECTION = 'boot loader'; begin ini := TMemIniFile.Create(''); strings := TStringList.Create; h := GetStdHandle(STD_INPUT_HANDLE); ft := GetFileType(h); if ParamCount > 0 then stream := TFileStream.Create(ParamStr(1), fmOpenRead) else if ft <> FILE_TYPE_CHAR then stream := THandleStream.Create(h) else stream := nil; if Assigned(stream) then begin strings.LoadFromStream(stream); stream.Free; end else begin AssignFile(input, ''); Reset(input); while not Eof do begin ReadLn(line); strings.Add(line); end; CloseFile(input); end; ini.SetStrings(strings); strings.Free; if ini.SectionExists(SECTION) then WriteLn('roll your own dice ...') else WriteLn('unexpected data found'); ini.Free; end. |
Re: [DOS] Ausgabe abfangen
[OT] Nanu, Delphi-Tags kaputt ? Sie sind eigentlich gesetzt...[/OT]
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:01 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz