jueves, 22 de noviembre de 2012

Visual Studio no lanza todas las excepciones del código

Hoy me ha pasado una cosa un poco extraña relacionada con la gestión de excepciones.

El problema

Tenemos un formulario de Windows con una caja de texto en la que en el evento “TextChanged” realizamos una serie de operaciones, llamando para ello a un método externo.

El tema es que en un momento dado, me he fijado que en el método externo se estaba produciendo una excepción, pero en depuración no me estaba mostrando la típica ventana de excepción no controlada… Vamos, que no me estaba enterando de que había un problema con el código.

Para reproducir este comportamiento, basta con añadir una caja de texto a un formulario y codificar en el manejador del evento “TextChanged” una llamada a una función que produzca una excepción, por ejemplo:

image

Ejecutamos el formulario y escribimos algo en la caja de texto.

¿Aparece esta ventana?

image

Entonces no tienes el mismo problema que yo y te has equivocado de post…

Lo que a mí me pasaba, es… nada. No da ningún tipo de excepción al trabajar con el formulario en cuestión. entonces, ¿cómo sabemos que hay una excepción? en la ventana de “Output” aparece la siguiente entrada:

image

Una explicación (rapidita)

Por lo visto, este comportamiento es así por diseño, siempre que estemos ejecutando Visual Studio en un sistema en 64 Bits (como es mi caso) cuando la excepción se produce en un método que cause una transición al kernel (como por ejemplo el manejador en cuestión, esta excepción se trata en el propio kernel y se atrapa por el sistema operativo. Como la excepción ya ha sido controlada, lo que sucede es que nosotros no nos enteramos.

Para más detalle, entiendo que Google estará encantado de ayudarnos.

Una solución (más bien alternativa)

Para conseguir que el depurador de Visual Studio nos avise de esas excepciones, tenemos que indicarle explícitamente, en la ventana de “Exceptions”

image

Esta ventana aparece en el menú “Debug”, “Exceptions…” y para evitar el comportamiento que he explicado, basta con marcar la casilla “Thrown” del grupo “Common Language Runtime Exceptions”

Una vez marcada la casilla, cuando llega al punto de la excepción, ya nos aparece la ventana de excepción no controlada que necesitamos. De esta manera ya no se nos “enmascaran” posibles errores…

¿Por qué digo que es una alternativa?

Un efecto colateral de esta configuración es que a partir de activar la opción, cada vez que de una excepción (sea controlada o no) nos va a aparecer la dichosa ventanita, deteniendo el depurador hasta que le demos a continuar.

Esto en condiciones normales es un auténtico problema, pero yo considero que me merece la pena el inconveniente, sobre todo si trabajamos con ‘rethrowing’

Último apunte

El problema expuesto aquí no genera ningún problema adicional en el código desarrollado, ya que si en lugar de arrancar el depurador ejecutamos el archivo compilado o lanzamos la ejecución SIN depuración (Ctrl + F5) la excepción no controlada SÍ que aparece aunque, claro, con la apariencia que nadie queremos en nuestros programas

image

martes, 6 de noviembre de 2012

Trabajando con NuGet–Un inicio

¿Qué es NuGet?

NuGet es una extensión de Visual Studio que hace que sea fácil agregar, actualizar y elimina bibliotecas (implementadas como paquetes) en un proyecto de Visual Studio. Un paquete de NuGet es un conjunto de archivos empaquetados en un solo archivo con extensión .nupkg que usa el formato Convenciones de empaquetado abierto (OPC).

(Copiado íntegramente del MSDN)

¿Qué hace falta?

Lo primero, instalarlo.

En Visual Studio 2010 se instala mediante el administrador de extensiones (Menú Tools, Extension Manager) mientras que Visual Studio 2012 lo trae instalado por defecto.

Una vez instalado, basta utilizar los nuevos menús (Manage NuGet Packages)

Esta herramienta es brutal, pero lo verdaderamente brutal sería poder crear nuestro propio repositorio de paquetes de NuGet, de forma que en la organización tuviéramos todos los componentes homologados disponibles para su utilización, actualizables además muy fácilmente.

En el artículo indicado anteriormente tenemos las instrucciones básicas, que a continuación intentaré explicar un poco más si es necesario.

Generar un servidor NuGet

No es necesario generar un servidor de NuGet para poder trabajar con un repositorio particular de paquetes, pero considero que es importante y útil como para al menos indicarlo.

Sencillo:

  1. Creamos una aplicación web ASP.NET (4.0) vacía en Visual Studio.
  2. Instalamos el paquete de NuGet “NuGet.Server”
  3. Publicamos la aplicación en un servidor web.
  4. Publicamos en la carpeta “Packages” los paquetes de NuGet que queramos que estén disponibles.

Añadir una ruta de paquetes en Visual Studio

Para configurar Visual Studio de forma que pueda conectar al repositorio, tenemos que ir a Herramientas, Opciones, y añadir un nuevo origen de paquetes en la ventana:

image

Generar un paquete de NuGet

Para generar nuestros propios paquetes para NuGet, podemos hacerlo mediante línea de comandos (descargando nuget.exe) o podemos hacerlo con un interfaz gráfico (descargando el “NuGet Package Explorer”) se trata de una aplicación click-once, con lo que se actualizará automáticamente.

A continuación vamos a ver los pasos necesarios para generar un paquete con el cliente click-once.

  1. Arrancamos el “NuGet Package Explorer”
  2. Elegimos la opción “Create a new package”
    image
  3. En la parte de la izquierda editamos los metadatos del paquete (Menú Edit, Metadata)
  4. En la parte de la derecha arrastramos en ensamblado que queremos empaquetar.
    image
  5. Guardamos el paquete en la ruta deseada con el menú File, Save o podemos exportarlo con el menú File, Export…

En el momento de generar el paquete podemos además indicar las dependencias que nuestro paquete tenga con otros componentes. Para añadir una dependencia, hacemos clic en el botón “Edit dependencies” en la parte inferior de la sección izquierda (donde hemos puesto la información del paquete)

  1. Añadimos un nuevo grupo con el botón con el símbolo “más”
    image
  2. Ahora hacemos clic en el botón con el icono de propiedades para elegir una dependencia alojada en un repositorio, y la seleccionamos con doble clic (en la siguiente captura, seleccionamos el paquete de log4net)
    image
  3. Confirmamos haciendo clic en el botón de añadir nueva dependencia (a la derecha de la caja con la versión del componente)
    image
  4. Confirmamos con “OK” y ya tenemos la dependencia creada.

Al añadir una dependencia, lo que conseguimos es que cada vez que se instale el paquete, automáticamente se instalen también las dependencias configuradas.

Otra opción interesante es hacer ‘transformaciones’. Esto significa que podemos configurar el paquete para que actualice archivos presentes en el proyecto, por ejemplo el archivo App.config.

Para esto, en la sección de “Package contents”

  1. Añadimos la carpeta para contenido (menú Content, Add, Content Folder)
    image
  2. Sobre la carpeta “content” añadimos un nuevo archivo con el botón derecho del ratón y, muy importante, le damos al archivo el nombre del archivo que queremos modificar, terminado en “.transform”
    image
  3. Esto genera un archivo vacío, en el que incluiremos el contenido que deseamos que se añada al configurar el paquete en el proyecto, en la siguiente captura se puede ver el contenido necesario para el correcto funcionamiento del paquete ‘log4net’
    image

Una vez hecho todo esto, cuando configuremos el proyecto para utilizar el paquete, automáticamente añadirá las entradas especificadas en el archivo de configuración.

Actualizar un paquete de NuGet

Realmente no existe el concepto como tal de actualizar, realmente lo que hacemos es un “Save as” del paquete anterior, modificando la versión en la sección de “Package Metadata”. Al hacer el “Save as” nos propone el nombre original actualizado con la nueva versión, y una vez en la solución, si hacemos clic con el botón derecho del ratón sobre la solución y elegimos “Manage NuGet Packages for Solution” veremos que tenemos nueva versión del paquete, y podremos actualizar todos los proyectos de la solución de un plumazo.

image

image

Ultimas consideraciones

Existen más posibilidades al generar paquetes, como por ejemplo publicar distintas versiones de los ensamblados para distintas versiones del Framework, pero de momento no vamos a entrar más a fondo, como primera aproximación es suficiente.