Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Befehlszeile ausführen (https://www.delphipraxis.net/156403-befehlszeile-ausfuehren.html)

Landogar-Garuno 1. Dez 2010 01:52

Befehlszeile ausführen
 
hallo alle zusammen

komme hier nicht weiter

r
procedure TForm1.Button1Click(Sender: TObject);
VAR
output,errors: TStringList;
sBatchDatei : string;
begin
Memo2.clear;
begin
If CheckBox1.Checked then begin
Memo2.Lines.add('xxxx.exe -parameter1 ');
end;
If CheckBox2.Checked then begin
Memo2.Lines.add('xxxx.exe -parameter2 ');
end;
begin
sBatchDatei := memo2.lines[0];
output:=TStringList.Create;
try errors:=TStringList.Create;
if GetConsoleOutput((sBatchDatei), output, errors) then
Memo1.Lines.AddStrings(errors);
Memo1.Lines.AddStrings(output);
finally
output.free;
errors.free;
end;
t.free;

soweit funzt der code....mein problem ist es sind über 80 zeilen die abgearbeitet werden sollen...und zum schluß als text datei abgespeichert werden.
bekomme die schleife nicht hin.

Assarbad 1. Dez 2010 01:57

AW: Befehlszeile ausführen
 
Guck mal, in meiner Version sind die Einrückungen zwar weg die vermutlich in deinem Original waren, aber trotzdem ist es lesbarer.

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  output, errors: TStringList;
  sBatchDatei: string;
begin
  BefehlsMemo.clear;
  begin
    If CheckBox1.Checked then
    begin
      BefehlsMemo.Lines.add('xxxx.exe -parameter1 ');
    end;
    If CheckBox2.Checked then
    begin
      BefehlsMemo.Lines.add('xxxx.exe -parameter2 ');
    end;
    begin
      sBatchDatei := BefehlsMemo.Lines[0];
      output := TStringList.Create;
      try
        errors := TStringList.Create;
        if GetConsoleOutput((sBatchDatei), output, errors) then
          AusgabeMemo.Lines.AddStrings(errors);
        AusgabeMemo.Lines.AddStrings(output);
      finally
        output.free;
        errors.free;
      end;
      t.free; // <--- ????
    end;
  end;
end;
Benutze doch bitte die Delphi-Tags (den "Griechenhelm" bei den Toolbuttons im Editor).

Nachtrag: habe es mal durch den Castalia-Formatierer gejagt. Da fehlten ja noch ein paar end-Statements usw ...

Landogar-Garuno 1. Dez 2010 02:06

AW: Befehlszeile ausführen
 
Danke

habe ich zwar benutzt aber...bestimmt verschoben (zeilen umbruch)

t.free; // <--- ????

ist delphi-tags wie gesagt habe einem zeilenumbruch gemacht.

Assarbad 1. Dez 2010 02:17

AW: Befehlszeile ausführen
 
So, dann widmen wir uns mal dem Code ;)

Tip: man kann den TMemo-Instanzen auch aussagekräftige Namen geben. Hilft dabei den eigenen Code zu verstehen. Bspw.:

Memo1 -> AusgabeMemo
Memo2 -> BefehlsMemo

Delphi-Quellcode:
      sBatchDatei := BefehlsMemo.Lines[0];
      output := TStringList.Create;
      try
        errors := TStringList.Create;
        if GetConsoleOutput(sBatchDatei, output, errors) then
          AusgabeMemo.Lines.AddStrings(errors);
        AusgabeMemo.Lines.AddStrings(output);
      finally
        output.free;
        errors.free;
      end;
Bis auf die fehlenden Checks fällt mir hier eigentlich nix auf.

Die Zeilen sollen aus dem Memo2 (BefehlsMemo) genommen und ausgeführt werden?

Grob wäre das:
Delphi-Quellcode:
    begin
      output := TStringList.Create;
      try
        errors := TStringList.Create;
        for i := 0 to BefehlsMemo.Lines.Count -1  do
        begin
          sBatchDatei := BefehlsMemo.Lines[i];
          if GetConsoleOutput((sBatchDatei), output, errors) then
            AusgabeMemo.Lines.AddStrings(errors);
          AusgabeMemo.Lines.AddStrings(output);
        end;
      finally
        output.free;
        errors.free;
      end;
    end;
Übrigens: du kannst deinen Ausgangsbeitrag noch immer bearbeiten um die Delphi-Tags einzufügen. Ansonsten müssen wir wieder warten bis sich ein Mod erbarmt.

Landogar-Garuno 1. Dez 2010 02:30

AW: Befehlszeile ausführen
 
danke funzt :-D

himitsu 1. Dez 2010 09:01

AW: Befehlszeile ausführen
 
Zitat:

Delphi-Quellcode:
output := TStringList.Create;
try
  errors := TStringList.Create; // 1
  ...
finally
  output.free;
  errors.free; // 2
end;

Wenn es bei (1) zu einer Exception kommt, dann knallt es bei (2) bestimmt nochmal und verfälscht so die Fehlerursache,
da die Variable in diesem Fall nicht initialisiert wurde (was eigentlich Delphi auch bemängeln sollte).

z.B. statt einem OutOfMemory bekommt man dann vermutlich ein "Zugriffsverletzung bei Adresse soundso" zu sehn.

also müßte es eigentlich so aussehn
Delphi-Quellcode:
output := TStringList.Create;
try
  errors := TStringList.Create;
  try
    ...
  finally
    errors.free;
  end;
finally
  output.free;
end;
oder wenigstens so
Delphi-Quellcode:
errors := nil;
output := TStringList.Create;
try
  errors := TStringList.Create;
  ...
finally
  output.free;
  errors.free;
end;
oder so
Delphi-Quellcode:
output := nil;
errors := nil;
try
  output := TStringList.Create;
  errors := TStringList.Create;
  ...
finally
  output.free;
  errors.free;
end;

idefix2 1. Dez 2010 09:26

AW: Befehlszeile ausführen
 
Das Problem, dass es beim finally knallen kann, hast Du in der letzten von Dir vorgeschlagenen Variante aber genauso.Auch die zweite Variante deckt nicht alle denkmöglichen Probleme 100%ig sauber ab. Und wozu die nil-Zuweisung?

Ich weiss nicht recht - im Prinzip stimmt zwar, was Du schreibst, aber ist nicht ohnehin schon alles verloren, wenn ein simples tstringlist.create fehlschlägt? So etwas mit einem (gar noch geschachtelten) Try finally abzufangen und dann im Programm weiterzumachen, scheint mir eigentlich nicht sehr sinnvoll zu sein. Da wird sicher nichts mehr, also kann man das Ganze doch ebenso gut ohne try finally einfach geich abstürzen lassen, oder liege ich da falsch?

DeddyH 1. Dez 2010 09:34

AW: Befehlszeile ausführen
 
Du liegst falsch. Free prüft intern auf nil ab, so dass nil-Objekte nicht zerstört werden, es folglich also auch nicht knallt.

idefix2 1. Dez 2010 09:40

AW: Befehlszeile ausführen
 
Wenn schon ein tstringlist.create abstürzt, wird es sowieso bei nächster Gelegenheit knallen. Derartige Fehler abfangen und weitermachen, als wäre nichts gewesen, bringt doch gar nichts.

himitsu 1. Dez 2010 09:40

AW: Befehlszeile ausführen
 
Nee, wieso soll es da knallen?
Free prüft ja auf NIL und überspringt dann das Freigeben.
(unter Anderem soll man darum ja auch vorzugsweise .Free und nicht direkt .Destroy aufrufen)
[add]ahhhh, wo kommen denn die Beiträge her :shock: ... und DeddyH zustimm[add/]

Nja, es geht mehr ums Prinzip. Klar kann bei diesem einfachen TStringLst.Create nicht viel passieren und wenn, dann ist wirklich Vieles schon verloren, aber was ist, wenn in dem Create mal mehr passiert?

Beispiel:
Delphi-Quellcode:
fs := TFileStream.Create('dateina.me', ...);
... wenn es hier z.B. wegen fehlenden Rechten knallt und dann diese Fehlermeldung durch die nachfolgend auftretende Speicherzugriffsverletzung verdeckt wird, dann hat man ein Problemchen.
(bei dieser lokalen Variable ist die Chance immerhin nur 1 zu 4 Milliarden, daß diese Variable zufällig schon nil ist)
OK, der Debugger hält vielleicht noch bei der ersten Exception kurz an, aber ohne Debugger sieht man nur noch die letzte Exception.


[add]
Auch wenn bei soeinem einfachem und dennoch extremen Einzelfall eh alles egal ist,
sollte man dennoch eine einheitliche Behandlung implementieren.
Wenn man es immer so/gleich macht, dann vergißt man es an anderen Stellen nicht, wo es dann mal nicht mehr egal sein könnte.

PS: Das Zweite ist nur eine kleine zusätzliche Zeile, ein einziger extrem kurzer ASM/CPU-Befehl und belegt nur sehr wenige Bytes in der EXE, aber es kann eine sehr große positive Wirkung haben.


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:07 Uhr.
Seite 1 von 2  1 2      

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