viernes, 18 de junio de 2010

Usa las interfaces… que para eso están!

Ole! Vaya título tan imperativo me ha salido, eh??? Un post cortito para comentar un problemilla que hemos tenido en casa de un cliente, y que al final era debido por no usar interfaces (en nuestro caso interfaces COM).

El problemilla…

En todos los ordenadores de desarrollo el sistema funcionaba perfectamente (como siempre… en mi máquina funciona!).

En los ordenadores de prueba el sistema daba error, concretamente se quejaba que no encontraba el ensamblado mshtml.dll. Nosotros usábamos una referencia contra el ensamblado PIA que está en “%PROGRAMFILES%\Microsoft.NET\Primary Interop Assemblies” y que se llama Microsoft.mshtml.dll.

Vimos que efectivamente dicho ensamblado no se distribuía junto con nuestro proyecto y que no estaba en la GAC de los ordenadores, así que cambiamos la referencia para que fuese con Copy Local=true. Ahora sí que aparecia el ensamblado: Microsoft.mshtml.dll.

Desplegando esta versión de Microsoft.mshtml.dll el sistema… seguía sin funcionar. Pero ahora ya no daba errores de carga de assemblies ni de validaciones falladas de strong name, sino que daba una excepción:

Unable to cast COM object of type 'System.__ComObject' to class type 'mshtml.HTMLDocumentClass'. COM components that enter the CLR and do not support IProvideClassInfo or that do not have any interop assembly registered will be wrapped in the __ComObject type. Instances of this type cannot be cast to any other class; however they can be cast to interfaces as long as the underlying COM component supports QueryInterface calls for the IID of the interface.

El código que daba el error era el siguiente:

var mainDocument = (mshtml.HTMLDocumentClass)webBrowserControl.Document.DomDocument;





La solución



Bueno… Lo primero que pensamos era que alguna diferencia de versión de internet explorer podía causar eso, pero descartamos el tema: aunque es cierto que había distintas versiones (aunque todos los ordenadores tenían la 6(*), no todos tenían las mismas actualizaciones) había un ordenador de desarrollo que tenía la 8… Si compilábamos en dicho ordenador podíamos ejecutar el programa en otros ordenadores de desarrollo que tuvieran la 6. Estaba claro que interet explorer no era el problema.



Entonces? Bueno… si habéis leído el título del post ya sabréis la causa: estábamos utilizando directamente las clases COM (P.ej. HTMLDocumentClass) en lugar de usar la interfaz (p.ej. IHTMLDocument2). Cambiando el código por el siguiente:




var mainDocument = (mshtml.IHTMLDocument2)webBrowserControl.Document.DomDocument;





Todo funcionó a la perfección!



¿Conclusion? Pues eso… usad las interfaces (COM) que para eso están! :)



Un saludo!!!!



(*) Sí, sí, sí… Internet Explorer 6 ya no está suportado por MS, es más viejo que matusalén, tienes más agujeros de seguridad que un queso gruyere pero… en muchos sitios sigue formando parte de la plataforma corporativa.



PD: Esto es un crosspost de mi blog en geeks.ms. Pásate mejor por allí, hombre!!! ;-)

No hay comentarios: