I am trying to dump a PDF to text using a command line utility (It works with tests from dos command line) from my Delphi code.
Here is my code
if fileexists(ExtractFilePath(Application.ExeName) + 'pdftotext.exe') then
begin
ShellExecute(H,'open', 'pdftotext.exe', PWideChar(fFileName), nil, SW_SHOWNORMAL);
if fileExists开发者_C百科(changeFileExt(fFileName, '.txt')) then
Lines.LoadFromFile(changeFileExt(fFileName, '.txt'))
else
ShowMessage('File Not found');
end;
When placing breakpoints in code and stepping through, it makes it to the
if fileExists(changeFileExt(fFileName, '.txt')) then
line but returns false, so the Shellexecute was called but no file was ever dumped
What have I done wrong?
ShellExecute
doesn't wait for the invoked program to finish running. You're probably checking for the file too soon. The file simply hasn't been created yet.
Run the program and wait for it to terminate before you check for the output file. ShellExecute
doesn't return enough information for you to do that, so you should try CreateProcess
instead. There are several examples of how to do that. Try this:
How can I wait for a command-line program to finish?
It turns out, that adding the fill path to the execuatble made it work just fine
uses
Forms, ShellAPI, SysConst, SysUtils;
procedure Pdf2Text(const fFileName: string; const Lines: TStrings);
var
H: HWND;
PdfToTextPathName: string;
ReturnValue: Integer;
TxtFileName: string;
begin
H := 0;
PdfToTextPathName := ExtractFilePath(Application.ExeName) + 'pdftotext.exe'; // full path
if FileExists(PdfToTextPathName) then
begin
ReturnValue := ShellExecute(0,'open', PWideChar(PdfToTextPathName), PWideChar(fFileName), nil, SW_SHOWNORMAL);
if ReturnValue <= 32 then
RaiseLastOsError();
// note: the code below this line will crash when pdftotext.exe does not finish soon enough; you should actually wait for pdftotext.exe completion
TxtFileName := ChangeFileExt(fFileName, '.txt');
if FileExists(TxtFileName) then
Lines.LoadFromFile(TxtFileName)
else
raise EFileNotFoundException.CreateRes(@SFileNotFound);
end;
end;
Edit: Some code cleanup helps big time to catch errors early on, especially when testing a proof of concept.
精彩评论