Зарегистрировать ключ HKCU с помощью CustomAction в проекте визуальной настройки?C#

Место общения программистов C#
Anonymous
Зарегистрировать ключ HKCU с помощью CustomAction в проекте визуальной настройки?

Сообщение Anonymous »

В моем файле Solution.slnx есть следующие проекты кода C#:
  • Простой проект VSTO .NET Framework 4.8.1, который работает хорошо
  • Простой проект ExcelDna, который добавляет в Excel некоторые служебные функции расширения, такие как SumByStyle. Он создал 32-битные и 64-битные файлы package.xll, и я убедился, что эти файлы перемещены по правильному пути, который Excel может прочитать, и все они работают правильно (если я добавляю их вручную в Excel)
  • Проект Installer-SetupProject (Microsoft Visual Studio Installer Projects 2022, последняя версия 3.0.0) для их упаковки
Чтобы динамически записывать в реестр для автозагрузки xll в Excel, не требуя каких-либо дополнительных действий пользователя после установки (с использованием VSTO и ExcelDna), я добавил проект библиотеки классов C#. Я реализовал код, унаследованный от установщика, и переопределил как установщик, так и деинсталлятор. Затем я назначил их CustomAction проекта установки.
Некоторые регистрационные коды реестра выглядят следующим образом:

Код: Выделить всё

public void RegisterOfficeExcelExtension()
{
WriteLog("Start RegisterOfficeExcelExtension");
LogCurrentContext();

using (RegistryKey officeRoot = Registry.CurrentUser.OpenSubKey(@"Software\\Microsoft\\Office", writable: true))
{
if (officeRoot == null)
{
WriteLog("Not found Office in HKCU");
return;
}

foreach (string version in officeRoot.GetSubKeyNames())
{
if (!Regex.IsMatch(version, @"^\d+(\.\d+)?$"))
continue;

using (RegistryKey versionKey = officeRoot.OpenSubKey(version, writable: true))
{
if (versionKey == null)
continue;

using (RegistryKey excelOptions = versionKey.CreateSubKey(@"Excel\\Options"))
{
if (excelOptions == null)
continue;

var existingValues = new HashSet(StringComparer.OrdinalIgnoreCase);

foreach (string valueName in excelOptions.GetValueNames())
{
existingValues.Add(valueName);
}

int index = 0;

foreach (string file in fullFilePathExt)
{
bool alreadyRegistered = false;

foreach (string valueName in excelOptions.GetValueNames())
{
string strValue = excelOptions.GetValue(valueName)?.ToString()?.Trim('"');

if (string.Equals(strValue, file, StringComparison.OrdinalIgnoreCase))
{
alreadyRegistered = true;
WriteLog($"File: {file} Key: {valueName}");
break;
}
}

if (!alreadyRegistered)
{
string newKeyName;

do
{
newKeyName = index == 0 ? "OPEN" : $"OPEN{index}";
index++;
} while (existingValues.Contains(newKeyName));

excelOptions.SetValue(newKeyName, file, RegistryValueKind.String);
existingValues.Add(newKeyName);

string regPath = $@"HKCU\\Software\\Microsoft\\Office\\{version}\\Excel\\Options";
WriteLog($"KeyCreated: '{newKeyName}' Value: '{file}' At: {regPath}");
}
}
}
}
}
}

WriteLog("End RegisterOfficeExcelExtension");
}
Этот цикл предназначен только для иллюстрации; не нужно в нем обо всем подробно рассказывать.
Конкретно реестр я напишу в HKCU

Код: Выделить всё

Computer\\HKEY_CURRENT_USER\\Software\\Microsoft\\Office\\16.0\\Excel\\Options
Создайте новый строковый ключ с именем ключа = OPEN, и значением будет точный абсолютный путь к файлам package.xll.
Да, они работают отлично, без каких-либо ошибок.
Но когда я запускаю -> Выполнить -> regedit -> Enter и проверяю ключи по адресу:

Код: Выделить всё

Computer\\HKEY_CURRENT_USER\\Software\\Microsoft\\Office\\16.0\\Excel\\Options
не записывается. Я также проверил свой файл журнала, и все ключи были успешно записаны.
Поэтому я зарегистрировался

Код: Выделить всё

Computer\\HKEY_USERS\\S-1-5-18\\Software\\Microsoft\\Office\\16.0\\Excel\\Options
и, черт возьми, там были написаны все ключи. Поскольку установщик Microsoft MSI, похоже, работает в другом контексте, чем HKCU, он не может писать в HKCU.
Я боролся, искал, искал, спрашивал AI и пробовал все доступные сегодня продвинутые технологии, но все безрезультатно. Я также рассмотрел другие решения для установки, но они либо устарели (например, WiX v3), больше не поддерживаются, либо требуют оплаты. Поэтому, если у вас есть опыт или лучшее решение, пожалуйста, просветите меня.

Вернуться в «C#»