Einzelnen Beitrag anzeigen

Benmik

Registriert seit: 11. Apr 2009
542 Beiträge
 
Delphi 11 Alexandria
 
#16

AW: Externes Programm ausführen

  Alt 12. Dez 2017, 20:56
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 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
Angehängte Dateien
Dateityp: pas EXIFTool.pas (3,2 KB, 15x aufgerufen)

Geändert von Benmik (12. Dez 2017 um 22:21 Uhr) Grund: Erst nachsehen, dann posten
  Mit Zitat antworten Zitat