C# 无法使用COM和.NET互操作从AcroPDF.dll实例化PDF浏览器控件

C# 无法使用COM和.NET互操作从AcroPDF.dll实例化PDF浏览器控件,c#,com,interop,activex,acrobat,C#,Com,Interop,Activex,Acrobat,当我尝试在C#中实例化PDF浏览器控件时: 我收到一条带有此消息的COMException: 由于以下错误,从IClassFactory创建CLSID为{CA8A9780-280D-11CF-A24D-444553540000}的COM组件实例失败:80004005 我参考了AcroPDF.dll,它的组件名为Adobe Acrobat 7.0浏览器控件类型库1.0 当我以管理员身份运行Visual C#2008 Express Edition时,我收到另一条错误消息: 无法将类型为“AcroP

当我尝试在C#中实例化PDF浏览器控件时:

我收到一条带有此消息的
COMException

由于以下错误,从IClassFactory创建CLSID为{CA8A9780-280D-11CF-A24D-444553540000}的COM组件实例失败:80004005

我参考了AcroPDF.dll,它的组件名为Adobe Acrobat 7.0浏览器控件类型库1.0

当我以管理员身份运行Visual C#2008 Express Edition时,我收到另一条错误消息:

无法将类型为“AcroPDFLib.AcroPDFClass”的COM对象强制转换为接口类型“AcroPDFLib.IAcroAXDocShim”。此操作失败,因为对IID为“{3B813CE7-7C10-4F84-AD06-9DF76D97A9AA}”的接口的COM组件的QueryInterface调用失败,原因是以下错误:不支持此类接口(HRESULT的异常:0x80004002(E_NOINTERFACE))

当我尝试使用该对象时,会在下一行发生这种情况:

acrobat.LoadFile("book.pdf");

我想不出是怎么回事。非常感谢您的帮助

.net COM互操作不会将所有COM消息直接路由回调用方。如果您从STA呼叫COM,它将无法理解您的应用程序如何处理重新进入。这意味着可以通过重试来处理的失败消息最终会导致异常

尝试实现接口。这将使COM了解如何将消息传递回您的应用程序。特别是,实现并检查是否有故障标志,并可能返回超时值(类似于1000ms),以允许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;
    }
}
一旦您实现了一个消息过滤器,您将需要使用注册它。这是一个每线程注册,所以要知道你在哪个线程上调用它。委员会:

即使这不起作用,至少,如果你把所有的消息都记录在过滤器中,你应该有希望得到更多关于出错原因的信息。查看传递到消息筛选器的参数值。如果您查找它们,它们将与错误/状态代码相关


[请注意,我这里指的IMessageFilter与不同,因此请确保您不会意外使用winforms one。]

.net COM interop不会将所有COM消息直接路由回调用方。如果您从STA呼叫COM,它将无法理解您的应用程序如何处理重新进入。这意味着可以通过重试来处理的失败消息最终会导致异常

尝试实现接口。这将使COM了解如何将消息传递回您的应用程序。特别是,实现并检查是否有故障标志,并可能返回超时值(类似于1000ms),以允许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;
    }
}
一旦您实现了一个消息过滤器,您将需要使用注册它。这是一个每线程注册,所以要知道你在哪个线程上调用它。委员会:

即使这不起作用,至少,如果你把所有的消息都记录在过滤器中,你应该有希望得到更多关于出错原因的信息。查看传递到消息筛选器的参数值。如果您查找它们,它们将与错误/状态代码相关


[请注意,我这里指的IMessageFilter与不同,因此请确保您不会意外使用winforms one。]

以下是使用Adobe PDF Reader控件的步骤:

  • 创建新的Windows窗体应用程序:文件→ 新项目…→ Windows窗体应用程序→ 嗯
  • 添加对Adobe Acrobat 7.0浏览器控件类型库1.0:项目的引用→ 添加引用…→ 组件对象模型→ Adobe Acrobat 7.0浏览器控件类型库1.0→ 嗯
  • 将Adobe PDF Reader控件添加到工具箱:工具→ 选择工具箱项…→ COM组件→ AdobePDF阅读器→ 嗯
  • 将Adobe PDF Reader控件从工具箱拖动到表单中
  • 我不知道为什么,但我必须以管理权限运行Microsoft Visual C#2008 Express Edition才能正常工作。对于有限的用户,我在designer中收到以下消息:

    调用COM组件时返回错误HRESULT E_FAIL

    请注意,将Adobe PDF Reader控件添加到工具箱后,将创建一个名为AxInterop.AcroPDFLib.dll的新.NET互操作程序集。已将对此新程序集的引用添加到项目引用中

    Adobe PDF Reader控件的API参考文档位于以下位置:


    此论坛线程提供了一些更有用的信息:

    以下是使用Adobe PDF Reader控件的步骤:

  • 创建新的Windows窗体应用程序:文件→ 新项目…→ Windows窗体应用程序→ 嗯
  • 添加对Adobe Acrobat 7.0浏览器控件类型库1.0:项目的引用→ 添加引用…→ 组件对象模型→ Adobe Acrobat 7.0浏览器控件类型库1.0→ 嗯
  • 将Adobe PDF Reader控件添加到工具箱:工具→ 选择工具箱项…→ COM组件→ AdobePDF阅读器→ 嗯
  • 将Adobe PDF Reader控件从工具箱拖动到表单中
  • 我不知道为什么,但我必须以管理权限运行Microsoft Visual C#2008 Express Edition才能正常工作。对于有限的用户,我在designer中收到以下消息:

    调用COM组件时返回错误HRESULT E_FAIL

    请注意,将Adobe PDF Reader控件添加到工具箱后,将创建一个名为AxInterop.AcroPDFLib.dll的新.NET互操作程序集。此新程序集的引用已被删除