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.