![]() |
Textdatei zur Anzeige bringen
Hallo,
ich muss von meinem Programm aus ein anderes Programm im Hintergrund starten, dass selber eine LOG-Datei schreibt. Zum einen, wie kann ich mit Delphi3 ein Programm im Hintergrund starten (WinExec soll ja out sein) ohne das es sichtbar wird? Wie kann ich die Logdatei ständig in einem TMemo anzeigen wenn die Datei schon mal 1,5MB groß werden kann? TScrollBox? Unter Unix kann ich mir mit tail immer aktuell die neuen Zeilen welche in die LOG-Datei geschrieben werden anzeigen lassen. Kann ich unter Delphi3 gleiches machen bzw eben ein Memofeld mit Scroll-Leisten aktuell versorgen? Wäre für Eure Tipps sehr dankbar, irgendwie finde ich nicht das richtige in der Hilfe... Gruss, Daniel |
Re: Textdatei zur Anzeige bringen
Mit
![]()
Code:
Damit müsstest du das Fenster im Hintergrund starten können!
SW_HIDE
|
Re: Textdatei zur Anzeige bringen
Zitat:
Als zweiten PChar("open") Als dritten PChar(<Programmpfad) Als vierten nil, außer wenn du Parameter brauchst Als fünften PChar(ExtractFilePath(Application.ExeName)) Und als letzten SW_HIDE Bedenke aber dass der Benutzer das zweite Programm nicht sieht, und folgedessen auch nicht so einfach beenden kannst, deshalb bist du für das Beenden des zweiten Programms zuständig. |
Re: Textdatei zur Anzeige bringen
Hi,
erst mal vielen Dank für Eure Tips. Wie aber kann ich das Logfile in meinem Programm über z.Bsp. TMemo so anzeigen, dass auch die weiteren Zeilen die in das LOG-File geschrieben werden aktuell angezeigt werden? Ich kann es nur so erklären was ich will: Unter UNIX kann man mit Type wie unter DOS etc eine Textdatei anzeigen lassen. Mit dem Parameter -t oder -tail wird die Datei angezeigt und sobald ein neuer Eintrag hinzukommt, wird auch der gleich angezeigt. Kann man das auch ohne ständig die Datei schliesen und wieder öffnen zu müßen anzeigen? Gruss, Daniel PS: Beschreibe das evtl etwas umständlich, sind meine ersten Schritte in Delphi 3 |
Re: Textdatei zur Anzeige bringen
Vielleicht mit
![]() |
Re: Textdatei zur Anzeige bringen
Wichtig ist, dass du andere Operationen auf die Datei zulässt. Dies geschieht nach AssignFile mit
Delphi-Quellcode:
Anschließend musst du die Dateigröße speichern, und in einem Timer überprüfen, ob sich diese geändert hat. Ist dies der Fall, musst du nur noch die letzten Zeilen ausgeben. Ob Seek auch bei Textdateien funktioniert weiß ich allerdings nicht.
FileMode := fmShareDenyNone;
|
Re: Textdatei zur Anzeige bringen
Die große Frage ist:
Ist das Programm das die LOG-Datei erzeugt von dir bzw. kanns Du an diesem etwas ändern? |
Re: Textdatei zur Anzeige bringen
Hallo,
leider wir die LOG-Datei von einem Programm geschrieben, auf das ich keinen Einfluß habe, kann daher leider nichts ändern. Noch eine andere Frage: Wenn ich das Programm im Hintergrund gestartet habe, muß ich dieses ja dann auch beenden wenn ich mein Programm schließe. Wie bekomme ich mit, dass das von mir gestartete Programm beendet ist? Gruss, Daniel |
Re: Textdatei zur Anzeige bringen
OnClose der Form, oder? :zwinker:
|
Re: Textdatei zur Anzeige bringen
Zitat:
Lies dir das hier durch, da könntest du was finden: ![]() |
Re: Textdatei zur Anzeige bringen
Oh, hab ich wohl falsch verstanden! :wall:
|
Re: Textdatei zur Anzeige bringen
Hi,
mir ist gerade eingefallen, dass dieses zu startende Programm die Ausgabe ursprünglich auf dem Bildschirm ausgiebt, das LOG-File wird durch eine Umleitung (Pipe?) in die LOG-Datei geschrieben (also durch "programm.exe ergebnis.log") Könnte man das Programm auch im Hintergrund starten und die Bildschirmausgabe in das Memo hineinschreiben? Das LOG-File kann man ja einfach mitschreiben, so als wenn es eben durch die Pipe erstellt würde. Wäre das ein gangbarer Weg und hättet Ihr dazu eine Lösung? Gruss, Daniel |
Re: Textdatei zur Anzeige bringen
Guten Morgen,
nachdem ich gestern (oder eher heute so recht früh) noch nach weiteren Möglichkeiten zu meinem Problem gesucht habe, ist mir ein interessanter Artikel ins Auge gesprungen, der die Lösung sein könnte. Hier wird quasi ein cmd-prozess gestartet (im Beispiel einfaches Dir) und dann über eine Stringlist in ein Memo-Feld übergeben. Funktioniert erst mal gut bei kleiner Datenmenge, doch bei größerer Menge bleibt das Programm eben so lange stehen, bis die Ausgabe des CMD-Prozesses beendet ist. Habe dann auf Grundlage dieses Codes versucht, das Memo-Feld direkt bzw sofort zu füllen, was mir aber nicht gelungen ist. Da ich aber eben noch Anfänger bin, habe ich da auch nicht den driekten Durchblick und wollte Euch fragen, sich das mal anzusehen. Der Link dazu (hoffe ist so erlaubt): ![]() Gruss, Daniel (der schlaflose :wink: ) |
Re: Textdatei zur Anzeige bringen
Hier ist es für die Ausgabepipe, für die Fehlerpipe machst du das gleiche:
Delphi-Quellcode:
Der Code liest alle Daten heraus, und sobald die Eingabe abgebrochen wird, wir alles der Stringlist hinzugefügt. Wir ändern die Reihenfolge ein wenig: die beiden Zeilen, die mit einem Kommentar versehen sind, werden in die Schleife geschoben, das heißt der Code müsste so aussehen:
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; //Diese Zeile Output.LoadFromStream(Stream); //und diese Zeile finally Stream.Free; end; CloseHandle(PipeOutputRead);
Delphi-Quellcode:
Dadurch werden die Daten vom Stream immer in die StringList geladen, und nicht erst sobald das cmd-Programm fertig ist. Der Algo ist sicher noch optimierungsfähig (nicht immer alles laden sondern nur zusätzliche Daten), aber es ist ein Ansatz.
Stream := TMemoryStream.Create;
try while true do begin succeed := ReadFile(PipeOutputRead, Buffer, 255, NumberOfBytesRead, nil); if not succeed then break; Stream.Write(Buffer, NumberOfBytesRead); Stream.Position := 0; //Diese Zeile Output.LoadFromStream(Stream); //und diese Zeile end; finally Stream.Free; end; CloseHandle(PipeOutputRead); |
Re: Textdatei zur Anzeige bringen
Hi,
super, musste dann noch das einlesen in die Memobox mit aufnehmen und es hat tatsächlich funktioniert. Mein Fehler zuvor war, dass ich das einfügen in die MemoBox nicht in der Schleife gemacht habe, Dank Dir sind meine Augen jetzt etwas offener :-D Eine Frage stellt sich jetzt: Die MemoBox wird jetzt gefüllt und ich kann über die Scrollbar den Inhalt ansehen. Wie könnte ich eine Art Autoscroll einstellen damit der Inhalt stets nach oben geschoben wird und die unterste Zeile die aktuelle ist? Ausserdem, wo könnte ich zum optimieren ansetzen, denn bei größer werdender Datenmenge schläft das Programm natürlich jetzt ein, wird ja derzeit immer alles wieder und wieder in TMemo geschrieben. Gruss, Daniel |
Re: Textdatei zur Anzeige bringen
Bei allen von TCustomEdit abgeleiteten Klassen gibts die Eigenschaften SelStart und SelLength. SelStart gibt den Start des markierten Textes an, und wenn kein Text markiert ist, ist SelStart die Cursorposition, wobei 0 das erste Zeichen darstellt. Also z.B.:
Delphi-Quellcode:
Memo1.SelStart := Length(Memo1.Text)-1;
Memo1.SelLength := 0; |
Re: Textdatei zur Anzeige bringen
Hallo,
habe mir mal TMemoryStream angeschaut und gesehen, dass es dort ein Size und ein Position gibt. Nun habe ich mir ein label auf mein Form gelegt und gebe beim abarbeiten die Größe des Streams aus. Da die Größe ja mit den Daten anwächst, dachte ich mir, man könnte ja die Position nach jedem Leseschritt merken und beim nächsten Durchgang wieder setzen, damit nicht der ganze Stream gelesen wird. Dadurch wird die Anwendung erwartungsgemäß sehr viel schneller (da ja schon gelesene Daten quasi übersprungen werden), doch das ist nicht ganz das erwartete. Ich vermute mal, dass wenn der Steam bis zum Ende des jeweiligen Schleifendurchgang gelesen wird und dies aber noch nicht das Zeilenende war, schreibe ich mit intems.addstrings den bis dahin gelesenen String in die Liste, die dann beim nächsten einfügen eben eine neue Zeile beginnt. Dies ist aber so nicht gewollt, denn das Ergebnis sieht eben nicht so gut aus weil die Zeile unterbrochen ist. Habt Ihr dazu evtl eine Idee? Leider geht ja Readln nicht, denn der würde ja dann lesen bis #10#13 oder so. Gruss, Daniel |
Re: Textdatei zur Anzeige bringen
probier mal anstatt dem hier:
Delphi-Quellcode:
das hier zu verwenden:
Stream := TMemoryStream.Create;
try while true do begin succeed := ReadFile(PipeOutputRead, Buffer, 255, NumberOfBytesRead, nil); if not succeed then break; Stream.Write(Buffer, NumberOfBytesRead); Stream.Position := 0; Output.LoadFromStream(Stream); end; finally Stream.Free; end; CloseHandle(PipeOutputRead);
Delphi-Quellcode:
So fügst du immer den gerade herausgelesenen Text der Stringlist hinzu...
Output.Clear;
Output.Strings.Add(''); try while true do begin succeed := ReadFile(PipeOutputRead, Buffer, 255, NumberOfBytesRead, nil); if not succeed then break; Output[0] := Output[0]+Buffer; end; finally Stream.Free; end; CloseHandle(PipeOutputRead); |
Re: Textdatei zur Anzeige bringen
Hi,
habe jetzt alles so gemacht, nur leider bekomme ich jetzte eine Exception der Klasse EAccessViolation, ausserdem ist die Ausgabe scheinbar nicht mehr Zeilenweise sondern die Angaben erscheinen hintereinander. Ich habe mal den Code eingefügt, MmAusgabe ist ein TMemo, die Variable Abbruch wird durch ein Button gesetzt. Sobald ich den Ablauf abbreche und die Variable Abbruch auf true setze und darauf dann die Procedure mit exit verlassen will, erscheint die obige Exception. Scheinbar ist das schon der richtige Weg, es klappt nur nicht mit der Ausgabe (also dem TMemo), welche ja von der Console kommt. Der Einfachheitshalber (auch wegen der Datenmenge) habe ich ein das Dir mit /s versehen. Könntet Ihr das mal versuchen und mir helfen? Gruss, Daniel
Delphi-Quellcode:
procedure THauptForm.GetConsoleOutput(const Command: String);
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 //Write-Pipes schließen CloseHandle(PipeOutputWrite); CloseHandle(PipeErrorsWrite); //Ausgabe Read-Pipe auslesen Abbruch:=false; MmAusgabe.Clear; MmAusgabe.Lines.Add(''); try while true do begin succeed := ReadFile(PipeOutputRead, Buffer, 255, NumberOfBytesRead, nil); if not succeed then break; MmAusgabe.Lines[0]:=MmAusgabe.Lines[0] + Buffer; Application.ProcessMessages; if Abbruch then exit; end; finally Stream.Free; end; CloseHandle(PipeOutputRead); //Fehler Read-Pipe auslesen try while true do begin succeed := ReadFile(PipeErrorsRead, Buffer, 255, NumberOfBytesRead, nil); if not succeed then break; MmAusgabe.Lines[0]:=MmAusgabe.Lines[0] + Buffer; Application.ProcessMessages; if Abbruch then exit; end; finally Stream.Free; end; CloseHandle(PipeErrorsRead); WaitForSingleObject(ProcessInfo.hProcess, INFINITE); CloseHandle(ProcessInfo.hProcess); end else begin CloseHandle(PipeOutputRead); CloseHandle(PipeOutputWrite); CloseHandle(PipeErrorsRead); CloseHandle(PipeErrorsWrite); end; end; procedure THauptForm.BtTestClick(Sender: TObject); begin GetConsoleOutput('cmd /c dir c:\winnt /s'); end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:45 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