Недавно мне нужно было автоматизировать установку Natural Docs через Кетарин. Я мог предположить, что он был установлен по пути по умолчанию (%ProgramFiles(x86)%\Natural Docs
), но решил использовать безопасный подход. К сожалению, даже если установщик создал ключ на HKLM\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall
, ни одно из его значений не привело меня к поиску установочного каталога.
Ответ Штейна предлагает функцию AppSearch MSI, и это выглядит интересно, но, к сожалению, установщик MSI Natural Docs не предоставляет таблицу подписей для его работы.
Поэтому я решил поискать в реестре любую ссылку на установочный каталог Natural Docs, и я нашел ее в ключе HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components
.
Я разработал Reg Class на C# для Ketarin, который допускает рекурсию. Поэтому я просматриваю все значения через HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components
, и если исполняемый файл основного приложения (NaturalDocs.exe) находится в одном из значений подразделов, он извлекается (C:\Program Files (x86)\Natural Docs\NaturalDocs.exe
становится C:\Program Files (x86)\Natural Docs
) и добавляется в переменную системной среды %PATH% (так что я могу вызвать " NaturalDocs.exe" напрямую вместо использования полного пути).
«Класс» реестра (на самом деле функции) можно найти на 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;
}
}
}
Даже если вы не используете Ketarin, вы можете легко вставить функцию и создать ее с помощью Visual Studio или CSC.
Можно использовать более общий подход, используя RegClassVBS, который допускает рекурсию ключей реестра и не зависит от .NET. Платформа фреймворка или процессы сборки.
Обратите внимание, что процесс перечисления ключа компонентов может сильно нагружать ЦП. В приведенном выше примере есть параметр «Длина», который вы можете использовать, чтобы показать пользователю некоторый прогресс (может быть, что-то вроде «i from (subKeysName.Length — 1) оставшихся ключей» — будьте изобретательны). Аналогичный подход можно использовать в RegClassVBS.
Оба класса (RegClassCS и RegClassVBS) имеют документацию и примеры, которые могут вам помочь, и вы можете использовать их в любом программном обеспечении и внести свой вклад в их разработку, сделав коммит в репозитории git и (конечно) открыв вопрос на его github. страницы, если вы обнаружите какую-либо проблему, которую не смогли решить самостоятельно, чтобы мы могли попытаться воспроизвести проблему, чтобы выяснить, что мы можем с ней сделать. знак равно
person
eduardomozart
schedule
29.12.2017