![]() |
AW: Doskonsole nutzen und Rückgabewerte einlesen
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. |
AW: Doskonsole nutzen und Rückgabewerte einlesen
Dies
Delphi-Quellcode:
kann man auch einfach so schreiben
for I := 0 to SLOut.Count - 1 do
begin Memo1.Lines.Add(SLOut.Strings[I]); end;
Delphi-Quellcode:
Memo1.Lines := SLOut;
|
AW: Doskonsole nutzen und Rückgabewerte einlesen
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 :gruebel:
|
AW: Doskonsole nutzen und Rückgabewerte einlesen
Zitat:
|
AW: Doskonsole nutzen und Rückgabewerte einlesen
Zitat:
Geht einwandfrei. Vielen Dank. |
AW: Doskonsole nutzen und Rückgabewerte einlesen
Zitat:
Delphi-Quellcode:
wäre richtig.
Memo1.Lines.AddStrings(SLOut);
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. |
AW: Doskonsole nutzen und Rückgabewerte einlesen
Ich gehe davon aus, dass hiermit
Delphi-Quellcode:
der Inhalt von Memo1 mit den Daten von SLOut überschrieben wird und dadurch immer "geleert" wird.
Memo1.Lines := SLOut;
In meinem speziellen Fall ist es gewünscht, dass immer nur der aktuelle Inhalt geladen wird. Daher ist es mir nicht negativ aufgefallen. |
AW: Doskonsole nutzen und Rückgabewerte einlesen
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 :evil: Mein Problem (der Fehler): Im Log steht für jeden Eintrag:
Code:
Alle Aufrufe geben den Fehler
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'
Code:
aus, aber die Packages werden erzeugt.
Fatal: F1026 File not found: 'Files.dpr'
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. |
AW: Doskonsole nutzen und Rückgabewerte einlesen
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. |
AW: Doskonsole nutzen und Rückgabewerte einlesen
Zitat:
Manchmal sieht man vor lauter Wald die Bäume nicht. :stupid:
Delphi-Quellcode:
Ist natürlich Humbug. Da muss es schon spät gewesen sein :stupid:
App := ChangeFileExt(ParamStr(0), '_org.exe');
... for i := 1 to ParamCount do Params := Params + #32 + ParamStr(i); ... // -> App + ' ' + Params Ich mache es nun über ein Suchen und Ersetzen mit
Delphi-Quellcode:
direkt in der
StringReplace
Delphi-Quellcode:
. -> funktioniert super.
cmdline
:dp: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:48 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 by Thomas Breitkreuz