Delphi-PRAXiS
Seite 1 von 2  1 2      

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 09: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 09: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 10: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 10:37

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

Jasocul 11. Dez 2017 11: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 12: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 14: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 09: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 09: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 10: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.

Willie1 12. Dez 2017 14:35

AW: Externes Programm ausführen
 
Liste der Anhänge anzeigen (Anzahl: 2)
Hallo,
in dem Temp-Ordner. Bei mir c:\users\nutzername\appdata\local\temp (ermittelt durch Windows-Funktion).
Auf dem Desktop-PC: Windows 10 1709 Built 16299.98 von letzter Woche. Hier gehsts nicht
Laptop: Windows 10 1709 Built 15062.726. Hier gehts.

Ich hab's gerade nochmal auf dem Laptop versucht, die Datei hänge ich an, ebenso einen Auszug aus der Doku von Phil Harvey zu Exiftool.

Ich werde ein Testprogramm entwickeln und sehen, ob ich dann heraus finde, warum die Datei nicht gespeichert wird.

Willie.

hoika 12. Dez 2017 14:45

AW: Externes Programm ausführen
 
Hallo,
ist es der gleiche Benutzername?

Willie1 12. Dez 2017 17:31

AW: Externes Programm ausführen
 
Ja!

Ich habe Exiftool in der "Eingabeaufforderung" ausgeführt und die Datei in den TEMP-Ordner ablegen wollen, ging nicht "Zugriff verweigert".

Willie.

LTE5 12. Dez 2017 17:33

AW: Externes Programm ausführen
 
Sicher, dass du TEMP eingegeben hast und nicht %TEMP% ?

Ist meiner Meinung nach aber kein Codeproblem sondern nur ein verkorkstes Windows 10.

Willie1 12. Dez 2017 17:56

AW: Externes Programm ausführen
 
Da könntest du recht haben. Es sieht wohl so aus, dass Exiftool die Datei nicht in TEMP schreiben kann.
Morgen werde ich es nochmal versuchen.
Da fällt mir gerade ein, könnte der Virenwächter dazwischen funken? Schließlich wird eine Datei erzeugt und abgelegt.

Willie.

Benmik 12. Dez 2017 20:56

AW: Externes Programm ausführen
 
Liste der Anhänge anzeigen (Anzahl: 1)
EXIF Tool ist auch für mich ein extrem interessantes Programm. Nur der Weg über diese temporären Dateien stört mich enorm.
Geht eigentlich nicht der Weg über eine pipe? Auf Harveys Seite gibt es einen Link zu VB-Beispiel-Code, der das über
Delphi-Quellcode:
CreatePipe
macht. Siehe vielleicht auch diese Beiträge hier.

PS: Bin ja doof, ich sehe eben, die Umsetzung schlummert schon längst auf meiner Festplatte...

Hier ist die Unit:
Delphi-Quellcode:
unit ExifTool;

interface
uses Classes;

var
  ETout, ETerr: TStringList; //data from ExifTool will be here

function ExecuteET(const ETcmd,WorkDir: string): Boolean;

implementation
uses Windows;

function ExecuteET(const ETcmd,WorkDir: string): Boolean;
const
  szBuffer=255;
var
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
  PWorkDir: PChar;
  SecurityAttr: TSecurityAttributes;
  PipeOutputRead: THandle;
  PipeOutputWrite: THandle;
  PipeErrorsRead: THandle;
  PipeErrorsWrite: THandle;
  Succeed: Boolean;
  Buffer: array [0..szBuffer] of Char;
  BytesRead: DWORD;
  Stream: TMemoryStream;
begin
  //=== Usual steps to initialize data for CreateProcess:
  FillChar(Buffer,SizeOf(Buffer),0);
  FillChar(ProcessInfo, SizeOf(TProcessInformation), 0);
  FillChar(SecurityAttr, SizeOf(TSecurityAttributes), 0);
  SecurityAttr.nLength := SizeOf(SecurityAttr);
  SecurityAttr.bInheritHandle := true;
  SecurityAttr.lpSecurityDescriptor := nil;
  CreatePipe(PipeOutputRead, PipeOutputWrite, @SecurityAttr, 0);
  CreatePipe(PipeErrorsRead, PipeErrorsWrite, @SecurityAttr, 0);
  FillChar(StartupInfo, SizeOf(TStartupInfo), 0);
  StartupInfo.cb:=SizeOf(StartupInfo);
  with StartupInfo do begin
    hStdInput:=0; hStdOutput:=PipeOutputWrite; hStdError:=PipeErrorsWrite;
    wShowWindow:=SW_HIDE;
    dwFlags:=STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
  end;
  if WorkDir='' then PWorkDir:=nil else PWorkDir:=PChar(WorkDir);
  ETout.Clear; ETerr.Clear;

  //=== Here is where ExifTool is called:
  if CreateProcess(nil, PChar(ETcmd), nil, nil, true,
    CREATE_DEFAULT_ERROR_MODE or CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS,
    nil, PWorkDir, StartupInfo, ProcessInfo)
  then begin     //=ExifTool started successfully:
    result:=true;
    CloseHandle(PipeOutputWrite);
    CloseHandle(PipeErrorsWrite);
  end else begin //=ExifTool not started (because, i.e. not found):
    result:=false;
    CloseHandle(PipeOutputRead); CloseHandle(PipeOutputWrite);
    CloseHandle(PipeErrorsRead); CloseHandle(PipeErrorsWrite);
  end;

  if result then begin
    //= Get output written by ExifTool(tag names/values):
    Stream:=TMemoryStream.Create;
    try
      repeat
        succeed:=ReadFile(PipeOutputRead,Buffer,szBuffer,BytesRead,nil);
        if not succeed then break;
        Stream.Write(Buffer,BytesRead)
      until (BytesRead=0);
      Stream.Position:=0; ETout.LoadFromStream(Stream);
    finally Stream.Free; end;
    CloseHandle(PipeOutputRead);
    //= Get errors written by ExifTool (if any):
    Stream:=TMemoryStream.Create;
    try
      repeat
        succeed:=ReadFile(PipeErrorsRead,Buffer,szBuffer,BytesRead,nil);
        if not succeed then break;
        Stream.Write(Buffer,BytesRead);
      until (BytesRead=0);
      Stream.Position:=0; ETerr.LoadFromStream(Stream);
    finally Stream.Free; end;
    CloseHandle(PipeErrorsRead);

    WaitForSingleObject(ProcessInfo.hProcess,5000); //=5sec
    CloseHandle(ProcessInfo.hThread); CloseHandle(ProcessInfo.hProcess);
  end;
end;

initialization
begin
  ETout:=TStringList.Create;
  ETerr:=TStringList.Create;
end;

finalization
begin
  ETerr.Free;
  ETout.Free;
end;

end.
Aufruf:
Delphi-Quellcode:
  procedure FühreTestCodeAus;
  var ETool,ETCmd,Datname:string;
  begin
    ETool  := 'C:\EXIFTool\exiftool.exe ';
    ETCmd := ' -k -a -u -g1 -lang de ';
    Datname := '"C:\Temp\Test\01-Testdatei.JPG"';
    ExecuteET(ETool + ETCmd + Datname,'');
  end;
Das Ergebnis ist dann in ETout

Delphi.Narium 12. Dez 2017 22:02

AW: Externes Programm ausführen
 
Handelt es sich bei dem Inhalt der Temp-Datei um die Konsolenausgabe des ExifTools, die per > in 'ne Datei umgeleitet wurde?

Dann mal hier im Forum nach "Process Pipe" suchen. Da müsste was brauchbares zu finden sein, per Pipe bekommt man die Konsolenausgabe des ExifTools dann direkt ins Programm geliefert.

Benmik 12. Dez 2017 22:26

AW: Externes Programm ausführen
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1388629)
Handelt es sich bei dem Inhalt der Temp-Datei um die Konsolenausgabe des ExifTools, die per > in 'ne Datei umgeleitet wurde?

Nein, dafür gibt es bei EXIFTools einen eigenen Schalter. Die Erläuterung hierzu hat er ja auch als Datei beigefügt.

Delphi.Narium 12. Dez 2017 22:49

AW: Externes Programm ausführen
 
Ok. Und wenn man den Schalter weglässt, dann erfolgt die Ausgabe auf die Konsole und kann dann (ohne Datei) per Pipe ins Programm übernommen werden.

Er wäre (denk ich) mal 'nen Versuch wert, ob man so die Kommunikation zwischen Programm und ExifTool vereinfachen kann und man muss sich dann nicht darum kümmern, ob man für (nur temporär benötigte) Dateien alle erforderlichen Rechte hat.

Benmik 12. Dez 2017 22:59

AW: Externes Programm ausführen
 
Vielleicht hast du meine Antwort übersehen (#16).

Delphi.Narium 12. Dez 2017 23:38

AW: Externes Programm ausführen
 
Ja, die Änderung von 23:21 Uhr, hab' ich irgendwie nicht mitbekommen, aber genau das meinte ich. Ist wohl schon zu spät :-(

jaenicke 13. Dez 2017 04:21

AW: Externes Programm ausführen
 
In solch einem Fall ist es am einfachsten den Process Monitor zu benutzen, um damit einfach festzustellen was eigentlich mit der temporären Datei schiefgeht. Dort siehst du ganz genau, ob die Datei im falschen Ordner erstellt werden soll oder was sonst das Problem ist.
https://technet.microsoft.com/de-de/...ssmonitor.aspx
Bei Filter setzt du process name is deine.exe, das war es.

Willie1 14. Dez 2017 10:58

AW: Externes Programm ausführen
 
Ich werde alles ausprobieren, ich bin sehr interessiert. Exiftool ist meiner Meinung nach das beste Programm für Metadaten von Bildern, besonders zum Schreiben von Daten z.B des Orientation-Tag, damit das Bild richtig gedreht wird.
Danke, ich melde mich...
Willie.

Willie1 14. Dez 2017 15:35

AW: Externes Programm ausführen
 
Hallo,

ich weiß jetzt, wie Exiftool in der Eingabeaufforderung eine externe Textdatei mit den
Metadaten anlegt.
Es geht so: In der Eingabeauff.:
1. Beispiel exiftool Korfu.jpg >"%temp%"\Bild.txt piped Bild.txt in Temp-Ordner des BS.
2. Beispiel exiftool Korfu.jpg -w! .txt legt Korfu.txt im gleichen Ordner wie das Bild ab.
3. Beispiel exiftool Korfu.jpg -w! %dc:\data\%f.txt legt Korfu.txt im Ordner Data ab,
falls nicht vorhanden, wird er angelegt.
4. Beispiel exiftool Korfu.jpg -w! %d"%temp%"\%f.txt legt Korfu.txt im Temp-Ordner des BS ab.
Hier klappt es.

Ich habe das Brett an der dünnsten Stelle gebohr, benutze ShellExecute mit dem Parameter Korfu.jpg -w! .txt wird Korfu.txt im gleichen Ordner wie das Bild angelegt. Wenn ich einen anderen Pfad wähle, geht es nicht.
Jaenicke, als Amateur bin ich mit ProcessMon überfordert. Die Help.chm funktioniert nicht! Kannst du mir bitte genauer beschreiben, wie ich vorgehen mus. Ich darf nochmal daraufweisen, es hat 5 Jahre lang funktioniert.

Benmik,
es sieht ja so aus, als ob der Umweg über eine externe Datei nicht notwendig ist. Ich hatte Piping in der Eingeauff. erfolgreich getestet aber den Weg über TMemoryStream kenne ich nicht. Es klappt, ich werde ihn in mein Programm einbauen.

Danke und Gruß Willie.

Benmik 15. Dez 2017 15:41

AW: Externes Programm ausführen
 
Ich würde mich freuen, wenn du später hier mal deine Erfahrungen mitteilen würdest, insbesondere, welche Kommandos und Schalter du eingesetzt und getestet hast.

Willie1 17. Dez 2017 09:31

AW: Externes Programm ausführen
 
Hallo Benmik,
das will gerne tun.
Ich habe -lang de ausprobiert. Hier gibt es Probleme mit dem Zeichensatz. Die deutschen Umlaute werden falsch dargestellt. Ich hab's mit OEMToChar und OEMConvert versucht, geht aber nicht. So geht es nicht:
Memo1.Lines.OEMConvert:=true;
CharToOEM(PWideChar(ETout.Text),PAnsiChar(Memo1.Li nes.Text)); Der Rückgabewert ist false
Ich sehe, über dieses Thema gibt es hier schon Beiträge, sie helfen mir aber nicht weiter...

Ich sehe, du hast auch die Starter Edition, es ist ein Elend, dass sich Variablen nicht im Schwebefenster direkt anzeigen lassen!
Willie1.

himitsu 17. Dez 2017 11:19

AW: Externes Programm ausführen
 
Memo1.Lines.Text ist und bleibt immer ein UnicodeString und das kannst/darfst du niemals nach PAnsiChar konvertieren.

Aber natürlich ist dir schon lange die Kompilerwarnung an dieser Stelle aufgefallen.


OEMConvert kannte ich noch nicht, aber wenn ich mir so die Hilfe durchlese, dann würde ich sagen, dass es sich ausschließlich auf das UserInterface, also um die Eingabe des Benutzers handelt und sich Programmintern auf nichts auswirkt.

CharToOEM will auch auf der rechten Seite garantiert eine Variable haben, mit der selben Größe (Length) wie Links, und du gibst da den Zeiger auf die temporäre Ausgabe eines Property rein.

Delphi.Narium 17. Dez 2017 12:22

AW: Externes Programm ausführen
 
Schau bitte mal, ob Du (sinngemäß) hiermit weiter kommst, es stammt aus 'ner alten Delphi 7-Komponente zum Aufruf von Konsolenprogrammen:
Delphi-Quellcode:

function OEM2Ansi(OEMString: string): string;
begin
  OEMString := OEMString + #0;
  OemToChar(PChar(OEMString), @OEMString[1]);
  Delete(OEMString, Length(OEMString), 1);
  Result := OEMString;
end;

...
      repeat
        succeed:=ReadFile(PipeOutputRead,Buffer,szBuffer,BytesRead,nil);
        if not succeed then break;
        // Hier die Funktion einfügen, vor dem Schreiben der Ausgabe in den Stream.
        OemToAnsi(Buffer^,Buffer^);
        Stream.Write(Buffer,BytesRead)
      until (BytesRead=0);
...

himitsu 17. Dez 2017 12:33

AW: Externes Programm ausführen
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1389091)
es stammt aus 'ner alten Delphi 7-Komponente zum Aufruf von Konsolenprogrammen:

Und weil dort mit "falschen" Typen gearbeitet wurde, funktioniert dieser Code seit 2009 nicht mehr, da dort String = UnicodeString und PChar = PWideChar ist.

OEMString hätte schon immer ein AnsiString sein müssen und das knallt nun bei der Unicode-Umstellung seit Delphi 2009.
PS: Delphi-Strings besitzen eine abschließende implizite #0, aber nicht so schlimm ... doppelt hält besser. :stupid:

Delphi.Narium 17. Dez 2017 13:17

AW: Externes Programm ausführen
 
Zitat:

Zitat von himitsu (Beitrag 1389092)
Und weil dort mit "falschen" Typen gearbeitet wurde, funktioniert dieser Code seit 2009 nicht mehr, da dort String = UnicodeString und PChar = PWideChar ist.

Deshalb schrieb ich ja auch sinngemäß. Klar, dass das nicht 1:1 zu übernehmen ist.

Die obige Routine dürfte hierher stammen: Console: OEM nach ANSI. Wurde hier also schon vor über 7 Jahren "falsch" veröffentlicht ;-), aber eventuell läßt sich ja aus dem Thread eine Lösung für das hier diskutierte Problem ableiten.

Willie1 17. Dez 2017 16:00

AW: Externes Programm ausführen
 
Delphi.Narium, das hatte ich hier schon gefunden, es läuft nicht.
Auf -lang de verzichten ist auch keine Lösung, es gibt den Tag City er zeigt z.B. Düsseldorf falsch in Unicode an, doof.

Ich habe es gerade ausprobiert, auf dem Rechner vor dem letzten Windows 10 Update werden Umlate z.B. Düsseldorf korrekt angezeigt.
Die Windows Console ist wohl verändert worden. Was sagt ihr jetzt.

Willie.

Delphi.Narium 17. Dez 2017 16:23

AW: Externes Programm ausführen
 
Was wird denn von ExifTool auf der Kommandozeile für Düsseldorf ausgegeben? Sieht's dort richtig aus. Habe schon Kommandozeilenprogramme erlebt, die nicht den dort üblichen Zeichensatz nutzen, so dass dort Düsseldorf "falsch" ausgegeben wurde. Wenn dem so ist, scheitert auch eine Übersetzung nach Ansi, Unicode ...

Könntest Du bitte mal die Ausgabe von ExifTool auf der Kommandozeile für diesen Problemfall in eine Datei umleiten?
Und dann (ohne eine von Dir vorgenommene Konvertierung) die Ausgabe, die Du in Deinem Programm erhältst?
Und das dann beides hier mal anhängen, eventuell kommen wir damit ja irgendwie weiter.
Wenn Du das entsprechende JPG mir dazulegen könntest, wäre nett, dann könnte man mal schauen, was da "wirklich" dinnesteht, um dem Zeichensatzwirrwarr, der momentan herrscht, mal auf die Sprünge zu kommen.

Willie1 17. Dez 2017 17:50

AW: Externes Programm ausführen
 
Liste der Anhänge anzeigen (Anzahl: 2)
Also, wenn ich K-Dom.txt im Explorer öffne, wird Köln korrekt angezeigt. Ween ich erst Notepad öffne und dann K-Dom.txt öffne, wirden die Umlaute falsch angezeigt. Es geht um den Tag City.
Anbei Bild und Txt-Datei.

P.S Stattdessen ein Bild von der schönen Nachbarstadt.

Delphi.Narium 17. Dez 2017 18:11

AW: Externes Programm ausführen
 
Die Textdatei ist die unveränderte Ausgabe von ExifTool? Dann dürfte das nicht den "DOS-Zeichensatz" benutzen.

Hab' mir mal die aktuelle Fassung geholt. Bei mir sieht es so aus, als wären die Umlaute ... bei der Ausgabe auf der Kommandozeile UTF8.

Wenn man die in eine Datei umgeleitet Ausgabe mit Totalcommander anschaut und dort als Zeichensatz UTF8 wählt, werden die Umlaute korrekt angezeigt.

Willie1 17. Dez 2017 18:38

AW: Externes Programm ausführen
 
Zitat:

Die Textdatei ist die unveränderte Ausgabe von ExifTool? Dann dürfte das nicht den "DOS-Zeichensatz" benutzen.
Ich habe sie eben mit Exiftool K-Dom.jpg -w! .txt in der CMD erzeugt.

Alles weitere später ...

Schönen Abend Willie.

himitsu 17. Dez 2017 19:25

AW: Externes Programm ausführen
 
Dir ist im Öffnen-Dialog des Notpad etwas aufgefallen?

Wenn die Datei per Parameter geöffnet wird, dann läuft eine Automatik über die Datei und erkennt das UTF-8.
Beim manuellen Öffnen mußt du die Standard-Codierung angeben und die steht nunmal auf ANSI, wenn du das nicht änderst.

Problem: Die Datei ist zwar UTF-8, aber ohne explizite Angabe der Codierung -> BOM

Das Selbe gibt übrigens auch für LoadFromFile und den TFileStream -> Standard-Kodierung über den Encoding-Parameter.

Willie1 18. Dez 2017 16:16

AW: Externes Programm ausführen
 
Hallo, ich habe mir Folgendes ausgedacht, es funktioniert zuerst mal. Nach den vielen Pleiten vielleicht ein Fortschritt. In meinem Archiv gefunden.

Delphi-Quellcode:
  function Ex195(const s: string): string;
  var            // Die deutschen Umlaute + ß werden falsch dargestellt (Unicode)
    po: Integer;
    ch: Char;    // Durch Ausprobieren habe ich die Codes herausbekommen
  begin          // erst #195 dann Zeichen ...  - 16-10-2008
    Result:=s;   // Utf8ToAnsi() von Delphi macht genau das
    po:=Pos(#195,Result);
    while (Length(Result) > 0) and (po > 0) do begin
      ch:=Result[Po+1];
      System.Delete(Result,po,2);
      case ch of
        #$84: ch:='Ä';
        #$96: ch:='Ö';
        #$9C: ch:='Ü';
        #$A4: ch:='ä';
        #$B6: ch:='ö';
        #$BC: ch:='ü';
        #$9F: ch:='ß';
        else ch:='.'
      end;
      System.Insert(ch,Result,po);
      po:=Pos(#195,Result,Succ(po))
    end
  end;
Willie.

Benmik 18. Dez 2017 19:04

AW: Externes Programm ausführen
 
In dem von dir angehängten Bild finde ich nicht die Informationen, die du ausgelesen hast. Kannst du mal das Original einstellen oder zumindest eins, in dem alle Informationen erhalten geblieben sind?

PS: Ich denke mal, ich habe die Lösung gefunden, und zwar hier. Beachte mal "Reply #9". Obwohl "UTF8" standardmäßig eingestellt sein soll, muss es mit angegeben werden.
Probiere mal folgende beiden Kommandos:
Delphi-Quellcode:
exiftool.exe -charset IPTC=UTF8 -city=Köln -lang de C:\Temp\K-Dom.jpg
dann
Delphi-Quellcode:
exiftool.exe C:\Temp\K-Dom.jpg -w! .txt
.
Wenn du meine Lösung mit Delphi verwendest, dann musst du
Delphi-Quellcode:
 -charset IPTC=UTF8
nochmal explizit angeben:
Delphi-Quellcode:
exiftool.exe -k -a -u -g1 -lang de -charset IPTC=UTF8  C:\Temp\K-Dom.jpg

Willie1 19. Dez 2017 11:05

AW: Externes Programm ausführen
 
Hallo
-charset IPTC=UTF8 in den Parameter aufnehmen, hilft bei mir nicht!!!
Delphi-Quellcode:
s:=UTF8ToAnsi(ETout.Text);
Damit funktioniert es! Bei Delphi 2005 gab es diese Funktion noch nicht, deshalb mein Eigenkonstrukt, das ebenfalls funktioniert. Warum sollte ich das nicht nutzen. Ich habe die Exiftool-Textdatei vom JPG-Bild mit einem Hexeditor ausgewertet.
Wiellie.

Delphi.Narium 19. Dez 2017 12:30

AW: Externes Programm ausführen
 
Delphi 7 hatte doch UTF8ToAnsi schon in der System.pas. Und bei Delphi 2005 soll das nicht mehr dabei sein?

http://www.delphipraxis.net/41960-ut...vertieren.html


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