2011-01-07 8 views
-2

私はDelphiコードからコマンドラインユーティリティ(これはdosコマンドラインのテストで動作します)を使用してテキストにPDFをダンプしようとしています。ここで ShellExecuteを使用すると、私の期待どおりのコマンドが実行されないのはなぜですか?

は私のコード

if fileexists(ExtractFilePath(Application.ExeName) + 'pdftotext.exe') then 
begin 
    ShellExecute(H,'open', 'pdftotext.exe', PWideChar(fFileName), nil, SW_SHOWNORMAL); 
    if fileExists(changeFileExt(fFileName, '.txt')) then 
    Lines.LoadFromFile(changeFileExt(fFileName, '.txt')) 
    else 
    ShowMessage('File Not found'); 
end; 
ある コードにブレークポイントを配置してステッピングすると、それは

if fileExists(changeFileExt(fFileName, '.txt')) then 

ラインにしますが、falseを返し、そうのShellExecuteは呼ばれていましたが、何のファイルがなかった

これまでにダンプされた

どうしたのですか?

+0

申し訳ありませんが、最後の最後は必要ありませんでした。他の場所からコードをカットアンドペーストしていました。 fFileNameは、プロシージャ内で定義された文字列変数です – IElite

+2

あなた自身のために、コードを適切にフォーマットする必要があります(一貫したインデントを使用して)。そして、エンドユーザのために、「File Not found」はひどいエラーメッセージです(「File not found」もあります)。 –

+0

THanksですが、これは現在の実験的なコーディングであり、何かの成果物とはかけ離れています。 showMessageは、私がwhtherをテストするために使っていたもので、ファイルが見つかりませんでした – IElite

答えて

1

それはexecuatbleにフィルパスを追加すると、それだけで罰金

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; 

編集作業作られていること、判明:キャッチする大きな時間に役立ついくつかのコードのクリーンアップをエラーの早期発見、特に概念実証のテストに役立ちます。

+0

書式を指定してコードを投稿してください。 –

+3

ここで学ぶべき教訓は次のとおりです。** API関数の戻り値を無視しないでください。**以前に結果を確認した場合は、Error_File_Not_Foundを返すことになります。これは、 'ShellExecute'が実行を依頼したファイルを見つけられなかった理由を説明します。 –

+1

もう一つのレッスン:**現在の作業ディレクトリをあなたが思っているものと仮定しないでください** Shaneは、OSが* pdftotext.exe *がどこにあるか知っていると仮定しました。完全修飾パスがなければ、OSは 'PATH'環境変数を使用してプログラムを探します。これには現在のプログラムの作業ディレクトリが含まれます。多くの場合、現在のEXEが存在するディレクトリになりますが、それは変更される可能性があります。目的のプログラムがどこにあるのか分かっている場合は、答えがそうであるように具体的にその場所を尋ねます。 –

7

ShellExecuteは、呼び出されたプログラムの実行が完了するまで待機しません。あなたはおそらくあまりにも早くファイルをチェックしているでしょう。ファイルはまだ作成されていません。

出力ファイルを確認する前に、プログラムを実行して終了するまで待ちます。 ShellExecuteはそれを行うのに十分な情報を返していないので、代わりにCreateProcessを試してください。それを行う方法のいくつかの例があります。これを試してみてください:

How can I wait for a command-line program to finish?

+0

+1。これはそうだ。 (しかし、OPはWindowsエクスプローラを使ってこの問題を非常に簡単に実現できたかもしれません...) –

+1

またはShellExecuteEX(http://msdn.microsoft.com/en-us/library/bb762154%28v=vs.85%あなたがWaitForSingleObject()を使用できるように、新しいプロセスのプロセスIDを提供します。 –

+0

@ Andreas - あなたはいつも重要ですか?あなたは本当にすべてがあなたのように賢明であると信じますか?そして、これらのことを理解できるはずですか?そうであれば、今そこにはこのサイトの理由はありません。人生を手に入れよう! – IElite

関連する問題