代码之家  ›  专栏  ›  技术社区  ›  Streamline

如何诊断原因、修复或处理与adobe activex/com相关的错误0x80004005?

  •  7
  • Streamline  · 技术社区  · 16 年前

    我已经构建了一个c.net应用程序,它使用adobe activex控件来显示pdf。

    它依赖于应用程序附带的几个dll。 这些dll与安装在计算机上的本地Adobe Acrobat或Adobe Acrobat Reader交互。

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

    我发现了3种情况,在尝试加载(加载ActiveX控件时)时,应用程序返回错误消息“error hresult e_fail has returned from a call to a COM component”。

    我已经检查了其中一台用户的机器,他已经安装了Acrobat9,并且经常使用,没有问题。Acrobat 7和Acrobat 8似乎是同时安装的,因为它们与Acrobat 9一起出现在注册表中。

    我不能在本地重现这个问题,所以我不确定该往哪个方向发展。

    stacktrace顶部的错误是:system.runtime.interopservices.comexception(0x80004005):调用COM组件返回错误hresult e_fail。

    对这个错误的一些研究表明这是一个注册表问题。

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

    错误消息的全部内容如下:

    system.runtime.interopservices.comexception(0x80004005):调用COM组件返回错误hresult e_fail。 在system.windows.forms.unsafentiveMethods.coCreateInstance上(guid&clsid、object punkouter、int32 context、guid&iid) 位于system.windows.forms.axhost.createWithOutlineCense(guid clsid) 在system.windows.forms.axhost.createWithLicense上(字符串许可证,guid clsid) 位于system.windows.forms.axhost.createInstanceCore(guid clsid) 位于system.windows.forms.axhost.createInstance() 在system.windows.forms.axhost.getocxcreate() 在system.windows.forms.axhost.transitionUpto(int32状态) 位于system.windows.forms.axhost.createhandle() 在system.windows.forms.control.createcontrol(boolean fignorevible) 在system.windows.forms.control.createcontrol(boolean fignorevible) 位于system.windows.forms.axhost.endinit() 在acrobatchecker.viewer.initializecomponent()上 在AcrobatChecker.viewer..ctor() 在acrobatchecker.form1.btnviewer点击(object sender,eventargs e) 在system.windows.forms.control.onclick(事件参数e) 在system.windows.forms.button.onclick(事件参数e) 在system.windows.forms.button.onmouseup(mouseeventargs mevent) 在system.windows.forms.control.wmmouseup(消息&m,mousebuttons按钮,int32单击) 位于system.windows.forms.control.wndproc(消息&m) 在system.windows.forms.buttonbase.wndproc(消息&m) 位于system.windows.forms.button.wndproc(消息&m) 位于system.windows.forms.control.controlNativeWindow.onMessage(消息&m) 在system.windows.forms.control.controlNativeWindow.wndproc(消息&m) 位于system.windows.forms.nativewindow.callback(intptr hwnd,int32 msg,intptr wparam,intptr lparam)

    3 回复  |  直到 16 年前
        1
  •  11
  •   Streamline    16 年前

    好吧,回去回答我自己的问题。

    该问题与“首选项”>“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
                    }
                }
            }
        }
    

    需要注意的几点:

    是否有人知道这些位置是否在所有版本中都可以互换,或者根据Acrobat的特定版本,注册表项是否在不同的位置?读者和杂技演员遵循同样的逻辑吗?

    • 除了windows文件关联,adobe是否使用其他方法来确定“打开pdf文件的默认adobe应用程序”?我这样问是因为,如果您有一个非Adobe产品,例如作为默认文件关联应用程序安装的Foxit,但是在同时安装了Reader和Acrobat的计算机上使用ActiveX控件for Adobe,则使用什么逻辑来决定COM对象将与哪个应用程序对话?
        2
  •  1
  •   Walter Rohrer    16 年前

    对于我的系统(WindowsXP,AdobeReader9.3.2),你的解决方案没有成功(但是给了我足够的灵感,谢谢!!)

    private void browserIntegration(string defaultPdfProgram)
        {
            try
            {
                RegistryKey reader = null;
                string[] vers = null;
    
                #region Walters Versuch
                reader = Registry.CurrentUser.OpenSubKey("Software").OpenSubKey("Adobe");
                reader = reader.OpenSubKey("Acrobat Reader");
                vers = reader.GetSubKeyNames();
                if (vers.Contains<string>("9.0"))
                {
                    reader = reader.OpenSubKey("9.0");
                    reader = reader.OpenSubKey("Originals", true);
                    if (reader.GetValueNames().Contains<string>("bBrowserIntegration"))
                        reader.SetValue("bBrowserIntegration", 1, RegistryValueKind.DWord);
                    // wenn der Key fehlt ist Browserintegration auch angeschaltet
                    // alternativ: reader.DeleteSubKey("bBrowserIntegration", false);
                }
                else
                    MessageBox.Show(
                        "In case you run into problems later, please make sure yourself to select\n'Show PDF in Browser' in Acrobat Reader's Settings"
                        , "Unknown Version of Acrobat Reader");
    
                #endregion
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + "\n" + ex.StackTrace
                    + "\nIn case you run into problems later, please make sure yourself to select\n'Show PDF in Browser' in Acrobat Reader's Settings"
                    , "Error while switching on 'Browserintegration' in 'Acrobat Reader'");
            }
    }
    
        3
  •  0
  •   Marcello Romani    13 年前

    非常感谢!

    我只想补充一点,我也可以用Adobe Reader Xi来再现行为。 (Windows XP 32位-VB.NET 2005。)

    注册表项是(*):

    HKEY_CURRENT_USER\Software\Adobe\Acrobat Reader\11.0\Originals\bBrowserIntegration
    

    如果该键值为1,则ActiveX组件已正确实例化。如果该键值为0,则在表单实例化时会出现异常。

    我无法在Adobe Reader XI Internet属性页中找到浏览器集成选项。

    (*)我在这一页找到了这个值: http://forums.adobe.com/thread/1042774