Почему мой сценарий Inno Setup не может обнаружить 32-битные или 64-битные приложения в реестре Uninstall?

Вопрос или проблема

Я использую Inno Setup, чтобы проверить, установлены ли определённые приложения (начинающиеся с “XYZ”) на системе, ищя ключи реестра Uninstall. Мой скрипт проверяет как 32-битные, так и 64-битные разделы Uninstall, но он не всегда находит приложения, особенно когда ищет 32-битные приложения на 64-битной системе или наоборот.

Например, код, похоже, вообще не находит Notepad++ согласно логу, эта запись существует в моем реестре, но лог не показывает её;
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Notepad++

function IsXYZInstalled: Boolean;
var
  KeyNames: array[0..3] of String;
  i, j: Integer;
  SubkeyNames: TArrayOfString;
  SubkeyNames2: TArrayOfString;
  DisplayName: String;
begin
  Result := False;
  


  // Инициализировать массив путей реестра для ключей Uninstall
  KeyNames[0] := 'Software\Microsoft\Windows\CurrentVersion\Uninstall';
  KeyNames[1] := 'Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall';
 
  
  
  // Перебирать каждый путь реестра
  for i := 0 to 1 do
  begin
  log('начать HKEY_CURRENT_USER USER '+KeyNames[i]);
    // Получить список подкладеров (каждый представляет установленное приложение)
    if RegGetSubkeyNames(HKEY_CURRENT_USER, KeyNames[i], SubkeyNames) then
    begin
      // Перебирать каждый подкласс
      for j := 0 to GetArrayLength(SubkeyNames) - 1 do
      begin
        log (inttostr(j)+ ' ' +KeyNames[i] + '\' + SubkeyNames[j]);
          log(DisplayName);
          
        // Попробовать прочитать значение DisplayName для каждого подкласса
        if RegQueryStringValue(HKEY_CURRENT_USER, KeyNames[i] + '\' + SubkeyNames[j], 'DisplayName', DisplayName) then
        begin
          // Проверить, начинается ли DisplayName с "XYZ"
          if Pos('XYZ', DisplayName) = 1 then
          begin
            Result := True;
            Exit;
          end;
        end;
      end;
    end;
  end;
            
  // Перебирать каждый путь реестра
  for i := 0 to 1 do
  begin
  log('НАЧАЛО HKEY_LOCAL_MACHINE\'+KeyNames[i]);
    // Получить список подкладеров (каждый представляет установленное приложение)
    if RegGetSubkeyNames(HKEY_LOCAL_MACHINE, KeyNames[i], SubkeyNames2) then
    begin
      // Перебирать каждый подкласс
      for j := 0 to GetArrayLength(SubkeyNames2) - 1 do
      begin
        log (inttostr(j)+ ' HKEY_LOCAL_MACHINE ' +KeyNames[i] + '\' + SubkeyNames2[j]);
        // Попробовать прочитать значение DisplayName для каждого подкласса
        if RegQueryStringValue(HKEY_LOCAL_MACHINE, KeyNames[i] + '\' + SubkeyNames2[j], 'DisplayName', DisplayName)            then
        begin
        log (inttostr(j)+ ' !HKEY_LOCAL_MACHINE ' +KeyNames[i] + '\' + SubkeyNames2[j]+'\'+DisplayName);
          // Проверить, начинается ли DisplayName с "XYZ"
          if Pos('XYZ', DisplayName) = 1 then
          begin
            Result := True;
            Exit;
          end;
        end;
      end;
    end;
  end;
  
end;

Ответ или решение

Ваш Inno Setup скрипт может не обнаруживать 32-разрядные или 64-разрядные приложения в реестре, по нескольким причинам, связанным с архитектурными нюансами Windows и некоторыми особенностями вашего кода. В этом ответе мы подробно рассмотрим причины и предложим решения.

1. Архитектурные аспекты Windows

Существует различие между 32-разрядными и 64-разрядными приложениями в контексте работы с реестром в Windows. 64-разрядные ОС в обязательном порядке поддерживают 32-разрядные приложения, но информация о них хранится в отдельном пространстве реестра — HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node. Ваш код должен работать с этим, и вы это правильно учли, однако есть несколько нюансов, которые могут вызвать проблемы.

2. Корректное обращение к реестру

По вашему коду видно, что вы дважды обращаетесь к HKEY_CURRENT_USER и HKEY_LOCAL_MACHINE, но не указали для каждого из этих случаев, к какому пространству реестра (32-разрядному или 64-разрядному) вы обращаетесь. Если ваш скрипт работает на 64-разрядной системе, а вы пытаетесь получить доступ к 32-разрядному ключу, вам нужно использовать соответствующие функции.

if RegGetSubkeyNames(HKEY_LOCAL_MACHINE, KeyNames[i], SubkeyNames) then

здесь должно быть обеспечено правильное обращение к 32/64-разрядным значениям.

3. Обработка реестра

Убедитесь, что вы правильно проверяете наличие нужного ключа. Например, возможно, что Notepad++ установлен как 32-разрядное приложение на 64-разрядной системе. Поэтому вам следует всегда проверять оба пространства реестра:

// Ищем в HKEY_LOCAL_MACHINE
for i := 0 to 1 do 
begin
  log('Поиск в HKEY_LOCAL_MACHINE ' + KeyNames[i]);
  if RegGetSubkeyNames(HKEY_LOCAL_MACHINE, KeyNames[i], SubkeyNames2) then 
  begin
    for j := 0 to GetArrayLength(SubkeyNames2) - 1 do 
    begin
      if RegQueryStringValue(HKEY_LOCAL_MACHINE, KeyNames[i] + '\' + SubkeyNames2[j], 'DisplayName', DisplayName) then 
      begin
        if Pos('XYZ', DisplayName) = 1 then 
        begin
          Result := True; // Найдено нужное приложение
          Exit;
        end;
      end;
    end;
  end;
end;

4. Логи и отладка

Обратите внимание на вашу отладочную информацию. Убедитесь, что вы логируете ключи реестра, которые проверяете. Это поможет вам увидеть, какие ключи обрабатываются, и поможет вам отследить, почему некоторые из них не находятся.

log('Проверка ключа: ' + KeyNames[i] + '\' + SubkeyNames[j]);

5. Права доступа

Не забудьте проверить, есть ли у вашего скрипта права доступа к соответствующим ключам реестра. Иногда это может стать причиной, по которой приложение не может получить нужную информацию.

Заключение

Для успешного обнаружения установленных приложений с помощью вашего Inno Setup скрипта требуется четко понимать и учитывать архитектурные особенности Windows, правильно обращаться к нужным разделам реестра и правильно обрабатывать их с помощью вашей логики в скрипте. Проведение тщательной отладки, внимание к деталям и грамотное логирование помогут выявить и устранить неполадки, а также обеспечат вам надежный инструмент для работы с установленными приложениями.

Оцените материал
Добавить комментарий

Капча загружается...