domingo, 16 de febrero de 2014

Receta No. 1-14 en C#: Gestión del Global Assembly Cache (GAC)

Tabla de Contenido

0. Introducción
1. Problema
2. Solución
3. Discusión de la Solución
4. Uso de la Solución
5. Conclusiones
6. Glosario
7. Enlaces & Literatura

0. Introducción

Desde las recetas 1-8 a 1-10 aprendimos a crear llaves para strong names (o nombres seguros); la asignación del strong name a un assembly; y verificación ante posibles modificaciones del assembly. Ahora es la oportunidad de desplegar el assembly en el repositorio destinado para ello: el Global Assembly Cache (o GAC). En esta receta nos centraremos en los puntos más importantes para llevar a cabo esta tarea que nos dejará poner a disposición de otras aplicaciones las librerías (assemblies) que creemos. Como contenido adicional veremos que esto nos ayudará a validar la autoría de nuestras librerías de terceros y los nuestros propios, y llevar a cabo una administración centralizada.

1. Problema

Ya hemos creado algunas librerías representandas por assemblies, ahora nos enfrentamos a un problema. Éste consiste (problema planteado originalmente en [1]) en desplegar el assembly sobre el repositorio común y centralizado del Framework .NET conocido como Global Assembly Cache [3]. Precisamente son las dos siguientes tareas:
  • Agregar un assembly en el GAC.
  • Obtener información de un assembly desde el GAC.
  • Remover un assembly desde el GAC.

2. Solución

Nuestra solución al problema planteado en la sección anterior consiste básicamente en el uso de la herramienta Global Assembly Cache Tool: gacutil.exe [9]. Esta herramienta la ejecutamos a través de órdenes dasdas sobre la línea de comandos.

Quiero agregar que la solución puede ser relativamente breve, pero me voy a extender desde el principio desde crear las llaves de firma, la creación del strong name para el assembly (que también crearé, pero será muy breve), y finalmente su despliegue sobre el GAC utilizando la herramienta gacutil.exe.

3. Discusión de la Solución

Empezaré la discusión hablando más detenidamente del GAC: características, uso, requerimientos, ejemplo abstracto, implementación, y algunos riesgos. Más adelante, detalles acerca de la naturaleza de la herramienta gacutil.exe.

3.1 Global Assembly Cache (GAC)

En esencia el GAC es el repositorio compartido o cache destinado al almacenamiento y fuente de referencia de assemblies. Su ámbito es de equipo, se haya protegido contra intentos no autorizados de modificación gracias que se encuentra en un directorio con privilegios de administrador. Fue concebido para hacer frente a lo que en inglés de conoce DLL hell (o de forma interpretada: infierno de librerías dinámicas DLL) [10].

En [2] encontramos está definición técnica de GAC:
The Global Assembly Cache (GAC) is a machine-wide CLI assembly cache for the Common Language Infrastructure (CLI).
Analizando la definición previa, podemos inferir que se trata del repositorio utilizado por el ambiente de ejecución de código y de máquina virtual utilizado por el Framework .NET. (Y también las implementaciones de código fuente (Mono) y Portable.NET): CLI [11].

3.1.1 Requerimientos

Si queremos agregar un assembly en el repositorio GAC, éste primero debe contar con un strong name [6]. Esto deriva en que los assemblies contarán con versionamiento y estarán disponibles para acceso global desde aplicaciones que se ejecuten sobre el host.

3.1.2 Uso

Para llevar a cabo la manipulación del GAC tenemos las dos siguientes alternativas:
  • A través de la herramienta de línea de comandos gacutil.exe, o
  • por medio del explorador de Windows.
  • En versiones previas a .NET Framework 4.0, se contaba con la herramienta shfusion.dll (Assembly Cache Viewer) [12].

3.1.3 Implementación

Desde Wikipedia [2] podemos extraer:
The GAC as a construct does not actually exist within the Windows OS. It is implemented and managed by the CLI. The folders within %systemroot% named assembly and Microsoft.NET\assembly (for .NET 4.0) contain all globally available assemblies with managed filenames so that the version and public key tokens can be included. Each version can therefore exist within the same location and be called without requiring subsequent versions to preserve code entry point locations as usual. Windows Explorer allows the drag-and-drop installation of assemblies into this folder only if they would otherwise be permitted to be installed from the command line.
Desde podemos inferir:
  • GAC es administrado por la propia implementación de CLI (i.e.: Microsoft .NET Framework, Mono, y Portable.NET); y no por el sistema operativo.
  • La ruta utilizada por el GAC en veriones previas al Framework .NET 4.0 es %systemroot%, y en versiones >= a 4.0 Microsoft.NET\assembly.
  • En el GAC pueden coexistir diferentes versiones de un assembly. Esta característica ese muy poderosa, dado que podemos referenciar/usar una versión en particular para los requerimientos particulares de una aplicación que estemos construyendo.
  • A través de Windows Explorer [14] nos basta con arrastrar el (o los) assembly(ies).

3.1.4 Riesgos

En la sección de Pitfalls en [2], se identifican los siguientes riesgos de uso del GAC:
  • By default, applications will only run with the version of the .NET Framework used to compile it, which can cause the application to fail on machines with newer versions of the .NET Framework installed — even when the application would normally run properly with the newer version.
  • It is sometimes necessary to use conditional compilation if some of the core .NET calls (used in the application) are only supported for some versions of the framework. (Ver receta R1-6)
  • .NET applications that rely on native code risk incompatibilities, even with the GAC mechanism.

3.2 gacutil.exe

Con la herramienta Global Assembly Cache Tool podemos agregar, remover, y conocer detalles de los assemblies. Viene incluida incluye con la instalación de Visual Studio y con Windows SDK. En el caso de Visual Studio, podemos hacer lo siguiente para tener acceso a la herramienta:
  1. Menú Inicio, 
  2. Todos los Programas, 
  3. Visual Studio (Versión), 
  4. Clic sobre Visual Studio Tools, y 
  5. Visual Studio Command Prompt
Visual Studio Command Prompt for VS2013
Figura 1. Visual Studio Command Prompt for VS2013.

3.2.1 Sintaxis

gacutil [options] [assemblyName | assemblyPath | assemblyListFile]
Se puede observar que su uso es muy sencillo. En cuanto a los argumentos:
  • assemblyName: Nombre del assembly. Podemos especificar sólamente el nombre textual del assembly, o con las características completas (versión, localización, y la llave publica). así:

    MiAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=0019abc9detrfle5
  • assemblyPath: Ruta relativa o absoluta del manifiesto del assembly.
  • assemblyListFile: Ruta que contiene el listado de los assembliesa instalar o desinstalar.
En [9] podemos encontrar el listado completo de opciones de gacutil, junto con la descripción más detallada.

[Nota: Ya veremos su aplicación práctica en la siguiente sección (4)].

3.2.2 Uso

Vamos a ver el uso básico de gacutil.exe.

3.2.2.1 Instalación de un assembly

  1. gacutil /i NombreAssembly.dll

3.2.2.2 Desinstalación de un assembly

  1. gacutil /u NombreAssembly

3.2.2.3 Desinstalación de un assembly completamente calificada

  1. gacutil /u NombreAssemlby,Version=1.0.0.0

3.2.2.4 Enlistado de assemblies

  1. gacutil /l

3.2.2.5 Filtro durante el enlistado de assemblies

  1. gacutil /l NombreAssembly

3.2.3 Comentarios

  • Para usar la herramienta gacutil.exe debemos poseer permisos de administrador.
  • En la Figura 2 se agrega la nota sobre el uso de GAC en tiempo de ejecución.
Nota acerca del uso de GAC en tiempo de ejecución.
Figura 2. Nota acerca del uso de GAC en tiempo de ejecución.

4. Uso de la Solución

Vamos a crear un ejemplo completo que parte desde la creación el par de llaves (pública y privada), pasando por la asignación de strong name al assembly, hasta la agreagación del assembly en el GAC. Empecemos.

4.1 Creación de Par de Llaves

Creamos el par de llaves (pública y privada) ejecutando el siguiente comando:

  1. sn -k MisLlaves.snk
Creación de par de llaves.
Figura 3. Creación de par de llaves.

4.2 Asignación de nombre seguro (strong name) al assembly

Vamos a crear el siguiente archivo que contiene los atributos de regionalización o cultura y número de versión para le asignemos un nombre seguro.

Archivo Calculadora.cs:



[Nota: Para los usuarios de Internet Explorer dar clic en el enlace previo. Existen algunos problemas de compatibilidad entre Gists de GitHub e Internet Explorer.]

Ahora vamos a instalar las llaves creadas en la sección 4.1 de esta manera:


  1. sn -i MisLlaves.snk ContendorLlaves

Las llaves o claves (pública y privada) quedaron almacenadas en el contendor CSP ContendorLlaves.
Llaves almacenadas en contenedor CSP.
Figura 4. Llaves almacenadas en contenedor CSP.

Pasemos a compilar el archivo Calculadora.cs asignándole un nombre seguro, a través del siguiente comando:


  1. csc /keycontainer:ContenedorLlaves Calculadora.cs
Creación de librería DLL satisfactoria.
Figura 5. Creación de librería DLL satisfactoria.

4.3 Agregación del assembly Calculadora.dll en el GAC

Pasemos a ejecutar el siguiente código en la línea de comandos sobre Visual Studio Studio Command Prompt:


  1. gacutil /i Calculadora.dll
Agregación satisfactoria assembly Calculadora.dll a GAC.
Figura 6. Agregación satisfactoria assembly Calculadora.dll a GAC.
[Nota: Recuerde que Visual Studio Command Prompt debe ser ejecutado con privilegios de administrador.]

4.4 Uso del assembly Calculadora.dll

Veamos cómo usar el assembly Calculadora.dll en una aplicación cliente de prueba.

Archivo PruebaCalculadora.cs:

[Nota: Para los usuarios de Internet Explorer dar clic en el enlace previo. Existen algunos problemas de compatibilidad entre Gists de GitHub e Internet Explorer.]

El archivo PruebaCalculadora.cs lo compilamos usando el siguiente comando en Visual Studio Command Prompt:

  1. csc /target:exe /reference:Calculadora.dll PruebaCalculadora.cs

Y lo podemos ejecutar de esta manera:

  1. PruebaCalculadora.exe

Y en la consola obtendremos el siguiente resultado:
Ejecución aplicación cliente de prueba assembly Calculadora.dll.
Figura 7. Ejecución aplicación cliente de prueba assembly Calculadora.dll.

Conclusiones

Hemos avanzado en un paso importante: creación de un assembly y su agregación en el Global Assembly Cache (GAC). Esto nos ubica en la capacidad de poder manipular el GAC para agregar, remover, y enlistar los assemblies localizados en el repositorio GAC. Vimos el uso de la herramienta gacutil.exe (Global Assembly Cache Tool) que realiza los tres cometidos mencionados anteriormente. Vimos en cuatro pasos como alcanzar este objetivo partiendo desde la creación de las llaves/claves pública y privada, la creación del contedor CSP, compilación del código fuente en el archivo Calculadora.cs y la especificación del contenedor de llave, y finalmente la agregación del assembly a través de gacutil /i Calculadora.dll.

Glosario

- Assembly
- Certificado
- CLI
- GAC
- Llave

Enlaces & Literatura

[1]: Visual C# 2010 Recipes by Allen Jones and Adam Freeman. Copyright 2010 Allen Jones and Adam Freeman, 978-1-4302-2525-6.
[2]: Global Assembly Cache, the free encyclopedia - http://en.wikipedia.org/wiki/Global_Assembly_Cache
[3]: Global Assembly Cache - http://msdn.microsoft.com/en-us/library/yf1d93sz%28v=vs.110%29.aspx
[4]: How to Install an Assembly in the GAC - http://msdn.microsoft.com/en-us/library/aa560649.aspx
[5]: Demystifying the .NET Global Assembly Cache - http://www.codeproject.com/Articles/4352/Demystifying-the-NET-Global-Assembly-Cache
[6]: Strong-Named Assemblies - http://msdn.microsoft.com/en-us/library/wd40t7ad%28v=vs.110%29.aspx
[7]: What is Global Assembly Cache? - http://www.webopedia.com/TERM/G/Global_Assembly_Cache.html
[8]: What is Global Assembly Cache (GAC)? - http://www.techopedia.com/definition/5234/global-assembly-cache-gac
[9]: Gacutil.exe (Global Assembly Cache Tool) - http://msdn.microsoft.com/en-us/library/ex0ss12c%28v=vs.110%29.aspx
[10]: DLL Hell - Wikipedia, the free encyclopedia - https://en.wikipedia.org/wiki/DLL_hell
[11]: Common Language Infrastructure - Wikipedia, the free encyclopedia - https://en.wikipedia.org/wiki/Common_Language_Infrastructure
[12]: Shfusion.dll (Assembly Cache Viewer) - http://msdn.microsoft.com/en-us/library/vstudio/34149zk3%28v=vs.100%29.aspx
[13]: File Explorer - Wikipedia, the free encyclopedia - https://en.wikipedia.org/wiki/Windows_Explorer


M

No hay comentarios:

Publicar un comentario

Envíe sus comentarios, dudas, sugerencias, críticas. Gracias.