25

Tengo un proyecto de instalación de Visual Studio. Al momento de la instalación, crea un archivo de lote de desinstalación en la carpeta de la aplicación. SI el usuario desea desinstalar el producto, puede ir a "Agregar/Eliminar programas", o simplemente puede hacer doble clic en uninstall.cmd. Los contenidos son:En un proyecto de instalación de Visual Studio, ¿cómo puedo generar un script de desinstalación?

%windir%\system32\msiexec /x {CC3EB7BF-DD82-48B9-8EC5-1B0B62B6D285} 

El GUID no es el código de producto del proyecto de instalación en Visual Studio.

ProductCode http://i32.tinypic.com/2uhwapy.jpg

Pero, a fin de que las actualizaciones funcionen correctamente, que tienen que incrementar el número de versión, cada vez que producir una nueva MSI. Y, si incremento el número de Versión, entonces también tengo que generar un nuevo Guid para el Código de Producto. Lo que significa que el archivo estático uninstall.cmd debe cambiar.

Como puedo dinámicamente generar un archivo por lotes que contiene el código de producto para el, en tiempo de compilación?

Respuesta

2

Este es el script que escribí que crea un uninstall.cmd. Se ejecuta como una acción personalizada durante la instalación.

var fso, ts; 
var ForWriting= 2; 
fso = new ActiveXObject("Scripting.FileSystemObject"); 

var parameters = Session.Property("CustomActionData").split("|"); 
var targetDir = parameters[0]; 
var productCode = parameters[1]; 

ts = fso.OpenTextFile(targetDir + "uninstall.cmd", ForWriting, true); 

ts.WriteLine("@echo off"); 
ts.WriteLine("goto START"); 
ts.WriteLine("======================================================="); 
ts.WriteBlankLines(1); 
ts.WriteLine(" Uninstall.cmd"); 
ts.WriteBlankLines(1); 
ts.WriteLine("======================================================="); 
ts.WriteBlankLines(1); 
ts.WriteLine(":START"); 
ts.WriteLine("@REM The uuid is the 'ProductCode' in the Visual Studio setup project"); 
ts.WriteLine("%windir%\\system32\\msiexec /x " + productCode); 
ts.WriteBlankLines(1); 
ts.Close(); 

El resultado es un archivo cmd que siempre tiene el código de producto actual en él.

La desventaja de esto es que? la secuencia de comandos que crea la desinstalación.cmd permanece en el directorio de instalación. No es un gran problema, pero no me gustan los desperdicios en el directorio de instalación. Todavía no he intentado hacer que el "createInstaller.js" se elimine automáticamente. Aquello podría funcionar.

EDITAR: sí, haciendo que el createInstaller.js auto-borrado funciona bien.

¡Voy a aceptar mi propia respuesta!

+1

Solución buena pero malditamente hacky, me pregunto acerca de Microsoft, los fabricantes de instalación que probé antes (como inno) estaba haciendo un archivo unistall automáticamente. – Cynede

+1

Sé que han pasado algunos años, pero por mi parte me gustaría saber exactamente cómo usaste esto, Cheeso. ¿Estás anulando el 'OnAfterInstall'? Si es así, ¿cómo está insertando el script allí? – jp2code

63

encontré esta solución here

"Uso de Visual Studio 2005/2008, que no es necesario escribir ningún código para agregar una opción de desinstalación para un proyecto de instalación (Sí sé que algunas personas pueden escribir código para hacer es)

1) en el proyecto de instalación -> ventanas del sistema de archivos -> Haga clic en “sistema de archivos en la máquina de destino” -> añadir una carpeta especial, seleccione la carpeta del sistema;

2) Dentro de esta carpeta del sistema Añadir .. un archivo Examinar para msiexec.exe desde la carpeta System32 locales y añadirlo Anulación de propiedades por defecto de este archivo de la siguiente manera:

Estado: = No instalado (asegúrese de poner 'No instalado' exactamente así, mismo caso y todo), Permanente: = True, Sistema: = True, transitiva: = True, Vital: = Falso.

3) Cree un nuevo acceso directo en el 'Menú de programa de usuarios', establezca el destino en la carpeta del sistema que creó en el paso 1. y apunte al msiexec.exe. Cambie el nombre del atajo a 'Desinstalar su aplicación'. Establezca la propiedad Arguments en/x {espacio} [ProductCode].

4) Generar el proyecto, hacer caso omiso de advertencia sobre el hecho de que msiexec deben ser excluidos, NO excluirlo o el proyecto de instalación suele construir.

La condición 'No instalado' y Permananet: = True asegurar que el msiexec.exe solamente se coloca en la carpeta del sistema como parte de la instalación si no existe aready, y no se elimina en una desinstalación - por lo tanto, es bastante seguro ignorar esa advertencia y solo intentarlo.

(basado en la descripción de slaphead)"

+1

Ahora que es muy útil y mucho más directo que el enfoque que tomé. – Cheeso

+8

Impresionante, funciona muy bien para mí en WinXP/Vista y Win7. Vale la pena señalar que, de acuerdo con el artículo vinculado a, si utiliza una versión de msiexec.exe MÁS ALTA que la plataforma de destino, hay problemas. Esto no es un problema para mí ya que sigo utilizando intencionalmente XP para compilar, pero obviamente si quieres que un instalador basado en Vista se ejecute en XP será un problema. –

+0

¡Excelente publicación! Exactamente lo que estaba buscando. – Martin

10

acabo de hacer this trabajo:.

añadir un archivo uninstall.bat a su proyecto el contenido del archivo es:

msiexec.exe /x %1 

Realice un acceso directo a ese archivo por lotes (por ejemplo, en Menú de programa del usuario), especifique en las propiedades del acceso directo, junto a Argumentos: [ProductCode].

+1

Puede deshacerse de la ventana negra usando 'start msiexec.exe/x% 1'; pero la ventana negra aún parpadea. – moala

+0

Probablemente 'start/B msiexec.exe/x% 1'. – MPelletier

+0

no, ni '/ b' ... – moala

1

una ligera variación en el enfoque del archivo por lotes. si no desea mostrar una ventana de comando, use un archivo wscript. suministro [ProductCode] como en los argumentos

<job> 
<?job debug="true" error="true" ?> 
<script language="JScript"> 
    var arg = []; 
    for (var i=0; i<WSH.Arguments.length; i++) { 
     arg.push(WSH.Arguments.Item(i)); 
    } 

    if (arg.length>0) { 
     var productcode = arg[0]; 
     var v = new ActiveXObject("Shell.Application"); 
     v.ShellExecute("msiexec.exe", "/x "+productcode, "", "open", 10); 
    } 

    WSH.Quit(0); 
</script> 
</job> 
0

cada vez que genera configuración, siempre cambie el código del producto. crea un atajo de desinstalador y encontrarás la técnica de paso del argumento de línea de comando para ordenar el corte. allí escribirás siempre el código de producto del código de producto "/ u" u necesitas escribir aquí siempre.

poner este código en el método principal de Program.cs presentar

[STAThread] 
     static void Main() 
     { 
      bool flag = true; 
      string[] arguements = Environment.GetCommandLineArgs(); 
      foreach (string str in arguements) 
      { 
       if ((str.Split('='))[0].ToLower() == "/u") 
       { 
        if (MessageBox.Show("Do you want to uninstall job board", "Are you Sure?", MessageBoxButtons.YesNo) == DialogResult.Yes) 
        { 
         flag = false; 
         RemoveRegSettings(); 
         RemoveIniFile(); 
         string guid = str.Split('=')[1]; 
         string path = Environment.GetFolderPath(Environment.SpecialFolder.System); 
         ProcessStartInfo si = new ProcessStartInfo(path + @"\msiexec.exe", "/i" + guid); 
         Process.Start(si); 
         Application.Exit(); 
         return; 
        } 
       } 
      } 
      // 

      //************************************************ 
      Application.EnableVisualStyles(); 
      Application.SetCompatibleTextRenderingDefault(false); 
1

realizo esta pregunta ya ha sido contestada, pero lo que hice fue crear un archivo por lotes con el siguiente contenido:

start msiexec.exe /x %1 

El uso de "inicio" evita que el símbolo del sistema permanezca abierto durante el proceso de desinstalación y el% 1 se reemplaza por el primer argumento que pasa al archivo de proceso por lotes cuando lo ejecuta.

Agregué el archivo por lotes a la carpeta de la aplicación y creé un atajo de menú que apunta al archivo por lotes. Si hace clic con el botón derecho en el acceso directo, selecciona Ventana de propiedades. Allí, añada el siguiente texto a la propiedad Argumentos:

[ProductCode] 

Después de construir y ejecutar el instalador, tendrá un acceso directo del menú de inicio que llama al archivo por lotes y pasa el código de producto como lo fue cuando esa versión de la aplicación fue construida. El usuario verá un mensaje preguntándole si el producto debe ser desinstalado.

El único inconveniente de esta solución es que si el usuario navega hacia la carpeta de la aplicación y hace doble clic en el archivo de proceso por lotes, el programa de desinstalación dará un error que indica que el paquete de instalación no existe.

Cuestiones relacionadas