gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-03 18:48:02 27 4
gpt4 key购买 nike

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

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

我收到一个 COMException 消息:

Creating an instance of the COM component with CLSID {CA8A9780-280D-11CF-A24D-444553540000} from the IClassFactory failed due to the following error: 80004005.

我已经引用了 AcroPDF.dll,它的组件名称是 Adobe Acrobat 7.0 Browser Control Type Library 1.0

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

Unable to cast COM object of type 'AcroPDFLib.AcroPDFClass' to interface type 'AcroPDFLib.IAcroAXDocShim'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{3B813CE7-7C10-4F84-AD06-9DF76D97A9AA}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).

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

acrobat.LoadFile("book.pdf");

我不知道哪里出了问题。帮助最感激!

最佳答案

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

尝试实现 IMessageFilter界面。这将使 COM 了解如何将消息传递回您的应用程序。特别是,实现 RetryRejectedCall并检查失败标志是否可能返回超时值(大约 1000 毫秒)以允许 COM 在短暂暂停后重试。

它是一个 COM 类型,所以这是定义接口(interface)所需的代码:

[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 signiture is :

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

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

[请注意,我在这里指的 IMessageFilter 不同于 System.Windows.Forms.IMessageFilter ,因此请确保您不会不小心使用 winforms。]

关于c# - 无法使用 COM 和 .NET 互操作从 AcroPDF.dll 实例化 PDF 浏览器控件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2702164/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com