2008-11-01 7 views
8

El MSI almacena el directorio de instalación para las futuras tareas de desinstalación.¿Cómo obtener el directorio de instalación?

El uso de la propiedad INSTALLPROPERTY_INSTALLLOCATION (es decir, "InstallLocation") solo funciona si el instalador ha establecido la propiedad ARPINSTALLLOCATION durante la instalación. Pero esta propiedad es opcional y casi nadie la usa.

¿Cómo podría recuperar el directorio de instalación?

Respuesta

2

Use una clave de registro para realizar un seguimiento de su directorio de instalación, de esa manera puede consultarlo cuando actualice y elimine el producto.

Usando WIX me gustaría crear un componente que crea la clave, justo después de la etiqueta Directy del directorio de instalación, la declaración

+0

No lo he hecho, así que todavía necesito saber cómo obtener el directorio ... –

+0

¿Con qué estás utilizando para crear el archivo MSI, cada idioma tendría sus especificaciones para obtener esa información? – CheGueVerra

+0

I ' lo hice con InstallShield 11.5 (sé que está desactualizado ...). Proyecto BasicMSI. –

0

me gustaría tratar de utilizar Installer.OpenProduct (Código de producto). Esto abre una sesión, en la que puede solicitar Propiedad ("TARGETDIR").

+1

Ya lo intenté: no funciona –

0

Pruebe esto: var sPath = this.Context.Parameters ["assemblypath"]. ToString();

0

Usaría MsiGetComponentPath() - necesita el IdProducto y un Id. De componente, pero obtendrá la ruta completa al archivo instalado; simplemente elija uno que vaya a la ubicación de su directorio de instalación. Si desea obtener el valor de un directorio para cualquier MSI aleatorio, no creo que haya una API que le permita hacer eso.

0

Como se indica en otra parte del hilo, normalmente escribo una clave de registro en HKLM para poder recuperar fácilmente el directorio de instalación para posteriores instalaciones.

En casos cuando estoy tratando con una configuración que no ha hecho esto, utilizo la función incorporada de Windows Installer AppSearch: http://msdn.microsoft.com/en-us/library/aa367578(v=vs.85).aspx para localizar el directorio de la instalación anterior especificando una firma de archivo para buscar.

Una firma de archivo puede consistir en el nombre del archivo, el tamaño del archivo y la versión del archivo y otras propiedades del archivo. Cada firma se puede especificar con un cierto grado de flexibilidad para que pueda encontrar diferentes versiones del mismo archivo, por ejemplo, especificando un rango de versión para buscar. Consulte la documentación del SDK: http://msdn.microsoft.com/en-us/library/aa371853(v=vs.85).aspx

En la mayoría de los casos, utilizo la aplicación principal EXE y establezco una firma estricta al buscar un rango de versión estrecha del archivo con la versión y la fecha correctas.

0

Recientemente necesité automatizar Natural Docs instalar a través de Ketarin. Podría suponer que se instaló en la ruta predeterminada (%ProgramFiles(x86)%\Natural Docs), pero decidí adoptar un enfoque seguro. Lamentablemente, incluso si el instalador creó una clave en HKLM\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall, nada de su valor me llevó a encontrar el directorio de instalación.

La respuesta de Stein sugiere la función AppSearch MSI, y parece interesante, pero lamentablemente el instalador de Natural Docs MSI no proporciona una tabla de Firma para sus trabajos de aproximación.

Así que decidí buscar en el registro para encontrar cualquier referencia al directorio de instalación de Natural Docs, y encontré uno en la clave HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components.

MSI Components Registry Key

he desarrollado una clase Reg en C# para Ketarin que permite la recursividad.Así que busco todos los valores a través de HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components y si el ejecutable de la aplicación Principal (NaturalDocs.exe) se encuentra en uno de los valores de subclaves, se extrae (C:\Program Files (x86)\Natural Docs\NaturalDocs.exe se convierte en C:\Program Files (x86)\Natural Docs) y se agrega a la variable de entorno del sistema% PATH% (Entonces puedo llamar " NaturalDocs.exe "directamente en lugar de usar la ruta completa).

La "clase" del Registro (funciones, en realidad) se puede encontrar en GitHub (RegClassCS).

System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo("NaturalDocs.exe", "-h"); 
startInfo.UseShellExecute = false; 
startInfo.CreateNoWindow = true; 

var process = System.Diagnostics.Process.Start (startInfo); 
process.WaitForExit(); 

if (process.ExitCode != 0) 
{ 
    string Components = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components"; 

    bool breakFlag = false; 

    string hKeyName = "HKEY_LOCAL_MACHINE"; 
    if (Environment.Is64BitOperatingSystem) 
    { 
     hKeyName = "HKEY_LOCAL_MACHINE64"; 
    } 

    string[] subKeyNames = RegGetSubKeyNames(hKeyName, Components); 
    // Array.Reverse(subKeyNames); 
    for(int i = 0; i <= subKeyNames.Length - 1; i++) 
    { 
     string[] valueNames = RegGetValueNames(hKeyName, subKeyNames[i]); 
     foreach(string valueName in valueNames) 
     { 
      string valueKind = RegGetValueKind(hKeyName, subKeyNames[i], valueName); 
      switch(valueKind) 
      { 
       case "REG_SZ": 
       // case "REG_EXPAND_SZ": 
       // case "REG_BINARY": 
        string valueSZ = (RegGetValue(hKeyName, subKeyNames[i], valueName) as String); 
        if (valueSZ.IndexOf("NaturalDocs.exe") != -1) 
        { 
         startInfo = new System.Diagnostics.ProcessStartInfo("setx", "path \"%path%;" + System.IO.Path.GetDirectoryName(valueSZ) + "\" /M"); 
         startInfo.Verb = "runas"; 

         process = System.Diagnostics.Process.Start (startInfo); 
         process.WaitForExit(); 

         if (process.ExitCode != 0) 
         { 
          Abort("SETX failed."); 
         } 

         breakFlag = true; 
        } 
        break; 

       /* 
       case "REG_MULTI_SZ": 
        string[] valueMultiSZ = (string[])RegGetValue("HKEY_CURRENT_USER", subKeyNames[i], valueKind); 

        for(int k = 0; k <= valueMultiSZ.Length - 1; k++) 
        { 
         Ketarin.Forms.LogDialog.Log("valueMultiSZ[" + k + "] = " + valueMultiSZ[k]); 
        } 
        break; 
       */ 

       default: 
        break; 
      } 

      if (breakFlag) 
      { 
       break; 
      } 
     } 

     if (breakFlag) 
     { 
      break; 
     } 
    } 
} 

Incluso si usted no utiliza Ketarin, puede pegar fácilmente la función y construirlo a través de Visual Studio o CSC.

Se puede tomar un enfoque más general usando RegClassVBS que permite la recursión de claves de registro y no depende de la plataforma de Framework .NET ni de los procesos de compilación.

Tenga en cuenta que el proceso de enumeración de la clave de componentes puede ser intenso para la CPU. El ejemplo anterior tiene un parámetro de Longitud, que puede usar para mostrar algún progreso al usuario (tal vez algo así como "i from (subKeysName.Length - 1) keys remaining" - sea creativo). Un enfoque similar se puede tomar en RegClassVBS.

Ambas clases (RegClassCS y RegClassVBS) tienen documentación y ejemplos que pueden guiarlo, y pueden usarlo en cualquier software y contribuir al desarrollo de ellos haciendo una confirmación en el repositorio git, y (por supuesto) abriendo un tema en sus páginas github si encuentra algún problema que no pueda resolver usted mismo, así podemos tratar de reproducir el problema para descubrir qué podemos hacer al respecto. =)

Cuestiones relacionadas