Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Eine *.cmd die startet, aber vorzeitig abbricht! (https://www.delphipraxis.net/170919-eine-%2A-cmd-die-startet-aber-vorzeitig-abbricht.html)

darkmarin 10. Okt 2012 12:00

Delphi-Version: XE

Eine *.cmd die startet, aber vorzeitig abbricht!
 
Hallo an Alle :-D

ich bin seit einiger Zeit dabei und fühle mich sehr wohl hier in diesem Forum.

Bis jetzt habe ich dieses lediglich nur als Nachschlagewerk genutzt,
das ist meine erste Anfrage und es wäre sehr nett wenn ich Unterstützung bekommen könnte.

Bis jetzt reichte immer die Suchfunktion aber jetzt... :?:

wenn ich ein *.cmd direkt in einem Windows Fenster starte dann läuft das Aufgerufene Programm mit allen Parametern fehlerfrei ab.

Starte ich aber aus dem Delphi Programm mit egal welcher version Shellexec... oder CreateProcess... schliesst der Vorgang ohne Fehler vorzeitig ab.

Wie kannich ein solches Windows Fenster nachprogrammieren? Als ob es aus dem Windows heraus gestartet wurde.

Ich hoffe ich konnte mein Problem ausreichend beschreiben.

Grüße
und vielen Dank im voraus

Darko

himitsu 10. Okt 2012 12:13

AW: Eine *.cmd die startet, aber vorzeitig abbricht!
 
Du kannst die CMD.exe starten und ihr via Parameter sagen, daß sie diese CMD ausführen soll (siehe
Delphi-Quellcode:
CMD /?
)

Hast du denn auch das Arbeitsverzeichnis beim ShellExecute angegeben?


Tipp: Mach einfach mal nach/vor jeder Zeile, in der CMD, eine PAUSE rein.

Uwe Raabe 10. Okt 2012 12:19

AW: Eine *.cmd die startet, aber vorzeitig abbricht!
 
Mit ShellExecute bzw. CreateProcess wird ja auch nur ein separater Prozess gestartet und der Aufruf kehrt sofort sofort zurück.

Wenn du in deinem Programm auf das Ende dieses Prozesses warten willst, dann musst du das auch tun. Das geht mit einer entsprechenden WaitFor-Anweisung, wobei du an das Process-Handle z.B. bei CreateProcess über den letzten Parameter lpProcessInformation herankommst.

Allerdings ist deine Anwendung dann während des WaitFor blockiert. Man sollte dann entsprechende Vorkehrungen treffen, um das gegebenfalls abzubrechen.

Bei Delphi About gibt es ein Beispiel: http://delphi.about.com/od/windowssh...uteprogram.htm

darkmarin 10. Okt 2012 13:13

AW: Eine *.cmd die startet, aber vorzeitig abbricht!
 
Hallo und vielen Dank für die schnelle Unterstützung!:thumb:

In der *.cmd ist folgender Inhalt

c:\openocd-0.5.0\bin\openocd-0.5.0.exe -f c:\openocd-0.5.0\interface\jtagkey.cfg -f C:\openocd-0.5.0\WORK\jtag_ertec\ertec200.cfg -c "global SOURCE" -c "set SOURCE 4377FC_105.bin" -f c:/FknFile/4377FC_105.scr > c:\AmoLogFiles\Standard.log

Ich bin auf die Ausgabe aus dem Script heraus angewiesen da dort jeweils der Fortschritt dokumentiert wird.
Ich gebe (TCL Script) jeweils mit ECHO und PUTS in die Konsole und das Logfile aus.

WaitForSingleObject(ProcessInfo.hProcess, INFINITE);// hab ich bedacht.

Im Process Explorer ist es so das aus der Konsole die openocd.exe gekillt wird
aus der SchellExecute aber die cmd.exe beendet wird obwohl openocd.exe noch läuft.

Wie formuliere ich den Aufruf das die Konsole bleibt bis alle aus Ihr heraus gestarteten Processe beendet sind?

Ich denke das ist mein Problem.

Liebe Grüße

Darko

DeddyH 10. Okt 2012 13:26

AW: Eine *.cmd die startet, aber vorzeitig abbricht!
 
Und wenn Du cmd mit dem Parameter /K startest?

darkmarin 10. Okt 2012 13:42

AW: Eine *.cmd die startet, aber vorzeitig abbricht!
 
Hallo Detlef

wie meinst du das?
Jetzt mal nur ein Aufruf als Beispiel.
Delphi-Quellcode:
begin
  if ExecAndWaitUAC('c:\openocd-0.5.0\bin\openocd-0.5.0.exe', ' -f c:\openocd-0.5.0\interface\jtagkey.cfg -f                                                                                                              C:\openocd-0.5.0\WORK\jtag_ertec\ertec200.cfg -c "global SOURCE" -c "set SOURCE 4377FC_105.bin" -f    c:/FknFile/4377FC_105.scr > c:\AmoLogFiles\Standard.log');
then
Die Funktion ist nicht von mir sondern lediglich die letzte von vielen die ich ausprobiert habe.

Delphi-Quellcode:
function TspecConsole.ExecAndWaitUAC(Filename, Params: Widestring; WindowState: word = SW_SHOWNORMAL): boolean;
var
  ShExecInfoW: SHELLEXECUTEINFOW;
  ShExecInfoA: SHELLEXECUTEINFOA;
  r : Cardinal;
begin
  Result := false;
  if Filename = '' then exit;
  if not FileExists(FileName) then
    exit;
    ZeroMemory(@ShExecInfoW, SizeOf(ShExecInfoW));
    ShExecInfoW.Wnd := GetForegroundWindow;
    ShExecInfoW.cbSize := sizeof(SHELLEXECUTEINFOW);
    ShExecInfoW.fMask := SEE_MASK_NOCLOSEPROCESS;
    ShExecInfoW.lpVerb := 'open';
    ShExecInfoW.lpFile := PWideChar(Filename);
    ShExecInfoW.lpParameters := PWideChar(Params);
    ShExecInfoW.lpDirectory := PWideChar(ExtractFileDir(Filename));
    ShExecInfoW.nShow := WindowState;
    Result := ShellExecuteExW(@ShExecInfoW);

  try
    if Result then
    begin
      r := WaitForSingleObject(ShExecInfoW.hProcess, INFINITE)
    end;
  finally
    //CloseHandle(ShExecInfoW.hProcess);
  end;
end;
Gruß

Darko

jaenicke 10. Okt 2012 13:51

AW: Eine *.cmd die startet, aber vorzeitig abbricht!
 
Starte nicht deine exe, sondern die cmd.exe und gib deinen Aufruf nach /k als weiteren Parameter an.

Oder du machst es noch einfacher und liest die Ausgabe des Aufrufs selbst aus und speicherst diese Ausgabe selbst aus Delphi heraus in die c:\AmoLogFiles\Standard.log.

darkmarin 10. Okt 2012 14:11

AW: Eine *.cmd die startet, aber vorzeitig abbricht!
 
Hallo Sebastian

ich verstehe nicht was du meinst mit meiner exe.

Ich starte
openocd.exe übergebe
dann => Programmerdaten jtagkey.cfg
dann => Prozessordaten ertec200.cfg
dann => Firmwaredaten als Global SOURCE" -c "set SOURCE xyz.bin"
dann => das ArbeitsScript xyz.scr
und sag ihm wohin mit den Mitteilungen aus dem Script
> c:\AmoLogFiles\Standard.log'

ich habe das Problem des zu frühen beenden des CreateProcess oder ShellExecute Processes.

Im Hintergrund läuft noch openocd.

Gruß und Danke

Darko

Dalai 10. Okt 2012 14:14

AW: Eine *.cmd die startet, aber vorzeitig abbricht!
 
Eine Umleitung von Ausgaben/Eingaben funktioniert nur auf einer CMD, denn die stellt die nötige Umgebung zur Verfügung. Das bedeutet, dass deine openocd.exe nur dann erfolgreich mit einer Umleitung läuft, wenn du sie innerhalb einer CMD laufen lässt.

MfG Dalai

himitsu 10. Okt 2012 14:20

AW: Eine *.cmd die startet, aber vorzeitig abbricht!
 
Oder anders gesagt, das > ist ein "Operator", welcher von der CMD interpretiert wird.

Aber so wie du es jetzt aufrufst, wird dieses als (zwei) Parameter an deine EXE übergeben, welche dieses so wohl nicht von sich aus behandelt.


Man kann es aber auch selber umleiten.
Es gibt auch Komponenten, welche eine Pipe als Ausgabepfade angeben, wo man dann die Ausgaben direkt in einer Datei, einem Stream oder gar als Event geliefert bekommt.

Zitat:

ich habe das Problem des zu frühen beenden des CreateProcess oder ShellExecute Processes.
Das ist aber kein Problem dieser Befehle, denn diese starten nunmal nur und warten nicht.

Bummi 10. Okt 2012 14:20

AW: Eine *.cmd die startet, aber vorzeitig abbricht!
 
Wenn Du bei CreateProcess mit Pipes versorgst, müsste der Aufruf funktionieren und die Ausgabe über die Pipe direkt abrufbar sein ...
StartupInfo.hStdOutput := PipeOutputWrite;
StartupInfo.hStdError := PipeErrorsWrite;


In dem Code hier sind die IMHO benötigten Info's...

http://www.delphipraxis.net/152490-w...tionieren.html

DeddyH 10. Okt 2012 14:39

AW: Eine *.cmd die startet, aber vorzeitig abbricht!
 
Müsste es
Delphi-Quellcode:
ShellExecute(0, 'open', 'cmd.exe', PChar('/K c:\openocd-0.5.0\bin\openocd-0.5.0.exe -f c:\openocd-0.5.0\interface\jtagkey.cfg -f C:\openocd-0.5.0\WORK\jtag_ertec\ertec200.cfg -c "global SOURCE" -c "set SOURCE 4377FC_105.bin" -f c:/FknFile/4377FC_105.scr > c:\AmoLogFiles\Standard.log'), nil, nil, SW_SHOW);
nicht auch tun?

darkmarin 10. Okt 2012 15:09

AW: Eine *.cmd die startet, aber vorzeitig abbricht!
 
Hallo hab da ganze mal mit memos aufgebaut.:idea:

Ok mit der Ausgabe über Pipes klappt,
Aber wie den Aufruf übergeben das die Abhängigkeiten stimmen?:arrow::?::(

Delphi-Quellcode:
function TForm1.GetConsoleOutput(const Command : string;
                          Output, Errors : TStringList) : Boolean;
var
  Buffer           : array[0..1024] of Char;
  CreationFlags    : DWORD;
  NumberOfBytesRead : DWORD;
  PipeErrorsRead   : THandle;
  PipeErrorsWrite  : THandle;
  PipeOutputRead   : THandle;
  PipeOutputWrite  : THandle;
  ProcessInfo      : TProcessInformation;
  SecurityAttr     : TSecurityAttributes;
  StartupInfo      : TStartupInfo;
  Stream           : TMemoryStream;
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;

  if CreateProcess(nil,
                   PChar(Command),
                   nil,
                   nil,
                   True,
                   CreationFlags,
                   nil,
                   nil,
                   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;
Delphi-Quellcode:
procedure TForm1.Button3Click(Sender: TObject);
   var
  Output : TStringList;
  Errors : TStringList;
begin
  Output := TStringList.Create;
  Errors := TStringList.Create;
  try
    if GetConsoleOutput(AdvEdit1.Text, Output, Errors) then
      Memo1.Lines.AddStrings(Output);
      Memo2.Lines.AddStrings(Errors);
  finally
    Output.free;
    Errors.free;
  end;
end;
Ich steh auf dem Schlauch.


Gruß

Darko

darkmarin 10. Okt 2012 15:10

AW: Eine *.cmd die startet, aber vorzeitig abbricht!
 
Hallo Detlef

probier ich sofort aus!:thumb:

darkmarin 10. Okt 2012 15:54

AW: Eine *.cmd die startet, aber vorzeitig abbricht!
 
Hallo Detlef

das Fenster bleibt stehen
aber das Programm bricht an der gleichen Stelle,
wie in den vorherigen Versuchen,
vorzeitig ab.

Teilauszug... aus der Konsole
************************************************** ***************************
Error: couldn't open 4377FC_105.bin
Runtime Error: c:/FknFile/4377FC_105.scr:298:
in procedure 'script'
at file "embedded:startup.tcl", line 58
in procedure 'flash' called at file "c:/FknFile/4377FC_105.scr", line 298
************************************************** ***************************

Das scheint das Problem zu sein wenn ich es über ShellEx... oder CreatePro... ablaufen lasse.

DeddyH 10. Okt 2012 15:59

AW: Eine *.cmd die startet, aber vorzeitig abbricht!
 
Das sieht so aus, als ob ein Bildschirmschoner auf eine Datei zugreifen will, die es nicht gibt oder die momentan gesperrt ist oder oder. Kannst Du im SET SOURCE-Aufruf einen absoluten Pfad angeben?

darkmarin 10. Okt 2012 16:31

AW: Eine *.cmd die startet, aber vorzeitig abbricht!
 
Ich habe den Pfad mit angegeben macht aber keinen Unterschied.
Der Fehler bleibt.

couldn't open 43.bin ...

DeddyH 10. Okt 2012 16:33

AW: Eine *.cmd die startet, aber vorzeitig abbricht!
 
Funktioniert es denn, wenn Du den ursprünglichen Befehl (also alles nach dem "/K") über Start-Ausführen absetzt? Es scheint ja irgend ein Problem beim Öffnen dieser bin zu geben.

darkmarin 10. Okt 2012 16:39

AW: Eine *.cmd die startet, aber vorzeitig abbricht!
 
Nein, gleicher Fehler.

Funktioniert nur wenn ich direkt in einer Konsole starte.

jaenicke 10. Okt 2012 16:40

AW: Eine *.cmd die startet, aber vorzeitig abbricht!
 
Naja, in dem geposteten Quelltext wird als Arbeitsverzeichnis "nichts" angegeben (nil). Wenn du auf der Konsole startest, ist das dann das Verzeichnis, in dem du da bist.

Ich vermute mal das musst du noch setzen...
Siehe Doku von CreateProcess:
http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx

darkmarin 10. Okt 2012 16:45

AW: Eine *.cmd die startet, aber vorzeitig abbricht!
 
Versuch läuft!

darkmarin 10. Okt 2012 16:56

AW: Eine *.cmd die startet, aber vorzeitig abbricht!
 
Super!:bouncing4::cheers::bounce1:

Sebastian das hat noch gefehlt.

Kaum macht man es richtig...

Vielen Dank an euch alle.

Ich war schon am verzweifeln.

Jetzt klappt es! Ohne Fehler mit Ausgabe in das File.

Gruß

Darko

darkmarin 16. Okt 2012 16:39

AW: Eine *.cmd die startet, aber vorzeitig abbricht!
 
Hallo zusammen, :)

jetzt habe ich in diesem Zusammenhang folgende Frage.

So lange das cmd.exe Programm läuft steht die Zeitanzeige(TVrClock)auf der Form,
diese läuft erst wieder nach Abschluss und beenden des Cmd Fensters.
Die cmd.exe läuft bis zu drei Minuten lang.

Das macht einen Anschein, als ob das Gesamtprogramm eingefroren wäre!

Wie kann ich diese Zeitanzeige weiterlaufen lassen. Unabhängig vom cmd.exe Fenster.

Einfach als Funktionsanzeige.

Gruß

Darko

Bummi 16. Okt 2012 16:48

AW: Eine *.cmd die startet, aber vorzeitig abbricht!
 
In einen Thread auslagern....

DeddyH 16. Okt 2012 16:52

AW: Eine *.cmd die startet, aber vorzeitig abbricht!
 
Wie wird cmd.exe denn aufgerufen? Wartest Du mit WaitForSingleObject?

darkmarin 16. Okt 2012 16:58

AW: Eine *.cmd die startet, aber vorzeitig abbricht!
 
Lese gerade das Tutorial im Delphi-Treff.

Scheint sehr kompliziert zu sein.

Was sollte ich den im Thread auslagern die Anzeige oder die cmd.exe ?


Ja ich warte auf "WaitForSingleObject" das ist wichtig für den weiteren Programmablauf!

Gruß

Darko

DeddyH 16. Okt 2012 17:02

AW: Eine *.cmd die startet, aber vorzeitig abbricht!
 
Nur mal zum Testen:
Delphi-Quellcode:
while WaitForSingleObject(...) = WAIT_OBJECT_0 do
  Application.ProcessMessages;

darkmarin 16. Okt 2012 17:13

AW: Eine *.cmd die startet, aber vorzeitig abbricht!
 
Mein Aufruf

unit ShellApiEx
Delphi-Quellcode:
ShellExecuteAndWaitW(aHwnd,
                     PChar('open'),
                     PChar('cmd.exe'),
                     PChar(Helpstring),
                     PChar('c:\fknfile\'),
                     SW_SHOWMINIMIZED,
                     true)

Bummi 16. Okt 2012 17:51

AW: Eine *.cmd die startet, aber vorzeitig abbricht!
 
In meinem Link aus #12 wird so etwas gemacht.

darkmarin 16. Okt 2012 18:26

AW: Eine *.cmd die startet, aber vorzeitig abbricht!
 
:)

@ Detlef
hab meinen Aufruf editiert aber die Form bleibt wie eingefroren.

@ Thomas
das schau ich mir morgen früh mal an. Danke für den Hinweis.

Schönen Abend an alle, für Heute reicht es erst mal.

Danke für die Unterstützung.:thumb:

Gruß

Darko


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:13 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