viernes, 9 de marzo de 2018

Crear instalador con Visual Studio 2017

Buenos días a tod@s

Sé qué hace mucho que no escribo por aquí, pero, espero alegraros con deciros que sigo vivo y entero jeje. 

Hoy vengo a contaros un problema/necesidad que he tenido y que me ha costado bastante solucionar. No por ser complicado, sino porque la documentación es escasa, difícil de encontrar y todo es muy poco intuitivo. Bueno al tema de hoy que no por eso es menos apasionante. 

Antiguamente desde la versión de Visual Studio 2008 (creo recordar), InstalShield ofrecía una versión gratuita y muy limita de su producto pero que para pequeñas instalaciones nos soluciona el problema de una forma muy profesional. Este acuerdo ha estado presente hasta la versión 2015, pero a partir de entonces ya no tenemos este recurso (una verdadera lástima). 

Visto que ya no podemos hacer las cosas como antes ¿Cómo lo hacemos?


Bueno pues existen múltiples soluciones, Yo he optado por utilizar el propio generador de instalaciones de Visual Studio 2017. Es probablemente la más complicada y engorrosa de todas, pero tiene una cosa a favor, que como forma parte del propio Visual Studio, es muy difícil que deje de funcionar o perdamos el soporte cuando cambiemos a una futura versión.

Este articulo está hecho con VS 2017 Professional. Estoy prácticamente seguro de que es válido al 99,999% para Visual Studio 2015 e incluso 2013 pero la realidad es que esta hecho en 2017 y puede que algunas cosas no sean iguales o se llamen de otra forma.

 

Instalar el paquete Visual Studio Installer para Visual Studio 2017


Antes de nada, si alguno recuerda Visual Studio 2010 en el tipo de proyectos disponibles, existían uno que decía Otros Proyectos à Instalación e implementación y teníamos dos opciones Instalado de Visual Studio y InstalShield LE


Si Intentamos hacer lo mismo en nuestro Visual Studio, veremos que en “Otros tipos de proyecto”, sale vacío. 

Primero debemos instalar el paquete para poder crear nuestros instaladores. Para hacer esto vamos al market de Visual Studio y https://marketplace.visualstudio.com/ y lo buscamos “Installer Projects”.

Para que sea más rápido, os pongo los enlaces directos a los paquetes:

VS 2017

VS 2015

VS 2013

Descargamos e instalamos el paquete y vuala, ya nos aparecerá dentro de “Otros tipos de proyecto “Visual Studio Installer”.

 

Creando nuestro instalador


Tenemos 2 tipos de proyecto en los que nos vamos a centrar. Basicamente son los mismos, la diferencia está en que el primero tiene un pequeño asistente y es algo más amigable (Setup Wizard) y el otro lleva direamente a la pantalla que aparece cuando terminas el asistente (Setup Proyect), por lo tanto el tutoria vale practiamente para los dos.


Pulsamos siguiente


En este ejemplo vamos a hacer una instalación para una aplicación de escritorio, por lo tanto seguimos con la primera opción y pulsamos siguiente.


En esta pantalla nos permite añadir cualquier fichero a la instalación. Podeis hacer lo que querais, desde añadir los ficheros de resultado del proyecto, hasta no añadir nada. Para el ejemplo no voy a añadir nada, pero podria añadirlo todo y ya aparecerian dentro del proyecto.



Ya estamos listos.


Bien ahora vamos a añadir nuestros ejecutables al instalador.
Pulsamos Botón derecho sobre el explorador de soluciones y tenemos la opción "Add"


Podemos hacer 4 cosas:
  • Añadir los resultados de un proyecto (pero para esto debemos añadir el proyecto a esta solución)
  • Añadir Archivo: Mi opción recomendada, añades cualquier fichero y el propio sistema se encarga de configurarlo, buscar sus dependencias etc etc.
  • Añadir “Merge Module”: Si hemos creado otro modulo, podemos añadirlo.
  • Ensamblado: Sin más, añade un ensamblado o componente  


Normalmente, yo la distribución la suelo hacerla independiente al desarrollo. Por lo tanto suelo integrar los ejecutables y librerías ya generados desde la carpeta de resultados, al menos es de la forma que lo he hecho siempre. Pero perfectamente podríamos añadir el proyecto a la solución y que el propio instalador integrara los ficheros (compilara primero el proyecto). Como digo, yo prefiero insertar todo a mano, desde la opción Añadir Archivo. Para eso pulsamos añadir archivo y nos saldrá una ventana para buscar y añadir los ficheros que queramos.


Una vez que hemos seleccionado y pulsamos abrir y ya está.


Y con esto ya tenemos instalador, hasta aquí fácil ¿no?

 

Insertar Información de la aplicación en el instalador

Ya tenemos un instalador para nuestra aplicación prueba ya creado, pero es un poco triste, ya que no hemos añadido información ni nada. Para eso pinchamos en el proyecto de instalación (en mi caso “Tuto Setup”) y seleccionamos la pestaña de propiedades (que no botón derecho propiedades que sale un menú que no tiene nada que ver).


Aquí ya podemos ponerle todos los datos que queramos para que quede más profesional.
Hasta aquí todo bien, ya tendríamos un instalador básico pero bastante apañado.


Opciones de configuración

Es curioso el lugar donde han colocado estos botones de configuración del instalador. Está en la barra superior del explorador de soluciones. Tenemos que tener seleccionado el proyecto de instalación (en el ejemplo “Tuto Setup”) y arriba a la derecha tendremos 5 botones.

De izquierda a derecha:
  • Editor del sistema de archivos
  • Editor del registro
  • Editor de tipos de archivos
  • Editor de acciones personalizadas
  • Editor de las condiciones de inicio


Acciones personalizadas

Ahora vamos a ir a chicha de verdad, lo realmente complicado y el porqué de este tutorial.

Muchas veces creamos programas que necesitamos configurarlos tras la instalación o que queremos que se arranquen. En Instalshield tienes una opción de que al terminar la instalación se lanza un programa. Para mi esta opción era muy útil, por lo dicho anteriormente. Tras instalarlo, lanzaba un programa que configuraba el cliente. Esta opción me permitía facilitar mucho el cómo instalar las cosas y me parece totalmente necesaria. 

Bueno, la buena noticia es que se puede y la mala que es un poco complicado. No porque sea difícil de hacer, si no porque hay poca documentación y la que hay para mi gusto no es demasiado buena. 

Para poder hacer esto debemos a ir al menu del editor de "cciones personalizadas. Al pulsar vemos lo siguiente. 


¿Cómo funciona esto? Bueno, parece evidente ¿no?

Pues no, no lo es.... 

Puedes pulsar botón derecho agregar acción personalizada, seleccionar un ejecutable y va a dar lo mismo lo que hagáis, que no va a ejecutar el programa. 

¿Cómo lo hacemos?

Pues despacito y con buena letra, porque tiene su ciencia. 

Vamos a la solución y agregamos un nuevo proyecto de “Biblioteca de clases (.Net Framework)” (Botón derecho agregar nuevo proyecto à Biblioteca de clases (.Net Framework)).
En mi caso le voy a llamar Acciones Personalizadas.


Bien, ya lo tenemos preparado.


Borramos el elemento Class1.cs y agregamos un elemento “Clase de instalador”


Pulsamos agregar y listo ya tenemos esto medio preparado. 


Ahora pulsamos en el enlace que pone “Haga clic aquí para cambiar a la vista de código”


Y una vez dentro vamos a pegar dentro de nuestra clase todas siguientes funciones, justo debajo de la función Installer.

[System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)]
        public override void Install(IDictionary stateSaver)
        {
            base.Install(stateSaver);
        }

        [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)]
        public override void Commit(IDictionary savedState)
        {
            base.Commit(savedState);
        }


        [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)]
        public override void Rollback(IDictionary savedState)
        {
            base.Rollback(savedState);
        }

        [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)]
        public override void Uninstall(IDictionary savedState)
        {
            base.Uninstall(savedState);
        }


Perfecto, pues ahora ya podemos programar las acciones personalizadas. Dentro de la función Commit (que será la que realice cuando este terminando la instalación) podemos incluir, por ejemplo, la ejecución de nuestra aplicación.
Sería algo así:

[System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)]
        public override void Commit(IDictionary savedState)
        {
            base.Commit(savedState);
            //ejecución
            System.Diagnostics.Process.Start("prueba.exe");

        }


Fantástico, casi lo tenemos. Ahora tenemos que incluir en acciones personalizadas el evento. Aquí sí que os aconsejo que integréis esta clase con el instalador. 

Para esto Sobre el proyecto de instalación pulsamos con el botón derecho “añadir”, “Resultados del proyecto” y seleccionamos el proyecto en mi caso llamado “acciones personalizadas”.


Ahora ya lo tenemos en nuestro instalador


Bien, vamos ahora la ventana de “Acciones personalizadas” y pinchamos directamente en “Custom Actions” botón derecho “Agregar acciones personalizadas” y buscamos (Que por defecto estará en “Aplicación Folder”) el resultado del proyecto que hemos añadido.


Con esto nuestro instalador va a ejecutar todo lo que este en los eventos que hemos en la clase installer.


Perfecto ya podemos ejecutar cualquier cosa, pero hay otro tema. ¿Cómo sabemos dónde se ha instalado nuestra aplicación para iniciarla? 

Evidentemente si no indicamos la ruta el sistema cuando intente enviar el proceso no da a encontrarla, debemos pasar la ruta completa. Para hacer esto debemos pasarle por parámetro a la clase installer donde esta nuestra aplicación instalada. Pero esto es variable ya que puede que el usuario cambie esto. 

Bien pues para hacer esto tenemos que seleccionar la acción personalizada que queramos y luego ir a propiedades. 


En propiedades tenemos una propiedad llamada “CustomActionData” esto le va a pasar el parámetro a la clase. En la clase en cada función tenemos dentro del objeto base.Context.Parameters un array con todos los parámetros que le hemos pasado.

Para pasar el parámetro se hace de la siguiente forma /name1=parámetro1 /name2=parametro2…. SI queremos pasar un parámetro personalizado del instalador debemos hacerlo “[parámetro]\”. Para pasar la ruta de la instalación debemos pasar el parámetro [TARGETDIR]. Por ejemplo así /TARGETDIR="[TARGETDIR]\", (se que la forma de poner las comillas es muy rara, pero es así 😑, no es ninguna errata ).


Como decía antes ahora debemos utilizar base.Context.Parameters para recuperarlo, sería algo así base.Context.Parameters["TARGETDIR"].ToString()

Si lo aplicamos al código para que ejecute la aplicación al acabar:
System.Diagnostics.Process.Start(base.Context.Parameters["TARGETDIR"].ToString() + "\\prueba.exe");

Con esto ya podemos ejecutar cualquier cosa que este en nuestra carpeta de instalación o no. Sé que existen más parámetros como estos,  [ProgramFilesFolder] [Manufacturer] [ProductName], pero no he encontrado ninguna lista donde aparezcan. Agradecería si alguien sabe de alguna, me la pasara para agregarla al artículo.

Diréis… de donde he sacado esto. Pues de una página de Microsoft, donde lo explican bastante regular (https://msdn.microsoft.com/es-es/library/d9k65z2d(v=vs.100).aspx)


Poner una carpeta de instalación personalizada


Para terminar, por defecto el instalador siempre instala la aplicación en la carpeta de archivos de programa \ nombre de la empresa\ Nombre de la aplicación, o lo que es lo mismo [ProgramFilesFolder] [Manufacturer]\ [ProductName]. A veces no nos interesa o queremos cambiar algo de esta ruta. Para eso tenemos que ir a “Editar el sistema de archivos”, seleccionamos “Application Folder” y pulsamos en propiedades. En la venta de propiedades tenemos una llamada “DefaultLocation” donde podemos poner una ruta personalizada. 


Cambiamos los valores que nos interesen y listo.

Fin del tutorial


Todo llega a su fin y este tutorial también, tengo que decir que ha sido un poco largo. No he querido meterme en otras partes como crear accesos directos, editar el menú de inicio, crear subcarpetas, porque es bastante sencillo. Lo realmente enrevesado es el tema de las acciones personalizadas y creo que con este tuto todo quedará más claro.

Aquí dejo este tuto para mí y para todo el que quiera utilizarlo. Espero que esto os sirva  a much@s, y si no te sirve, que al menos la lectura haya sido amena.

Muy importante, si decides compartir o republicar parte de este articulo porque te ha sido útil, por favor cita la fuente y el autor del mismo (vamos cítame) y pon un enlace al artículo de mi blog, te estaré eternamente agradecido.

Muchas gracias por leerme.
Saludetes a todos

P.D. Podéis seguirme en @Jberron, Google+ y LinkedIn




12 comentarios:

  1. Antes que nada muchas gracias por el tutorial pero tengo una pregunta. ¿Como seria para un proyecto con base de datos en SQL?

    ResponderEliminar
    Respuestas
    1. Supongo que habras resuelto el tema. De todas formas desde las acciones personalizadas puedes hacer lo que necesites, si quieres puedes conectarte a una BBDD y lanzar su instalación o, lo que seria mas logico hacer un programa de configuración que una vez instalada la aplicación se lanzara y entre otras cosas a parte de configurar lo esencial te instalara la BBDD. Yo lo haria asi, es facil e hacer y facil de controlar.

      Eliminar
    2. Disculpa, ¿Me podrías ayudar con esa parte? Necesito que se cree la base de datos en SQL Server después de instalar mi aplicación, pero he tenido problemas con ello.

      Eliminar
    3. Hola de nuevo!
      Podrías hacer un tutorial, como este, haciendo el programa de configuración para instalar y configurar la BBDD como dices.

      Eliminar
  2. Hola una consulta, como hago para que el instalador instale una fuente (font) que es necesaria para el uso del programa.
    Gracias por adelantado.

    ResponderEliminar
    Respuestas
    1. Buenas Sebavm73 Sencillamente puedes crear una accione personalizalizada que instale la fuente ¡Nada mas sencillo! si no te funciona esto haer una miniaplicación que te instale la fuente y la llames desde las acciones personalizadas como detallo en el tutorial.

      Eliminar
  3. Hola consulta, si quiero agregar un cuadro de dialogo que pregunte una contraseña si no es correcta que cancele la instalacion?

    ResponderEliminar
  4. !Muchas gracias por el tutorial, me ha servido muchísimo!

    ResponderEliminar
  5. Buenas tardes,
    ¿Como puedo crear un instalador, que, aparte de realizar la propia instalación, si existe una actualización de esta se haga?
    Muchas gracias

    ResponderEliminar
  6. Hola!!!
    No suelo escribir comentarios en blogs, pero lo merece...
    Sencillamente MARAVILLOSO! =D
    Me funciona perfectamente en .Net
    La duda que tengo es si podré ejecutar varios instaladores... imagino que si, pero los abrirá todos de golpe...

    Saludos desde Valencia.

    ResponderEliminar
  7. Gracias bro me salvaste la vida sos un GENIO!!!!

    ResponderEliminar
  8. como puedo hacer que detecte actualizacion desde servidor

    ResponderEliminar

Gracias por tu comentario y gracias por leer el articulo
Un saludo