Question

Je Inno installateurs de configuration que j'utilise pour mettre à jour les ordinateurs sur les sites clients. En général, il y a deux ordinateurs, mais parfois trois ou plus. Tous sont mis en réseau, et exactement un est sans tête.

Il est relativement facile à exécuter le programme d'installation sur tous les rieuse (si c'est à l'opposé de sans tête?) Postes de travail, en cours d'exécution ainsi toutes les tâches associées à ces ordinateurs. Il y a aussi des tâches qui doivent être effectuées sur le poste de travail sans tête. En général, ceux-ci sont rapides, des tâches simples (copie de petits fichiers et le redémarrage des services) qui peuvent être exécutées plusieurs fois.

De temps en temps, cependant, je rencontre le temps de consommer des tâches qui sont mieux exécutées exactement une fois, telles que les tâches qui nécessitent un redémarrage. Dans ce cas particulier, je dois déterminer si j'ai une version brisée de UltraVNC installé, et la meilleure façon que je connaisse est d'interroger le registre sur le poste de travail sans tête. Malheureusement, RegQueryStringValue ne fournit pas d'options pour l'interrogation des registres sur des machines distantes.

Comment fait-on le faire?

Était-ce utile?

La solution

This issue is complicated by two things:

  1. UltraVNC installs itself in the 64-bit view of the registry on 64-bit Windows, so we need to query both views, and
  2. RemoteRegistry isn't running by default on Windows Vista and later.

This is what I came up with:

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';

Then, calling the functions is relatively straightforward. Most error handling has been omitted for conciseness. Also, no attempt is made to read non-REG_SZ values.

<target> is the target, either by name or by IP address. <key> and <value> are the remote key and value to query.

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;

See Microsoft's documentation on these functions for more details.

Autres conseils

Probably the easiest way is to write a small applet that uses the registry API directly to query the remote server and return an exit code to Inno with the result.
Another option is to use psexec or similar to run an app that does the work on the remote server itself.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top