miércoles, 26 de diciembre de 2012

Instalar un servicio de Windows en una máquina de 64 bits

Si el PC con el que desarrollas es una máquina de 32 bits y el servidor en el que se va a instalar es de 64 bits puedes tener algunos problemas para realizar la instalación, ya que el instalador generado no funcionará.

Lo primero a tener en cuenta es que debes compilar todos los proyectos que incluyan el servicio, el propio servicio y todos los proyectos satélites, en x64. Esto se hace en la sección "Generar" de la ventana de propiedades de cada proyecto. Yo no lo dejaría en AnyCPU ya que no siempre funciona correctamente.

Pero con esto no es suficiente, ya que el instalador de Visual Studio, al menos hasta la versión 2008, tiene un  pequeño bug. Aunque la plataforma de destino sea x64, para generar el instalador Visual Studio usa una librería del sistema (InstallUtilLib.dll) compilada en 32 bits. Por tanto, al instalar el servicio en un servidor x64 se genera una excepción del tipo “BadImageFormat”.


Para solucionar este problema debes reemplazar la librería (InstallUtilLib.dll) introducida en 32bits  en el .msi instalador por la librería de 64bits.

Para reemplazar la librería debes seguir los siguientes pasos:

  1. Abre el fichero .msi generado en Orca
    1. Si no tienes instalada la aplicación Orca de Microsoft es necesario que la descargues e instales.
  2. Selecciona “Binary table”
  3. Haz doble click en la celda [Binary Data] para el registro “InstallUtil”
  4. Asegúrate de que “Read binary from filename” está seleccionado  y pulsa sobre el botón “Browse”
  5. Navega hasta la ruta %WINDIR%\Microsoft.NET\Framework64\v2.0.50727
    1. Esta ruta solo está disponible en máquinas con arquitectura de 64Bits, por tanto debes seleccionar esta ruta en un servidor remoto, o copiar este fichero desde un servidor a tu máquina local.
  6. Selecciona “InstallUtilLib.dll”
  7. Pulsa en el botón “Open”
  8. Pulsa en el botón “OK”
  9. Guarda el .msi


Este .msi ya es posible instalarlo en un servidor de 64Bits.



miércoles, 12 de diciembre de 2012

Usar un fichero Excel desde un servicio de Windows


Si intentas manejar un fichero Excel con las librerías de interoperalilidad desde un servicio de Windows desarrollado en .Net, te encontrarás con una Excepción poco esclarecedora: "Microsoft Office Excel cannot access the file".

El problema se debe a que un servicio de Windows, independientemente del usuario de ejecución que se configure, se ejecuta en un perfil especial, el systemprofile. Este perfil no tiene una carpeta de escritorio, sin embargo la librería de interoperabilidad de Excel, para modificar un documento Excel, lo intenta abrir en segundo plano en el escritorio. Al no existir la ruta, se provoca esta excepción.

Por tanto, en el momento de la instalación es necesario crear la carpeta de escritorio (Desktop) en función de la arquitectura del servidor:


  • Servidor de 32bits: %WINDIR%\System32\config\systemprofile\Desktop
  • Servidor de 64bits: %WINDIR%\SysWOW64\config\systemprofile\Desktop


martes, 11 de diciembre de 2012

Cifrar el fichero de configuración con RSA

Un problema recurrente es tener que proteger tu fichero de configuración, app.config o web.config, de miradas indiscretas.

Para realizar el cifrado de estos ficheros podemos usar el contenedor de claves RSA. En función de dónde se desplegará la aplicación y qué usuarios deben tener acceso al fichero de configuración descifrado, se puede usar el contenedor de claves RSA de dos maneras, o bien usar el contenedor por defecto, o bien usar un contenedor personalizado.

  • Contenedor por defecto: No tienes que preocuparte de crear el contenedor, ni adaptar la configuración de tu fichero a un contenedor específico. Por contra escogiendo este método no es posible migrar el fichero de configuración cifrado de un equipo a otro o tener una aplicación distribuida en diferentes máquinas con un único fichero de configuración.
  • Contenedor personalizado: Permite la distribución de una aplicación utilizando el mismo cifrado en diferentes máquinas. Además permite el control del acceso a la información descifrada por usuario o grupo de usuarios.
Sin ninguna duda es mejor opción utilizar un contenedor personalizado, ya que el aumento de esfuerzo es casi nulo y ofrece mucha más versatilidad. Por tanto, en esta entrada se va a explicar cómo cifrar tu fichero de configuración utilizando un contenedor de claves RSA personalizado.

En este ejemplo se va a mostrar como cifrar un fichero app.config, sin embargo el proceso para cifrar un fichero web.config es completamente análogo.

Para cifrar el fichero de configuración se deben seguir los siguientes pasos:

  1. Crear el contenedor de claves
  2. Crear el proveedor de cifrado personalizado
  3. Cifrar el fichero usando "EntLib Config"

Crear contenedor de claves

El primer paso es crear el contenedor de claves a utilizar. Por si en un futuro se quiere migrar la aplicación a otro servidor o implantarlo en diversas máquinas, es importante crear este contenedor como 'exportable'. Todas las instrucciones para manejar los contenedores de claves RSA las puedes encontrar en esta entrada: Manejar el contenedor de Claves RSA.


Crear proveedor de cifrado personalizado

El siguiente paso es indicar en el fichero de configuración cuál es el contenedor de claves que debe utilizar. Para ello se creará un nuevo proveedor de cifrado RSA introduciendo dentro de la sección <configuration> la siguiente clave:

<configprotecteddata> 
 <providers> 
  <remove name="RSAProtectedConfigurationProvider"> 
    <add 
      description="Uses RsaCryptoServiceProvider to encrypt and decrypt" 
      keycontainername="nombreClave" 
      name="RsaProtectedConfigurationProvider"  
      type="System.Configuration.RsaProtectedConfigurationProvider, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" 
      usemachinecontainer="true"> 
    </add>
  </remove>
 </providers>
</configprotecteddata>

En esta clave se ha de cambiar el valor de keycontainername por el nombre que se le haya dado al contenedor en el momento de su creación. Adicionalmente se puede proporcionar una descripción diferente al proveedor de RSA.


Cifrar el fichero usando "EntLib Config"

Al instalar las Enterprise library 4 o superior (no sé si con versiones anteriores también), se instala la herramienta de configuración de Enterprise Library, esta herramienta se llama "Ent Lib Config". Se intalarán distintas versiones de esta herramienta teniendo que elegir la versión adecuada en cada momento, en función de la versión del framework del proyecto (3.5 o 4) y de la arquitectura de la máquina (32 o 64 bits).

Se debe abrir el fichero de configuración con esta herramienta Ent Lib Config, para ello se puede abrir la aplicación y buscar el fichero o dentro del Visual Studio: pulsar botón derecho sobre el fichero de configuración > Edit Enterprise Library V5 Configuration.

Editar fichero de configuración con Ent Lib Configuration desde Visual Studio

El fichero de configuración se cifra por secciones, no se cifra entero. es decir, se puede cifrar la sección de cadenas de conexión pero no cifrar la sección de AppSettings. Para cifrar una sección hay que seguir los siguientes pasos:

Desplegar las opciones de la sección a cifrar pulsando en el botón: 

Seleccionar en la opción "Cifrado" el valor "RsaProtectedconfigurationProvider"



Resultado final

Fichero sin cifrar:



Fichero con sección AppSettings cifrada: