AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Textdatei zur Anzeige bringen

Ein Thema von DanielBodensee · begonnen am 1. Mai 2004 · letzter Beitrag vom 2. Mai 2004
Antwort Antwort
Seite 2 von 2     12   
Benutzerbild von S2B
S2B

Registriert seit: 1. Feb 2004
Ort: Aachen
1.268 Beiträge
 
#11

Re: Textdatei zur Anzeige bringen

  Alt 1. Mai 2004, 17:38
Oh, hab ich wohl falsch verstanden!
Simon Praetorius
Gruß
S2B
  Mit Zitat antworten Zitat
DanielBodensee

Registriert seit: 25. Apr 2004
10 Beiträge
 
#12

Re: Textdatei zur Anzeige bringen

  Alt 1. Mai 2004, 22:40
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
  Mit Zitat antworten Zitat
DanielBodensee

Registriert seit: 25. Apr 2004
10 Beiträge
 
#13

Re: Textdatei zur Anzeige bringen

  Alt 2. Mai 2004, 09:43
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): Code

Gruss,
Daniel (der schlaflose )
  Mit Zitat antworten Zitat
Benutzerbild von alcaeus
alcaeus

Registriert seit: 11. Aug 2003
Ort: München
6.537 Beiträge
 
#14

Re: Textdatei zur Anzeige bringen

  Alt 2. Mai 2004, 09:54
Hier ist es für die Ausgabepipe, für die Fehlerpipe machst du das gleiche:
Delphi-Quellcode:
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);
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:
Delphi-Quellcode:
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);
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.
Andreas B.
Die Mutter der Dummen ist immer schwanger.
Ein Portal für Informatik-Studenten: www.infler.de
  Mit Zitat antworten Zitat
DanielBodensee

Registriert seit: 25. Apr 2004
10 Beiträge
 
#15

Re: Textdatei zur Anzeige bringen

  Alt 2. Mai 2004, 10:27
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

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
  Mit Zitat antworten Zitat
Benutzerbild von alcaeus
alcaeus

Registriert seit: 11. Aug 2003
Ort: München
6.537 Beiträge
 
#16

Re: Textdatei zur Anzeige bringen

  Alt 2. Mai 2004, 10:31
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;
Andreas B.
Die Mutter der Dummen ist immer schwanger.
Ein Portal für Informatik-Studenten: www.infler.de
  Mit Zitat antworten Zitat
DanielBodensee

Registriert seit: 25. Apr 2004
10 Beiträge
 
#17

Re: Textdatei zur Anzeige bringen

  Alt 2. Mai 2004, 13:03
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
  Mit Zitat antworten Zitat
Benutzerbild von alcaeus
alcaeus

Registriert seit: 11. Aug 2003
Ort: München
6.537 Beiträge
 
#18

Re: Textdatei zur Anzeige bringen

  Alt 2. Mai 2004, 14:46
probier mal anstatt dem hier:
Delphi-Quellcode:
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);
das hier zu verwenden:
Delphi-Quellcode:
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);
So fügst du immer den gerade herausgelesenen Text der Stringlist hinzu...
Andreas B.
Die Mutter der Dummen ist immer schwanger.
Ein Portal für Informatik-Studenten: www.infler.de
  Mit Zitat antworten Zitat
DanielBodensee

Registriert seit: 25. Apr 2004
10 Beiträge
 
#19

Re: Textdatei zur Anzeige bringen

  Alt 2. Mai 2004, 21:47
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;
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:26 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz