AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Doskonsole nutzen und Rückgabewerte einlesen
Thema durchsuchen
Ansicht
Themen-Optionen

Doskonsole nutzen und Rückgabewerte einlesen

Ein Thema von fuchsle · begonnen am 9. Nov 2011 · letzter Beitrag vom 28. Jul 2021
Antwort Antwort
Seite 2 von 2     12   
daywalker9

Registriert seit: 1. Jan 2010
Ort: Leer
594 Beiträge
 
Delphi XE3 Professional
 
#11

AW: Doskonsole nutzen und Rückgabewerte einlesen

  Alt 10. Nov 2011, 09:22
Hast Du TStrings.Create aufgerufen vorher?

TStrings ist nur die Basisklasse, dann kannst Du auch sowas wie DeddyH bereits gepostet hat zB Memo1.Lines übergeben.

Erzeugen musst Du aber TStringList.
Lars
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.006 Beiträge
 
Delphi 12 Athens
 
#12

AW: Doskonsole nutzen und Rückgabewerte einlesen

  Alt 10. Nov 2011, 09:30
Dies
Delphi-Quellcode:
    for I := 0 to SLOut.Count - 1 do
    begin
      Memo1.Lines.Add(SLOut.Strings[I]);
    end;
kann man auch einfach so schreiben

Memo1.Lines := SLOut;
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.540 Beiträge
 
Delphi 11 Alexandria
 
#13

AW: Doskonsole nutzen und Rückgabewerte einlesen

  Alt 10. Nov 2011, 09:37
Ich habe meinen Code aus #9 genauso ausprobiert, wie er da steht (mit direkter Übergabe der Memo.Lines). Das hat nach Änderung auf TStrings-Parameter ohne Probleme funktioniert, damit kann man sich doch temporäre Listen sparen. Wieso das bei fuchsle nicht klappen soll, ist mir nicht ganz klar
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
  Mit Zitat antworten Zitat
fuchsle

Registriert seit: 22. Jul 2011
Ort: Heilbronn
35 Beiträge
 
Delphi XE3 Professional
 
#14

AW: Doskonsole nutzen und Rückgabewerte einlesen

  Alt 14. Nov 2011, 08:02
Dies
Delphi-Quellcode:
    for I := 0 to SLOut.Count - 1 do
    begin
      Memo1.Lines.Add(SLOut.Strings[I]);
    end;
kann man auch einfach so schreiben

Memo1.Lines := SLOut;
Danke. Sieht gleich besser aus.
  Mit Zitat antworten Zitat
fuchsle

Registriert seit: 22. Jul 2011
Ort: Heilbronn
35 Beiträge
 
Delphi XE3 Professional
 
#15

AW: Doskonsole nutzen und Rückgabewerte einlesen

  Alt 14. Nov 2011, 08:31
Ich habe meinen Code aus #9 genauso ausprobiert, wie er da steht (mit direkter Übergabe der Memo.Lines). Das hat nach Änderung auf TStrings-Parameter ohne Probleme funktioniert, damit kann man sich doch temporäre Listen sparen. Wieso das bei fuchsle nicht klappen soll, ist mir nicht ganz klar
Habe es nochmals probiert.
Geht einwandfrei.
Vielen Dank.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.134 Beiträge
 
Delphi 12 Athens
 
#16

AW: Doskonsole nutzen und Rückgabewerte einlesen

  Alt 14. Nov 2011, 08:44
Dies
Delphi-Quellcode:
    for I := 0 to SLOut.Count - 1 do
    begin
      Memo1.Lines.Add(SLOut.Strings[I]);
    end;
kann man auch einfach so schreiben

Memo1.Lines := SLOut;
Das ist aber keine korrekte Übersetzung.

Memo1.Lines.AddStrings(SLOut); wäre richtig.
Das andere stimmt nur überein, wenn das Memo vorher leer ist, bzw. wenn es vorher geleert wird,
denn AddString hängt die Strings an den vorhandenen Inhalt an, wärend die Zuweisung über .Text den Inhalt ersetzt.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
fuchsle

Registriert seit: 22. Jul 2011
Ort: Heilbronn
35 Beiträge
 
Delphi XE3 Professional
 
#17

AW: Doskonsole nutzen und Rückgabewerte einlesen

  Alt 14. Nov 2011, 10:00
Ich gehe davon aus, dass hiermit
Memo1.Lines := SLOut; der Inhalt von Memo1 mit den Daten von SLOut überschrieben wird und dadurch immer "geleert" wird.

In meinem speziellen Fall ist es gewünscht, dass immer nur der aktuelle Inhalt geladen wird.
Daher ist es mir nicht negativ aufgefallen.
  Mit Zitat antworten Zitat
Benutzerbild von MaBuSE
MaBuSE

Registriert seit: 23. Sep 2002
Ort: Frankfurt am Main (in der Nähe)
1.837 Beiträge
 
Delphi 10 Seattle Enterprise
 
#18

AW: Doskonsole nutzen und Rückgabewerte einlesen

  Alt 28. Jul 2021, 12:31
Hallo,
sorry wenn ich diesen alten Beitrag wieder rauskrame, aber mein Problem ist hier wohl am besten aufgehoben, da ich den hier veröffentlichen Quelltext verwende.

Mein Problem (Aufgabenstellung):
Ich möchte die Aufrufe von dcc32 protokollieren, um zu sehen, in welcher Reihenfolge und mit welchen Parametern dcc32 aufgerufen wird.

Umsetzung:
Ich habe einen kleinen Wrapper um dcc32 geschrieben.
Der loggt die Aufrufe und wenn eine dcc32_org.exe (Kopie der originalen dcc32.exe) vorhanden ist, wird diese auch aufgerufen und die Ausgabe geloggt.
(Dazu habe ich die GetConsoleOutput von hier verwendet.)

-> Das funktioniert auch meistens, aber manchmal auch nicht

Mein Problem (der Fehler):
Im Log steht für jeden Eintrag:
Code:
40705308-0001: rem cd /d C:\Temp\DevExpress\VCL\Library\RS27
40705308-0002: "C:\Program Files (x86)\Embarcadero\Studio\21.0\Bin\dcc32.exe" "C:\Temp\DevExpress\VCL\Library\RS27\dxCoreRS27.dpk" -B -U"C:\Temp\DevExpress\VCL\Library\RS27" -I"C:\Temp\DevExpress\VCL\Library\RS27" -R"C:\Program Files (x86)\Embarcadero\Studio\21.0\lib\win32\release;C:\Temp\DevExpress\VCL\Library\RS27" -NU"C:\Temp\DevExpress\VCL\Library\RS27" -LE"C:\Temp\DevExpress\VCL\Library\RS27" -LN"C:\Temp\DevExpress\VCL\Library\RS27"   -NS"WinApi;Vcl;System;System.Win;Vcl.Imaging;Data;Data.Win;Bde;Xml;Xml.Win;Vcl.Shell;VclTee;Datasnap;IBX" -DSHAREPACKAGES -NB"C:\Temp\DevExpress\VCL\Library\RS27" -NH"C:\Temp\DevExpress\VCL\Library\RS27" -JL -W-UNSUPPORTED_CONSTRUCT
40705308-0003:  rem Embarcadero Delphi for Win32 compiler version 34.0
40705308-0004:  rem Copyright (c) 1983,2021 Embarcadero Technologies, Inc.
40705308-0005:  rem Fatal: F1026 File not found: 'Files.dpr'
Alle Aufrufe geben den Fehler
Code:
Fatal: F1026 File not found: 'Files.dpr'
aus, aber die Packages werden erzeugt.

Der Aufruf ohne Wrapper funktioniert und auch der Aufruf von dcc32_org.exe funktioniert ohne Fehler.
Code:
 C:\Temp\DevExpress\VCL\Library\RS27>"C:\Program Files (x86)\Embarcadero\Studio\21.0\Bin\dcc32_org.exe" "C:\Temp\DevExpress\VCL\Library\RS27\dxCoreRS27.dpk" -B -U"C:\Temp\DevExpress\VCL\Library\RS27" -I"C:\Temp\DevExpress\VCL\Library\RS27" -R"C:\Program Files (x86)\Embarcadero\Studio\21.0\lib\win32\release;C:\Temp\DevExpress\VCL\Library\RS27" -NU"C:\Temp\DevExpress\VCL\Library\RS27" -LE"C:\Temp\DevExpress\VCL\Library\RS27" -LN"C:\Temp\DevExpress\VCL\Library\RS27"   -NS"WinApi;Vcl;System;System.Win;Vcl.Imaging;Data;Data.Win;Bde;Xml;Xml.Win;Vcl.Shell;VclTee;Datasnap;IBX" -DSHAREPACKAGES -NB"C:\Temp\DevExpress\VCL\Library\RS27" -NH"C:\Temp\DevExpress\VCL\Library\RS27" -JL -W-UNSUPPORTED_CONSTRUCT
Embarcadero Delphi for Win32 compiler version 34.0
Copyright (c) 1983,2021 Embarcadero Technologies, Inc.
dxCoreRS27.dpk(67)
68 lines, 0.48 seconds, 1273428 bytes code, 209496 bytes data.

Frage:
Hat jemand eine Ahnung woran das liegen könnte?

Danke im Voraus.


Der Quelltext (auf das wesentliche reduziert):
Delphi-Quellcode:
program DCC32_Dummy;

{$APPTYPE CONSOLE}

// Ersatz für DCC32.exe in Delphi Installation um BuildSkripts zu analysieren
// z.B. DevExpress
// Diese Version ruft (falls vorhanden) *_org.exe mit den übergebenen Parametern auf.

uses
  SysUtils, Windows, Classes;

const
  Filename = 'C:\TEMP\DCC32.LOG';
var
  Programmstart: Integer;
  Zeile: integer = 0;

function GetConsoleOutput(const 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;
  sCmd : string;
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;
  sCmd:=Command;
  UniqueString(sCmd);
  if CreateProcess(nil,
                   (PChar(sCmd)),
                   nil,
                   nil,
                   True,
                   CreationFlags,
                   nil,
                   PChar(GetCurrentDir),
                   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;

{ TMyLog }

type
  TMyLog = class(TObject)
  private
    Log: TextFile;
  public
    constructor Create;
    destructor Destroy; override;
    procedure Add(const s: string);
  end;

constructor TMyLog.Create;
begin
  inherited;
  ForceDirectories(ExtractFilePath(Filename));
  AssignFile(Log, Filename);
  if FileExists(Filename) then
  begin
    Append(Log);
  end
  else
  begin
    ReWrite(Log);
  end;
end;

destructor TMyLog.Destroy;
begin
  CloseFile(Log);
  inherited;
end;

procedure TMyLog.Add(const s: string);
begin
  Inc(Zeile);
  WriteLn(Log, Format('%.8d-%.4d: %s', [ProgrammStart, Zeile, s]));
  Flush(Log);
end;

var
  i, j: Integer;
  App, Params: string;
  sl1, sl2: TStringList;
  MyLog: TMyLog;
begin
  Programmstart := DateTimeToTimeStamp(now).Time;
  try
    MyLog := TMyLog.Create;
    try
      MyLog.Add('rem cd /d '+GetCurrentDir);
      MyLog.Add(CmdLine);
    finally
      MyLog.Free;
    end;

    // Wenn *_org.exe da ist, dann diese mit Parametern starten
    App := ChangeFileExt(ParamStr(0), '_org.exe');
// WriteLn(App);
    if FileExists(App) then
    begin
      for i := 1 to ParamCount do Params := Params + #32 + ParamStr(i);
// WriteLn(Params);
      sl1 := TStringList.Create;
      sl2 := TStringList.Create;
      try
        GetconsoleOutPut(App + ' ' + Params, sl1, sl2);
        MyLog := TMyLog.Create;
        try
          for j := 0 to sl1.Count-1 do
          begin
            MyLog.Add(' rem ' + sl1[j]);
            WriteLn(sl1[j]);
          end;
          for j := 0 to sl2.Count-1 do
          begin
            MyLog.Add(' rem ERROR:' + sl2[j]);
            WriteLn(sl1[j]);
          end;
        finally
          MyLog.Free;
        end;
      finally
        sl1.Free;
        sl2.Free;
      end;
    end;
    except
    on E: Exception do
      Writeln('Es ist ein Fehler aufgetreten:',#13#10,E.ClassName, ': ', E.Message);
  end;
end.
(°¿°) MaBuSE - proud to be a DP member
(°¿°) MaBuSE - proud to be a "Rüsselmops" ;-)
  Mit Zitat antworten Zitat
generic

Registriert seit: 24. Mär 2004
Ort: bei Hannover
2.415 Beiträge
 
Delphi XE5 Professional
 
#19

AW: Doskonsole nutzen und Rückgabewerte einlesen

  Alt 28. Jul 2021, 13:49
Ideen beim ersten lesen:
Ich denke die Parameter werden nicht "richtig" übergeben.
Das "Files" kommt bestimmt aus den langen Dateinamen welche in " gefasst sind bzw. welche Leerzeichen enthalten.
Coding BOTT - Video Tutorials rund um das Programmieren - https://www.youtube.com/@codingbott
  Mit Zitat antworten Zitat
Benutzerbild von MaBuSE
MaBuSE

Registriert seit: 23. Sep 2002
Ort: Frankfurt am Main (in der Nähe)
1.837 Beiträge
 
Delphi 10 Seattle Enterprise
 
#20

AW: Doskonsole nutzen und Rückgabewerte einlesen

  Alt 28. Jul 2021, 17:26
Ideen beim ersten lesen:
Ich denke die Parameter werden nicht "richtig" übergeben.
Das "Files" kommt bestimmt aus den langen Dateinamen welche in " gefasst sind bzw. welche Leerzeichen enthalten.
Danke, ja das wars.
Manchmal sieht man vor lauter Wald die Bäume nicht.

Delphi-Quellcode:
 App := ChangeFileExt(ParamStr(0), '_org.exe');
...
for i := 1 to ParamCount do Params := Params + #32 + ParamStr(i);
...
// -> App + ' ' + Params
Ist natürlich Humbug. Da muss es schon spät gewesen sein

Ich mache es nun über ein Suchen und Ersetzen mit StringReplace direkt in der cmdline . -> funktioniert super.

(°¿°) MaBuSE - proud to be a DP member
(°¿°) MaBuSE - proud to be a "Rüsselmops" ;-)

Geändert von MaBuSE (28. Jul 2021 um 17:28 Uhr)
  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 13:12 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