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
.
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. =)
No lo he hecho, así que todavía necesito saber cómo obtener el directorio ... –
¿Con qué estás utilizando para crear el archivo MSI, cada idioma tendría sus especificaciones para obtener esa información? – CheGueVerra
I ' lo hice con InstallShield 11.5 (sé que está desactualizado ...). Proyecto BasicMSI. –