如何诊断原因,修复或解决Adobe ActiveX/COM相关错误0x80004005的进度?

Str*_*ine 7 .net c# com dll acrobat

我已经构建了一个C#.NET应用程序,它使用Adobe ActiveX控件来显示PDF.

它依赖于随应用程序一起提供的几个DLL.这些DLL与计算机上安装的本地安装的Adobe Acrobat或Adobe Acrobat Reader交互.

这个应用程序已被一些客户使用,并且几乎适用于所有用户(我检查本地计算机是否至少运行了Acrobat或Reader的版本9).

我发现在尝试加载时(当加载activex控件时)应用程序返回错误消息"错误HRESULT E_FAIL已从调用COM组件返回"的3种情况.

我已经检查了这些用户的其中一台机器,并且安装了Acrobat 9并且经常使用它没有任何问题.看来Acrobat 7和8一次安装,因为它们与Acrobat 9一起在注册表中有条目.

我不能在本地重现这个问题,所以我不确定到底要走哪个方向.

堆栈跟踪顶部的错误是:System.Runtime.InteropServices.COMException(0x80004005):错误HRESULT E_FAIL已从对COM组件的调用返回.

对此错误的一些研究表明它是一个注册表问题.

有没有人知道如何修复或解决这个问题,或者确定如何找到问题的核心根?

错误消息的完整内容如下:

System.Runtime.InteropServices.COMException(0x80004005):错误HRESULT E_FAIL已从对COM组件的调用返回.System.Windows.Forms.AxHost.CreateWithLicense的System.Windows.Forms.AxHost.CreateWithoutLicense(Guid clsid)上的System.Windows.Forms.UnsafeNativeMethods.CoCreateInstance(Guid&clsid,Object punkOuter,Int32 context,Guid&iid)(字符串许可证) System.Windows.Forx.AxHost上的System.Windows.Forms.AxHost.GetOcxCreate()处的System.Windows.Forms.AxHost.CreateInstance()处的System.Windows.Forms.AxHost.CreateInstanceCore(Guid clsid)中的Guid clsid) System.Windows上System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)的System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)上的System.Windows.Forms.AxHost.CreateHandle()处的.TransitionUpTo(Int32状态) .Asms.AxHost.EndInit()在AcrobatChecker.InitializeComponent()AcrobatChecker.Viewer..ctor()在AcrobatChecker.Form1.btnViewer_Click(Object sender,EventArgs e)的System.Windows.Forms.Control.OnClick(EventArgs) e)System.Wind上的System.Windows.Forms.Button.OnClick(EventArgs e)在System.Windows的System.Windows.Forms.Control.WndProc(Message&m)处的System.Windows.Forms.Control.WmMouseUp(Message&m,MouseButtons按钮,Int32单击)处的ows.Forms.Button.OnMouseUp(MouseEventArgs mevent). System.Windows.Fornd.WandProc(Message&m)位于System.Windows.Fornd.Bandton.WndProc(Message&m)的System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message&m)at System.Windows.Forms.Control.ControlNativeWindow. System.Windows.Forms.NativeWindow.Callback的WndProc(Message&m)(IntPtr hWnd,Int32 msg,IntPtr wparam,IntPtr lparam)

Str*_*ine 11

好的,报告回答我自己的问题.

该问题与"首选项">"Internet"中"在浏览器中显示PDF"的设置直接相关.选中此选项后,问题就会消失.当它未经检查时,它会回来.

以下是我们建议以编程方式处理它的方法:

    private string defaultPdfProg()
    { //Returns the default program for opening a .pdf file; On Fail returns empty string. 
      // (see notes below) 
        string retval = "";

        RegistryKey pdfDefault = Registry.ClassesRoot.OpenSubKey(".pdf").OpenSubKey("OpenWithList");
        string[] progs = pdfDefault.GetSubKeyNames();
        if (progs.Length > 0)
        {
            retval = progs[1];
            string[] pieces = retval.Split('.'); // Remove .exe

            if (pieces.Length > 0)
            {
                retval = pieces[0];
            }
        }

        return retval;
    }

    private void browserIntegration(string defaultPdfProgram)
    { //Test if browser integration is enabled for Adobe Acrobat (see notes below)
        RegistryKey reader = null;
        string[] vers = null;

        if (defaultPdfProgram.ToLower() == "acrobat")
        { //Default program is Adobe Acrobat
            reader = Registry.LocalMachine.OpenSubKey("Software").OpenSubKey("Adobe").OpenSubKey("Adobe Acrobat");
            vers = reader.GetSubKeyNames();
        }
        else if (defaultPdfProgram.ToLower() == "acrord32")
        { //Default program is Adobe Acrobat Reader
            reader = Registry.LocalMachine.OpenSubKey("Software").OpenSubKey("Adobe").OpenSubKey("Acrobat Reader");
            vers = reader.GetSubKeyNames();
        }
        else
        {
            //TODO: Handle non - adobe .pdf default program
        }

        if (vers.Length > 0)
        {
            string versNum = vers[vers.Length - 1].ToString();
            reader = reader.OpenSubKey(versNum);
            reader = reader.OpenSubKey("AdobeViewer",true);

            Boolean keyExists = false;
            Double keyValue = -1;
            foreach(string adobeViewerValue in reader.GetValueNames())
            {
                if (adobeViewerValue.Contains("BrowserIntegration"))
                {
                    keyExists = true;
                    keyValue = Double.Parse(reader.GetValue("BrowserIntegration").ToString());
                }
            }

            if (keyExists == false || keyValue < 1)
            {
                string message = "This application requires a setting in Adobe to be changed. Would you like to attempt to change this setting automatically?";
                DialogResult createKey = MessageBox.Show(message, "Adobe Settings", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1);
                if (createKey.ToString() == "OK")
                {
                    reader.SetValue("BrowserIntegration", 1, RegistryValueKind.DWord);
                    //test to make sure registry value was set
                }
                if (createKey.ToString() == "Cancel")
                {
                    //TODO: Provide instructions to manually change setting
                }
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

一些注意事项:

有谁知道这些位置在所有版本中是否可以互换,或者如果基于特定版本的Acrobat,注册表项位于不同的位置?Reader是否遵循与Acrobat相同的逻辑?

  • Adobe是否使用任何其他方法来确定除Windows文件关联之外的"打开PDF文件的默认Adobe应用程序"?我问,因为如果你有一个非adobe产品,比如FoxIt作为默认文件关联应用程序安装,但是在安装了Reader和Acrobat的机器上使用Adobe的ActiveX控件,那么使用什么逻辑来决定哪个应用程序COM对象会跟?