My kemenworld…

To mock or not to mock…

Windows Vista Preview Handlers

Posted by kementeus en agosto 3, 2007

Uff, hace ratos que no escribía. Bueno, en realidad ya he escrito varias cosas pero por n o y razón nunca las publiqué, quizás más adelante😛. Y entre tantas cosas como levantar la empresa, proyectos nuevos y mudanza (yep, me mudé) no me quedó tanto tiempo como para escribir una nota nueva.

Desde hace un par de meses estoy suscrito a una de las que personalmente considero de las mejores revistas de índole técnico para el programador de .Net y Windows en general, se trata de la MSDN Magazine, una de las primeras ediciones que leí traía un artículo sobre algo llamado Vista Preview Handlers. Trataré de forma breve de explicar el funcionamiento de los preview handlers en Windows Vista usando un pequeño y simple ejemplo.

Quienes tienen Office 2007 se habrán dado cuenta de una de las mejoras agregadas en el panel de lectura de Outlook es la posibilidad de hechar un vistazo previo a ciertos documentos que se envian en forma de attachments, por ejemplo, si se envia un documento de word podríamos observar el contenido del documento (con formatos y todo) sin necesidad de abrir Word.

Esto se logra através de una nueva adición a la API de Windows llamada la Preview Handler Framework, se trata de un conjunto de interfaces COM+ que en conjunto crean una framework para la previsualización de documentos. Lo más importante, no solamente estan presentes en Office Outlook 2007, también se incluyen en la shell de Windows en general (Explorer) y debido a que en la shell se trata de un proceso host aparte (prevhost.exe) puede ser incluída en otras aplicaciones en el futuro muy próximo.

La Preview Handler Framework nativa viene incluída en Windows Vista por default y en Microsoft Office 2007. Eso involucra que podríamos diseñar preview handlers que pudieran funcionar normalmente en Windows Vista y Windows XP (claro, Windows 2003 server también). Como mencioné esta framework la componen un conjunto de interfaces COM, claro que podemos usar Interop Services para lograr implementar nuestro preview handler en .Net y así evitarnos la divertida parte de programarlo usando COM (no me lean así, trabajar en COM puede ser divertido).

Bien, la cuestion es que alguien se apiadó de nosotros y leyendo la MSDN Magazine del mes de enero me topo con un artículo muy bueno de Stephen Toub (http://msdn.microsoft.com/msdnmag/issues/07/01/PreviewHandlers/default.aspx) sobre su Framework en .Net que hace un “wrapping” de las interfaces COM+ para fabricar Preview Handlers en .Net 2.0, un artículo excelente que vale la pena leer. Revisando en internet me topo con que muchas personas han hecho sus implementaciones basada en la framework de Toub, un ejemplo es la del PSD Preview Handler encontrada en The Code Project (http://www.codeproject.com/vista/PhotoshopPreviewHandler.asp) pero me topo con que muchos usaban la Framework de Toub indiscriminadamente, o sea, tomaban en cuenta que ya estaba instalada y preparada en el computador host y claro, Toub la pensó con fines educativos, es por eso que se incluye en la misma framework preview handlers incluídos para archivos como texto, PDF, Zip y algunos otros.

Le escribí a este señor Toub diciendole que habia simplificado un poco su framework, en realidad lo unico que hice fue separar en assemblies la framework como tal y en otro set de assemblies los ejemplos que envía en su framework, y sobre el assembly con la framework hice un pequeño ejemplo que mostraré en este post para ejemplificarlo. Si quieren bajar mis modificaciones pueden hacerlo al siguiente link.

En general para implementar un preview handler con la framework de Toub simplemente tenemos que derivar de alguna de las dos clases bases, FileBasedPreviewHandler (para archivos como tal) y StreamBasedPreviewHandler (en el caso de Streams). Claro, sus propiedades dependen de si usaremos una Stream o un Archivo para manejar y ver el contenido. Luego de escoger que usar debemos crear un objeto que contendrá el “control” del preview handler, este debe ser igual del mismo “tipo” que el anterior (ya sea Stream o File). A este objeto hacemos un override de su propiedad Load y agregamos los controles necesarios para mostrar el contenido del archivo en nuestro Preview Handler.

Para ilustrar mejor el uso de los preview handlers se me ocurrió hacer un pequeño PreviewHandler para mirar el contenido de los archivos de código en mi computadora. Para comenzar usaré mi versión simplificada del la Managed Preview Handler Framework de Stephen Toub. Crearé un proyecto y agregaré el assembly Msdn.PreviewHandlerFramework a las dependencias de mi proyecto. Hay muchos controles en el mercado para mostrar código fuente, pero una gran mayoría son pagados, encontré un par que renderizan el código fuente en un archivo HTML así que se me ocurrió generar a partir del archivo de código y luego mostrarlo en un control Web en el preview handler. Con esto en mano decidí usar el Code Highlighter de Jean-Claude Manoli (http://www.manoli.net/csharpformat/).

Es importante que para que un preview handler funcione debe estar registrado como un server COM+ (usando regasm), y para que un Assembly pueda registrarse como COM+ server debe antes estar registrado e instalado en la GAC (usando gacutil), claro, para que un assembly pueda ser instalado en la GAC el assembly debe estar firmado, o sea, usar un Strong Name (quizas usando sn), y un Assembly en la GAC solo puede depender de otro Assembly en la GAC. En otras palabras, el código de la preview handler simplificada debe antes agregarse a la GAC, luego agregar el código de mi preview handler ejemplo y luego registrar mi preview handler a la GAC. Para evitar problemas, decidí embeber el código de Manoli dentro del código de mi preview handler, veamos el preview handler en sí en código.

   1: public sealed class BasicCodePreviewHandler : FileBasedPreviewHandler
   2:     {
   3:         protected override PreviewHandlerControl CreatePreviewHandlerControl()
   4:         {
   5:             return new BasicCodePreviewHandlerControl();
   6:         }
   7:  
   8:         private sealed class BasicCodePreviewHandlerControl : FileBasedPreviewHandlerControl
   9:         {
  10:             public override void Load(FileInfo file)
  11:             {
  12:                 string extension = file.Extension.ToLower();
  13:                 SourceFormat formatter = FormatterFactory.GetFormatter(extension);
  14:                 formatter.LineNumbers = true;
  15:                 formatter.EmbedStyleSheet = true;
  16:  
  17:                 FileStream stream = file.Open(FileMode.Open);
  18:                 string formattedCode = formatter.FormatCode(stream);
  19:  
  20:                 WebBrowser browser = new WebBrowser();
  21:                 browser.Dock = DockStyle.Fill;
  22:                 browser.DocumentText = formattedCode;
  23:  
  24:                 Controls.Add(browser);
  25:             }
  26:         }
  27:     }

Bien como veran es sumamente sencillo crear un preview handler, simplemente usamos la referencia al assembly en cuestión (el de la Preview Handler Framework for Managed Code de Stephen Toub), derivar la clase dependiendo si usaremos una Stream o un Archivo (en mi caso usé un archivo ya que sería más fácil el darme cuenta que tipo de código resaltaría). Bien, el siguiente paso es indicar que esta clase es un “preview handler” eso lo hacemos adornando la clase con el atributo PreviewHandler, indicamos con este atributo el nombre de nuestro preview handler, las extensiones (separadas por😉 para el cual lo registraremos y un ID que identificará al atributo entre los demas (este ID es fácilmente generado usando la GUID generation tool de Visual Studio).

De igual manera debemos indicar un GUID único de la clase ante las demas clases COM+ registradas, esto es obligatorio entre los servers COM+, asignamos un nombre o ProgID a la clase (en general es al assembly) y por último indicamos que es una clase visible ante COM+, dicho esto la clase quedaría ordenada de la siguiente manera:

   1: [PreviewHandler("Basic Code Preview Handler", 
   2:     ".cs;.vb;.sql;.tsql", 
   3:     "{B442EFE0-613A-404d-900A-2903106C1581}")]
   4: [ProgId("Rioshu.Examples.CodePreviewHandler")]
   5: [Guid("9E9CE8EC-21DB-4030-830A-0D8ED5E88F0B")]
   6: [ClassInterface(ClassInterfaceType.None)]
   7: [ComVisible(true)]
   8: public sealed class BasicCodePreviewHandler : FileBasedPreviewHandler
   9: {
  10:    // ...
  11: }

Recuerden que esta clase va a ser registrada ante el registro de servidores COM+, así que debemos escribir el código necesario para que regasm sepa donde registrarlo, eso lo hacemos através de la función helper de la Managed Preview Handler Framework llamada Register y Unregister. Con esto en mente podemos crear la siguiente clase sencilla para ayudarnos a registrar el assembly:

   1: internal static class PreviewHandlerRegistration
   2: {
   3:     [ComRegisterFunction]
   4:     private static void Register(Type t) { PreviewHandler.Register(t); }
   5:         
   6:     [ComUnregisterFunction]
   7:     private static void Unregister(Type t) { PreviewHandler.Unregister(t); }
   8: }

Bien, por último recordemos que necesitamos firmar nuestro assembly, eso podemos hacerlo generando un Strong Name file con sn

sn -k previewhandler.snk

Agregado el strong name al assembly basta con compilar el proyecto y pasamos ahora a instalar lo que necesitamos. Tomemos en cuenta que el Assembly con el Msdn Preview Handler Framework ya esta en la GAC correctamente instalado, entonces simplemente instalamos en la GAC luego registramos como un COM+ server y listo.

gacutil /i Rioshu.CodePreviewHandler.dll

regasm /register Rioshu.CodePreviewHandler.dll

Para probar nuestro código simplemente activamos el panel de preview en el explorer de Vista y vamos a un archivo de código. 

previewhandlerinaction

Bien, como ven es sumamente fácil agregar con la Framework de Stephen Toub soporte para previsualización de nuestros archivos en Windows Vista, aconsejo que lean el artículo de la MSDN Magazine que les anuncié arriba, y claro, experimentar con sus propios archivos. En mi caso hay mucho más que se podría lograr con archivos de código fuente, pero será para la próxima. Los dejo con los archivos originales, espero que les sea de ayuda y espero escribir mas seguido de ahora en adelante.

Los dejo con los archivos que acompañan al post.

http://www.box.net/shared/oxbtevz3cz

Saludos!

3 comentarios to “Windows Vista Preview Handlers”

  1. Muy interesante.

  2. Estuardo Hernandez said

    Exelente que estes escribiendo nuevamente, leo cada una de las cosas que escribis, ya hacia falta leer algo nuevo.😉 saludos

  3. Estuardo Hernandez said

    Tino, tenes alguno de los libros que Microsoft propone para la certificacion de web developer que querras vender? Si lo tenes por favor, avisame yo te los compro.
    Saludos!

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

 
A %d blogueros les gusta esto: