Delphi-PRAXiS
Seite 1 von 5  1 23     Letzte » 

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Externes Programm ausführen (https://www.delphipraxis.net/194595-externes-programm-ausfuehren.html)

Willie1 11. Dez 2017 10:35

Externes Programm ausführen
 
Hallo Delphifreunde/innen,

ich führe Exiftool von Phil Harvey aus, um die vollständigen Metadaten eines Bildes zu erhalten. Exiftool ist ein Programm ohne Oberfläche. Ich starte Exiftool aus meiner Anwendung, Exiftool legt eine temporäre Datei an, die ich dann mit meiner Anwendung einlese und anzeige. Das hat bis jetzt gut funktioniert, seit dem letzten Windows-Update nicht mehr. Unter Vista läuft es immer noch!
Zum Ausführen von Exiftool benutze ich diese Routine, nicht von mir wahrscheinlich hier aus dem Forum.
Delphi-Quellcode:
function ExecAndWait(const CommandLine, Parameter: string; SWModus: Word=SW_HIDE) : Boolean;
var
  StartupInfo: Windows.TStartupInfo;       // start-up info passed to process
  ProcessInfo: Windows.TProcessInformation; // info about the process
  ProcessExitCode: Windows.DWord;          // process's exit code
begin
  // Set default error result
  Result := False;
  // Initialise startup info structure to 0, and record length
  FillChar(StartupInfo, SizeOf(StartupInfo), 0);
  StartupInfo.cb := SizeOf(StartupInfo);
  StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
  StartupInfo.wShowWindow:=SWModus;
  // Execute application commandline
  if Windows.CreateProcess(nil,
                           PChar(CommandLine),
                           nil,
                           nil,
                           False,
                           0,
                           nil,
                           PChar(Parameter),
                           StartupInfo,
                           ProcessInfo) then
  begin
    try
      // Now wait for application to complete
      if Windows.WaitForSingleObject(ProcessInfo.hProcess, INFINITE)
        = WAIT_OBJECT_0 then
        // It's completed - get its exit code
        if Windows.GetExitCodeProcess(ProcessInfo.hProcess,
          ProcessExitCode) then
          // Check exit code is zero => successful completion
          if ProcessExitCode = 0 then
            Result := True
    finally
      // Tidy up
      Windows.CloseHandle(ProcessInfo.hProcess);
      Windows.CloseHandle(ProcessInfo.hThread);
    end
  end
  else
    Showmessage(Format('Fehler:%d - %s!',[GetLastError,SysErrorMessage(GetLastError)]))
end; {ExecAndWait}
Unter Windows 10 nach dem Update liefert sie false zurück.. CreateProcess wird ausgeführt, denn sonst gäbe es eine Fehlermeldung.

Ich weise darauf hin, dass ich ExecAndWait oft benutze auch mit Exiftool, nur hier geht's nicht. Was kann Microsoft geändert haben?
Hat jemand eine Idee, woran das liegen kann.

Gruß Willie.

Der schöne Günther 11. Dez 2017 10:41

AW: Externes Programm ausführen
 
Du hast doch einen Debugger. False kommt nur zurück wenn entweder WaitForSingleObject oder GetExitCodeProcess fehlschlägt oder der ExitCode ungleich Null ist.

Die ganzen WinApi-Funktionen die einen Boolean zurückgeben würde ich immer mit
Delphi-Quellcode:
Win32Check(..)
prüfen. Deine Methode wirft dann direkt die passene
Delphi-Quellcode:
EOSError
-Exception, da musst du nichts mehr mit
Delphi-Quellcode:
GetLastError()
usw. herauspflücken.

Jasocul 11. Dez 2017 11:31

AW: Externes Programm ausführen
 
So, wie ich das sehe, ist das Verhalten unter Vista falsch.
GetExitCodeProcess ist ungleich 0, wenn alles korrekt gelaufen ist.
Du prüfst aber auf gleich 0

Aus der Doku von Microsoft:
Zitat:

Return value

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

DeddyH 11. Dez 2017 11:37

AW: Externes Programm ausführen
 
Nein, er prüft ProcessExitCode gegen 0, nicht den Rückgabewert der Funktion.

Jasocul 11. Dez 2017 12:00

AW: Externes Programm ausführen
 
Ja, Sorry.
Ich bin auf den Klassiker reingefallen. :roll:

Habe mal meine alten Sourcen durchgesehen.
Der Status könnte an der Stelle noch STILL_ACTIVE sein, auch wenn der Prozess eigentlich beendet ist. Das ist dann ungleich 0.

Deswegen sollte man auch WaitForSingleObject verwendet, wie es hier schon im Source steht. Nutzt man nur GetExitCodeProcess in einer Schleife, kann das eine Endlos-Schleife werden. Zumindest habe ich das bei mir so notiert.

jaenicke 11. Dez 2017 13:59

AW: Externes Programm ausführen
 
Was gibt GetExitCodeProcess denn zurück? False? Oder ist ProcessExitCode ungleich 0? Das solltest du zunächst einmal im Debugger prüfen wie schon erwähnt.

Und wenn du ohnehin eine Meldung bei einem Fehlschlag anzeigst, könntest du das dort auch machen. Ich würde allerdings eher Exceptions verwenden, denn mit der Meldung ist der Fehler ja nicht unbedingt behandelt.

Willie1 11. Dez 2017 15:41

AW: Externes Programm ausführen
 
Antwort an euch alle:

ich hab's ausprobiert, auch auf einem Laptop mit Windows 10 vor dem letzen Update läuft es, wie gewünscht!
Ich werde euren Ratschlägen folgen und mich dann wieder melden.
Willie.

Willie1 12. Dez 2017 10:45

AW: Externes Programm ausführen
 
Hallo Günther,
ich habe ExecAndWait debuggt. Es wird vollständig durchlaufen, Rückgabewert immer true. Ich habe festgestellt, dass unter Windows 10 nach dem Update die temporäre Datei, die Exiftool mit den Metadaten anlegen soll, nicht erzeugt! Ich benutze die neuste Version Exiftool. Was hat Microsoft da gedreht? Eure Expertise ist gefragt, danke.

Willie.

rapante 12. Dez 2017 10:55

AW: Externes Programm ausführen
 
Hallo Willie,
wo soll die temporäre Datei denn erstellt werden? Eventuell gibt es hier ein Berechtigungsproblem...

Zitat:

Zitat von Willie1 (Beitrag 1388502)
ich hab's ausprobiert, auch auf einem Laptop mit Windows 10 vor dem letzen Update läuft es, wie gewünscht!

Was heißt den VOR dem letzten Update (bzw. danach)? Meinst du das Update auf 1709?

Delphi.Narium 12. Dez 2017 11:23

AW: Externes Programm ausführen
 
Ich würd' ja mal den Wert von ProcessExitCode abfragen. <> 0 heißt Fehler. Der entsprechende Wert gibt eventuell Auskunft darüber, was beim Exiftool schiefgegangen ist, den Fehler würd' ich dann mal beseitigen.

Eventuell mal CommandLine und Parameter ausgeben und auf der Kommandozeile nachschauen, ob dort bereits eine Fehlermeldung erscheint?

Wenn es dort bereits nicht funktioniert, den Fehler beheben und anschließend dann mit dem eigenen Programm das Zusammenspiel erneut testen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:46 Uhr.
Seite 1 von 5  1 23     Letzte » 

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