Как получить доступ к реестру удаленной машины в Inno Setup

#registry #inno-setup #pascal #remote-registry

#реестр #inno-setup #паскаль #удаленный реестр

Вопрос:

У меня есть установщики Inno Setup, которые я использую для обновления компьютеров на сайтах клиентов. Обычно есть два компьютера, но иногда три или более. Все подключены к сети, и ровно один без головы.

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

Однако иногда я сталкиваюсь с трудоемкими задачами, которые лучше всего выполнять ровно один раз, например, с задачами, требующими перезагрузки. В данном конкретном случае мне нужно определить, установлена ли у меня неработающая версия UltraVNC, и лучший известный мне способ — запросить реестр на безголовой рабочей станции. К сожалению, RegQueryStringValue не предоставляет опции для запроса реестров на удаленных компьютерах.

Как это сделать?

Ответ №1:

Эта проблема осложняется двумя вещами:

  1. UltraVNC устанавливается в 64-разрядном представлении реестра в 64-разрядной Windows, поэтому нам нужно запросить оба представления, и
  2. RemoteRegistry не запускается по умолчанию в Windows Vista и более поздних версиях.

Это то, что я придумал:

 function RegConnectRegistry(machineName: String; hKeyRoot:Integer; var phKey: Integer): integer;
  external 'RegConnectRegistryA@Advapi32.dll';
function RegOpenKeyEx(hKeyRoot:Integer; subkey:string; reserved, access:integer; var phKey: Integer): integer;
  external 'RegOpenKeyExA@Advapi32.dll';
function RegQueryValueEx(hKey:Integer; value: String; reserved: integer; var pType: integer; data: string; var pDataLen:integer): integer;
  external 'RegQueryValueExA@Advapi32.dll';
function RegCloseKey(hKey:Integer): integer;
  external 'RegCloseKey@Advapi32.dll';
  

Тогда вызов функций относительно прост. Большая часть обработки ошибок была опущена для краткости. Кроме того, не предпринимается никаких попыток считывания значений, отличных от REG_SZ.

<target> является ли цель либо по имени, либо по IP-адресу. <key> и <value> являются удаленным ключом и значением для запроса.

 procedure CheckRemoteVNC();
var
  HKRM, key: Integer;
  data: string;
  dwType, dataLen, retVal: Integer;
begin
  data := '12345678901234567890'; { Padding. Digits so I can easily count how long it is. }
  dataLen := 20
  { Make sure the Remote Registry service is running }
  Exec('sc', ExpandConstant('\<target> start RemoteRegistry'), '', SW_HIDE, ewWaitUntilTerminated, retVal)
  RegConnectRegistry('<target>', HKEY_LOCAL_MACHINE, HKRM)
  if RegOpenKeyEx(HKRM, '<key>', 0, 1 {KEY_QUERY_VALUE}, key) = 2 {Bad registry entry} then
    { Try the 64-bit view. }
    retVal := RegOpenKeyEx(HKRM, '<key>', 0, 257 {0x101 == KEY_WOW64_64KEY | KEY_QUERY_VALUE}, key)
  RegQueryValueEx(Key, '<value>', 0, dwType, data, dataLen)
  data := Copy(data, 0, dataLen-1)

  { Deal with the data appropriately. }

  if key <> 0 then RegCloseKey(key)
  if HKRM <> 0 then RegCloseKey(HKRM)
end;
  

Более подробную информацию см. в документации Microsoft по этим функциям.

Ответ №2:

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

Комментарии:

1. Внешнее вспомогательное приложение, отличное от встроенных в Windows, является проблемой из-за политики компании. Я бы предпочел сделать это непосредственно в Pascal. Удаленное запуск приложения было решено. Psexec выглядит красиво, но это внешнее приложение, которое не поставляется с Windows, что означает, что это было бы больно.

2. Вспомогательное приложение может быть встроено в сам установщик и извлечено при необходимости.

3. Да, но это тоже не проблема. На сервер сборки должны быть добавлены собственные вспомогательные приложения, какими бы обыденными они ни были. Для сторонних помощников мы должны иметь возможность находить точно такую же версию в течение как минимум года после того, как мы в последний раз выпускали обновление с ее использованием.

4. То же самое относится к любому другому коду / части установки, не так ли?