2010-03-26 29 views
7

He creado una aplicación C# .NET que utiliza el control Adobe ActiveX para mostrar un PDF.¿Cómo diagnosticar causa, solución o solucionar el error relacionado con Adobe ActiveX/COM 0x80004005 de forma progmática?

Se basa en un par de archivos DLL que se envían con la aplicación. Estas DLL interactúan con Adobe Acrobat instalado localmente o Adobe Acrobat Reader instalado en la máquina.

Esta aplicación ya está siendo utilizada por algunos clientes y funciona muy bien para casi todos los usuarios (compruebo que la máquina local ya esté funcionando al menos con la versión 9 de Acrobat o Reader).

He encontrado 3 casos donde la aplicación devuelve el mensaje de error "Error HRESULT E_FAIL ha sido devuelto desde una llamada a un componente COM" al intentar cargar (cuando se está cargando el control activex).

He comprobado una de estas máquinas del usuario y tiene instalado Acrobat 9 y lo usa con frecuencia sin problemas. Parece que Acrobat 7 y 8 se instalaron al mismo tiempo ya que hay entradas para ellos en el registro junto con Acrobat 9.

No puedo reproducir este problema localmente, por lo que no estoy seguro exactamente qué dirección tomar .

El error en la parte superior de stacktrace es: System.Runtime.InteropServices.COMException (0x80004005): Error HRESULT E_FAIL ha sido devuelto por una llamada a un componente COM.

Algunas investigaciones sobre este error indican que se trata de un problema de registro.

¿Alguien tiene una idea de cómo solucionar o solucionar este problema o determinar cómo llegar al origen del problema?

El contenido completo del mensaje de error es la siguiente:

System.Runtime.InteropServices.COMException (0x80004005): Error HRESULT E_FAIL ha sido devuelto de una llamada a un componente COM. en System.Windows.Forms.UnsafeNativeMethods.CoCreateInstance (Guid & clsid, de objetos punkOuter, el contexto Int32, Guid & iid) en System.Windows.Forms.AxHost.CreateWithoutLicense (Guid clsid) en System.Windows.Forms.AxHost .CreateWithLicense (licencia de cuerdas, Guid idcls) en System.Windows.Forms.AxHost.CreateInstanceCore (Guid idcls) en System.Windows.Forms.AxHost.CreateInstance() en System.Windows.Forms.AxHost.GetOcxCreate() en System.Windows.Forms.AxHost.TransitionUpTo (estado de Int32) en System.Windows.Forms.AxHost.CreateHandle() en System.Windows.Forms.Control.CreateControl (boolean fIgnoreVisible) en System.Windows.Forms.Control.CreateControl (Boolean fIgnoreVisible) en System.Windows.Forms.AxHost.EndInit() en AcrobatChecker.Viewer.InitializeComponent() en AcrobatChecker.Viewer..ctor() en AcrobatChecker .Form1.btnViewer_Click (Object Sender, EventArgs e) en System.Windows.Forms.Control.OnClick (EventArgs e) en System.Windows.Forms.Button.OnClick (EventArgs e) en System.Windows.Forms.Button .OnMouseUp (MouseEventArgs mevent) en System.Windows.Forms.Control.WmMouseUp (Mensaje & m, botón MouseButtons, clics Int32) en System.Windows.Forms.Control.WndProc (Mensaje & m) en System.Windows.Forms.ButtonBase.WndProc (Mensaje & m) en System.Windows.Forms.Button.WndProc (Mensaje & m) en System.Windows.Forms.Control.ControlNativeWindow. OnMessage (Mensaje & m) en System.Windows.Forms.Control.ControlNativeWindow.WndProc (Mensaje & m) en System.Windows.Forms.NativeWindow.Callback (IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

+0

Podría ser cuestión de 32 bits/64 bits, que el sistema operativo es de 64 bits, mientras que los de Adobe DLL son de 32 bits. –

+0

"Algunas investigaciones sobre este error indican que es un problema de registro". Prueba esa hipótesis Obtenga RegMon, o ProcMon o lo que sea que estén llamando esa cosa hoy en día y vea si los accesos al registro son los que espera que se den si alguien está intentando crear un objeto COM. –

+0

No estoy familiarizado con cómo hacer lo que está sugiriendo ... ¿Cómo veo si los accesos de registro son como esperaría que alguien intente crear un objeto COM? una vez que ejecuta ProcMon o similar? - Me gustaría averiguarlo antes de intentarlo en la máquina del usuario, ya que tengo acceso limitado a su máquina. – Streamline

Respuesta

11

Ok, respondiendo para responder mi propia pregunta.

El problema estaba directamente relacionado con la configuración de 'Mostrar PDF en el navegador' en Preferencias> Internet. Con esta opción marcada, el problema desaparece. Cuando no está marcado, regresa.

Aquí es cómo nos proponemos manejarlo mediante programación:

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

Algunos elementos a tener en cuenta:

¿Alguien sabe si estas ubicaciones son intercambiables en todas las versiones o si, según las versiones específicas de Acrobat, la clave de registro se encuentra en diferentes ubicaciones? ¿Sigue Reader la misma lógica que Acrobat?

  • ¿Adobe utiliza algún otro método para determinar la 'aplicación predeterminada de Adobe para abrir archivos PDF' que no sea la asociación de archivos de Windows? Pregunto porque si tiene un producto que no es Adobe, como FoxIt instalado como la aplicación de asociación de archivos predeterminada, pero está usando el control ActiveX para Adobe en una máquina que tiene instalados tanto Reader como Acrobat, qué lógica se usa para decidir qué aplicación el objeto COM hablará con?
+0

También vale la pena señalar que si se instala Adobe Pro, la opción es deshabilitado en Adobe Reader, y debe estar habilitado desde Adobe Pro. – Kye

+0

Gracias Señor, esto me ahorró muchos problemas. – Golvellius

+0

Actualizando esto 5 años después ahora con una referencia a una nueva pregunta que publiqué aquí http: // stackoverflow.com/questions/31255483/how-to-programmatically-enable-disable-display-pdf-in-browser-for-acrobat-r porque la solución que publiqué aquí hace 5 años no está funcionando como se esperaba en XI o DC. La clave bBrowserIntegration parece estar obsoleta en 11. ¿Alguien sabe el XI (11) o el equivalente de DC de mi solución anterior (codificada, no manual)? – Streamline

1

Para mi sistema (Windows XP, Adobe Reader 9.3.2) su solución no funcionó (pero me dio la inspiración suficiente, GRACIAS !!)

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'"); 
     } 
} 
0

Muchas gracias!

Solo quiero agregar que soy capaz de reproducir el comportamiento con Adobe Reader XI también. (Windows XP 32 bits - VB.net 2005)

La clave de registro es (*):

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

Si ese valor clave es 1, el componente ActiveX se crea una instancia correctamente. Si ese valor de clave es 0, obtengo la excepción en la creación de instancias de formularios.

No he podido encontrar la opción de integración del navegador en la página de propiedades de Internet de Adobe Reader XI.

(*) He encontrado que el valor de esta página: http://forums.adobe.com/thread/1042774

Cuestiones relacionadas