1

C# で次のような PDF ブラウザー コントロールをインスタンス化しようとすると、次のようになります。

AcroPDFLib.AcroPDFClass acrobat = new AcroPDFLib.AcroPDFClass();

次のCOMExceptionメッセージが表示されます。

IClassFactory からの CLSID {CA8A9780-280D-11CF-A24D-444553540000} を持つ COM コンポーネントのインスタンスの作成は、次のエラーのために失敗しました: 80004005。

コンポーネント名Adob​​e Acrobat 7.0 Browser Control Type Library 1.0を持つAcroPDF.dllを参照しました。

管理者として Visual C# 2008 Express Edition を実行すると、別のエラー メッセージが表示されます。

タイプ 'AcroPDFLib.AcroPDFClass' の COM オブジェクトをインターフェイス タイプ 'AcroPDFLib.IAcroAXDocShim' にキャストできません。IID '{3B813CE7-7C10-4F84-AD06-9DF76D97A9AA}' を持つインターフェイスの COM コンポーネントでの QueryInterface 呼び出しが、次のエラーにより失敗したため、この操作は失敗しました: No such interface supported (HRESULT からの例外: 0x80004002 (E_NOINTERFACE)) .

これは、オブジェクトを使用しようとすると、次の行で発生します。

acrobat.LoadFile("book.pdf");

何が悪いのかわかりません。最も感謝ヘルプ!

4

2 に答える 2

4

.net COM 相互運用では、すべての COM メッセージが呼び出し元に直接ルーティングされるわけではありません。STA から COM を呼び出した場合、アプリが再入を処理する方法を理解できません。これは、再試行で処理できた失敗メッセージが例外を引き起こすことを意味します。

IMessageFilterインターフェイスを実装してみてください。これにより、COM はアプリにメッセージを返す方法を理解できるようになります。特に、RetryRejectedCallを実装し、失敗フラグがあるかどうかを確認し、場合によってはタイムアウト値 (1000 ミリ秒など) を返して、COM が短い一時停止の後に再試行できるようにします。

これは COM 型なので、インターフェイスを定義するために必要なコードは次のとおりです。

[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("00000016-0000-0000-C000-000000000046")]
public interface IMessageFilter
{
    [PreserveSig]
    int HandleInComingCall(int dwCallType, IntPtr hTaskCaller, int dwTickCount, IntPtr lpInterfaceInfo);

    [PreserveSig]
    int RetryRejectedCall(IntPtr hTaskCallee, int dwTickCount, int dwRejectType);

    [PreserveSig]
    int MessagePending(IntPtr hTaskCallee, int dwTickCount, int dwPendingType);
}

これを実装する方法の例を次に示します。

public class MyMessageFilter : IMessageFilter
{
    int IMessageFilter.HandleInComingCall(int dwCallType, IntPtr hTaskCaller,int dwTickCount, IntPtr lpInterfaceInfo)
    {
        // 0 means that it's handled.
        return 0;
    }

    int IMessageFilter.RetryRejectedCall(IntPtr hTaskCallee, int dwTickCount, int dwRejectType)
    {
        // The return value is the delay (in ms) before retrying.
        return 1000;
    }

    int IMessageFilter.MessagePending(IntPtr hTaskCallee, int dwTickCount, int dwPendingType)
    {
        // 1 hear means that the message is still not processed and to just continue waiting.
        return 1;
    }
}

メッセージ フィルタを実装したら、CoRegisterMessageFilterを使用して登録する必要があります。これはスレッドごとの登録であるため、呼び出しているスレッドに注意してください。PInvoke 署名は次のとおりです。

[DllImport("ole32.dll")]
static extern int CoRegisterMessageFilter(IMessageFilter lpMessageFilter, out IMessageFilter lplpMessageFilter);

これが機能しない場合でも、少なくとも、フィルタ内のすべてのメッセージをログに記録すれば、問題の原因に関する詳細情報を取得できるはずです。メッセージ フィルタに渡されるパラメータの値を確認します。それらを調べると、エラー/状態コードに関連しています。

[ここで言及している IMessageFilter はSystem.Windows.Forms.IMessageFilterとは異なるため、誤って winforms のものを使用しないように注意してください。]

于 2010-04-23T22:02:32.013 に答える
3

Adobe PDF Reader コントロールを使用する手順は次のとおりです。

  1. 新しい Windows フォーム アプリケーションを作成します: [ファイル] → [新しいプロジェクト…] → [Windows フォーム アプリケーション] → [OK ]
  2. Adobe Acrobat 7.0 Browser Control Type Library 1.0 への参照を追加: Project → Add Reference… → COM → Adob​​e Acrobat 7.0 Browser Control Type Library 1.0 → OK
  3. Adobe PDF Reader コントロールをツールボックスに追加します:ツール → ツールボックス項目の選択… → COM コンポーネント → Adob​​e PDF Reader → OK
  4. Adobe PDF Reader コントロールをツールボックスからフォームにドラッグします

理由はわかりませんが、これを機能させるには、Microsoft Visual C# 2008 Express Edition を管理者権限で実行する必要があります。限られたユーザーの場合、デザイナーで次のメッセージが表示されます。

COM コンポーネントへの呼び出しからエラー HRESULT E_FAIL が返されました。

Adobe PDF Reader コントロールをツールボックスに追加した後、新しい .NET 相互運用アセンブリがAxInterop.AcroPDFLib.dllという名前で作成されていることに注意してください。この新しいアセンブリへの参照がプロジェクト参照に追加されました。

Adobe PDF Reader コントロールの API リファレンス ドキュメントは、http: //icio.us/ajukkrにあります。

このフォーラム スレッドでは、さらに役立つ情報が提供されています: http://forums.adobe.com/thread/438362

于 2010-04-24T13:49:45.710 に答える