Как получить доступ к реестру удаленной машины в Inno Setup - PullRequest
0 голосов
/ 20 октября 2011

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

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

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

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

Ответы [ 2 ]

1 голос
/ 20 октября 2011

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

  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 по этим функциям .

0 голосов
/ 20 октября 2011

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

...