Accediendo a tus ensamblados de .NET desde Silverlight
Posted on : 27-07-2011 | By : Rodrigo | In : Silverlight, Silverlight 4, Silverlight 5
Tags: AutomationFactory, interop, Silverlight
4
El BCL (Biblioteca de Clases Base, por sus siglas en inglés) de Silverlight está reducido a comparación del BCL del .NET Framework completo que tenemos instalado en nuestros equipos, por lo que la funcionalidad no es la misma en un aplicativo de Silverlight que alguno construido con el .NET Framework completo.
No obstante, a partir de Silverlight 4, es posible que las aplicaciones de Silverlight sean clientes de automatización cuando ejecutan en Confianza Elevada, esto es, poder invocar los servidores de automatización registrados en el sistema operativo Windows. Generalmente, la mayoría de ejemplos que podemos encontrar en la Web al respecto de esta característica van por el lado de invocar los servidores de automatización de Office (Outlook.Application o Excel.Application por ejemplo), pero ¿qué sucede si necesitamos invocar funcionalidad ya construida en alguno de nustros ensamblados que hayamos escrito en .NET 4.0?
Ensamblado
En esta solución crearemos dos proyectos, uno de tipo Class Library del .NET Framework 4.0 y otro proyecto será la aplicación de Silverlight.
En el proyecto de la Biblioteca de Clases escribiremos la funcionalidad para obtener la información de todas las unidades lógicas del equipo. Tradicionalmente, esto lo podemos lograr por medio de la clase DriveInfo del espacio de nombres System.IO, pero justamente esa es una de las clases que no está en el BCL de Silverlight, por lo que crearemos un ensamblado de .NET 4.0 que regrese esa información, y la usaremos en un aplicativo de Silverlight.
La clave para lograr esto es abrir las propiedades del proyecto de la Biblioteca de Clases y seleccionar la opción “Register for COM interop” para poder exponer este ensamblado a través de COM.
En el proyecto agregaremos una clase llamada DriveInfo, la cual tendrá las propiedades Name, DriveFormat, TotalSize y TotalFreeSpace de la siguiente manera:
[ComVisible(true)]
public class DriveInfo
{
public string Name { get; set; }
public string DriveFormat { get; set; }
public long TotalSize { get; set; }
public long TotalFreeSpace { get; set; }
}
Nota cómo se está decorando la clase con el atributo ComVisibleAttribute. Este atributo indica que este tipo estará disponible a través de COM.
Adicionalmente a esto, agregaremos una clase llamada Información.cs, la cual tendrá el método GetLogicalDrivesInfo() para regresar la información de todas las unidades lógicas del equipo del usuario. También he agregado el método GetLogicalDrives() para obtener únicamente el nombre de todas las unidades lógicas. De hecho, también podríamos agregar cualquier funcionalidad necesaria que utilice el .NET Framework 4.0 (métodos, propiedades y eventos). El siguiente fragmento de código muestra la implementación de la clase Informacion.cs. Nota cómo también se está decorando con el atributo ComVisibleAttribute.
[ComVisible(true)] public class Informacion { public DriveInfo[] GetLogicalDrivesInfo() { var result = new List<DriveInfo>(); var drives = System.IO.DriveInfo.GetDrives(); foreach (var item in drives) { if (true) { result.Add(new DriveInfo() { Name = item.Name, DriveFormat = item.IsReady ? item.DriveFormat : string.Empty, TotalFreeSpace = item.IsReady ? item.TotalFreeSpace : 0, TotalSize = item.IsReady ? item.TotalSize : 0 }); } } return result.ToArray(); } public string[] GetLogicalDrives() { return System.Environment.GetLogicalDrives(); } }
Gracias a la opción que habilitamos en las propiedades del proyecto de Silverlight, al compilar el ensamblado este será registrado en el registro de la máquina local con un progID del tipo EspacioDeNombres.Clase, en este caso Utilerias.Información. Para hacer esto manualmente podrías utilizar la utilería regasm.exe, cuando quisieras registrar el ensamblado en los equipos de tus usuarios.
Nota: necesitarás ejecutar Visual Studio .NET como Administrador, para que al momento de compilar el tipo sea registrado adecuadamente en el Registro de tu equipo.
Proyecto de Silverlight
Del lado del proyecto de Silverlight utilizaremos la clase AutomationFactory y su método CreateObject() para poder crear una referencia al componente con progID Utilerias.Información registrado previamente.
Además de esto, crearemos una clase DriveInfo.cs, igual a la que creamos en el proyecto de la Biblioteca de Clases. Esto para poder crear un DataTemplate adecuado al presentar la información de las unidades lógicas en un ListBox.
if (AutomationFactory.IsAvailable) { dynamic obj = AutomationFactory.CreateObject("Utilerias.Informacion"); var drives = obj.GetLogicalDrivesInfo(); var result = new List<DriveInfo>(); foreach (var item in drives) { var driveInfo = new DriveInfo(); driveInfo.Name = item.Name; driveInfo.TotalFreeSpace = item.TotalFreeSpace; driveInfo.TotalSize = item.TotalSize; driveInfo.DriveFormat = item.DriveFormat; result.Add(driveInfo); } if (result.Count > 0) { listBox1.ItemsSource = result; } }
Nota el uso de los tipos dinámicos (palabra clave dynamic). Debido a que se basan en Late Binding, no tendremos Intellisense para poder conocer los miembros del tipo en cuestión, por lo que es importante que los nombres correspondan correctamente.
Finalmente, al probar la aplicación te podrás dar cuenta que efectivamente tu aplicación de Silverlight utiliza el ensamblado Utilerias.dll que creamos en el primer paso, usando el .NET Framework 4.0 completo. A través de AutomationFactory lo accedemos y obtenemos la información de todas las unidades lógicas del equipo.
Toma en cuenta que el ensamblado que vayas a utilizar, deberá estar registrado previamente en la máquina del usuario (utiliza regasm.exe), de lo contrario AutomationFactory.CreateObject() arrojará una excepción. Probablemente necesitarás un instalador de prerequisitos antes de instalar y/o ejecutar la aplicación de Silverlight en Confianza Elevada.
¡Espero que les sea de utilidad!





Si, bastante útil…. lo malo si es el tema de registrarlo; digamos que estaría un entredicho cuan “Web” seria; ademas de las dependencias de plataforma… por que cual seria la diferencia en desarrollar un app wpf?… igual hay que instalarla… (aunque de hecho lo he utilizado jejejeje).
Buen Articulo.
Ciertamente existirá la dependencia a que ejecute en Windows por el tema de COM. Con respecto a WPF, cierto que lo podrías hacer en WPF también aunque hay ciertos escenarios donde Silverlight sería una opción más adecuada por ser más liviano.
Gracias y Salu2!
Excelente tutorial!
La librería .Net podría ser registrada a través de un instalador que por debajo hace un regsvr32 ?
Rodrigo, por otro lado, podría ser esto una utilidad para acceder a los archivos en cualquier ubicación física de la máquina cliente desde Silverlight?
Hola David! Usarías regasm.exe para el registro del ensamblado. Por otro lado sí podrías acceder con esta técnica cualquier parte del sistema de archivos del usuario, pero eso ya lo hace de manera nativa Silverlight 5 en Confianza Elevada
Gracias y salu2!