How to diagnose cause, fix, or work around Adobe ActiveX / COM related error 0x80004005 progmatically?

删除回忆录丶 提交于 2019-12-20 23:26:52

问题


I've built a C# .NET app that uses the Adobe ActiveX control to display a PDF.

It relies on a couple DLLs that get shipped with the application. These DLLs interact with the locally installed Adobe Acrobat or Adobe Acrobat Reader installed on the machine.

This app is being used by some customer already and works great for nearly all users ( I check to see that the local machine is running at least version 9 of either Acrobat or Reader already ).

I've found 3 cases where the app returns the error message "Error HRESULT E_FAIL has been returned from a call to a COM component" when trying to load (when the activex control is loading).

I've checked one of these user's machines and he has Acrobat 9 installed and is using it frequently with no problems. It does appear that Acrobat 7 and 8 were installed at one time since there are entries for them in the registry along with Acrobat 9.

I can't reproduce this problem locally, so I am not sure exactly which direction to go.

The error at the top of the stacktrace is: System.Runtime.InteropServices.COMException (0x80004005): Error HRESULT E_FAIL has been returned from a call to a COM component.

Some research into this error indicates it is a registry problem.

Does anyone have a clue as to how to fix or work around this problem, or determine how to get to the core root of the problem?

The full content of the error message is this:

System.Runtime.InteropServices.COMException (0x80004005): Error HRESULT E_FAIL has been returned from a call to a COM component.    at System.Windows.Forms.UnsafeNativeMethods.CoCreateInstance(Guid& clsid, Object punkOuter, Int32 context, Guid& iid)    at System.Windows.Forms.AxHost.CreateWithoutLicense(Guid clsid)    at System.Windows.Forms.AxHost.CreateWithLicense(String license, Guid clsid)    at System.Windows.Forms.AxHost.CreateInstanceCore(Guid clsid)    at System.Windows.Forms.AxHost.CreateInstance()    at System.Windows.Forms.AxHost.GetOcxCreate()    at System.Windows.Forms.AxHost.TransitionUpTo(Int32 state)    at System.Windows.Forms.AxHost.CreateHandle()    at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)    at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)    at System.Windows.Forms.AxHost.EndInit()    at AcrobatChecker.Viewer.InitializeComponent()    at AcrobatChecker.Viewer..ctor()    at AcrobatChecker.Form1.btnViewer_Click(Object sender, EventArgs e)    at System.Windows.Forms.Control.OnClick(EventArgs e)    at System.Windows.Forms.Button.OnClick(EventArgs e)    at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)    at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)    at System.Windows.Forms.Control.WndProc(Message& m)    at System.Windows.Forms.ButtonBase.WndProc(Message& m)    at System.Windows.Forms.Button.WndProc(Message& m)    at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)    at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)    at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)


回答1:


Ok, reporting back to answer my own question.

The problem was directly related to the setting for 'Display PDF in browser' in Preferences > Internet. With this option checked, the problem goes away. When it is unchecked, it comes back.

Here is how we propose to handle it programmatically:

    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
                }
            }
        }
    }

A few items to note:

  • It appears according to these two articles, the key can be in two different locations in the registry (Originals vs AdobeViewer) : http://support.adobe.com/devsup/devsup.nsf/docs/51722.htm http://support.adobe.com/devsup/devsup.nsf/docs/53556.htm

Does anyone know if these locations are interchangeable in all versions or if based on specific versions of Acrobat the registry key is in different locations? Does Reader follow the same logic as Acrobat?

  • Does Adobe use any other method to determine the 'default Adobe application for opening PDF files' other than the windows file association? I ask because if you have a non-adobe product, such as FoxIt installed as the default file association application, but are using the ActiveX control for Adobe on a machine that has both Reader and Acrobat installed, what logic is used to decide which application the COM object will talk to?



回答2:


For my system (Windows XP, Adobe Reader 9.3.2) your solution didn't work (but gave me enough inspiration, THANK YOU!!)

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:


Thank you so much!

I just want to add that I am able to reproduce the behaviour with Adobe Reader XI too. (Windows XP 32 bit - VB.net 2005.)

The registry key is(*):

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

If that key value is 1, the activex component is correctly instantiated. If that key value is 0, I get the exception at form instantiation.

I was not able to find the browser integration option in Adobe Reader XI Internet properties page.

(*) I found that value on this page: http://forums.adobe.com/thread/1042774



来源:https://stackoverflow.com/questions/2526301/how-to-diagnose-cause-fix-or-work-around-adobe-activex-com-related-error-0x8

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!