![]() |
Registry: WOW6432NODE
Problem: Unter einem 64-Bit-Windows (bspw. XP oder Vista) werden Anfragen von 32-Bit und 64-Bit Programmen unterschiedlich beantwortet:
![]() Beispiel: Unsere (32-Bit) Anwendung möchte auf den Schlüssel "HKEY_LM\Software\Microsoft\Windows" zugreifen (Schreibzugriff). Tatsächlich aber wird die Anfrage von TRegistry umgeleitet, auf den Schlüssel "HKEY_LM\Software\WOW6432Node\Microsoft\Window s". D.h., der Wert wird in den Schlüssel "HKEY_LM\Software\WOW6432Node\Microsoft\Window s" geschrieben, statt in "KEY_LM\Software\Microsoft\Windows ". Lösung: Die TRegistry muss mit speziellen Zugriffsrechten geöffnet werden, um 32-Bit-Anwendungen expliziten Zugriff auf einen der beiden Schlüssel zu geben (also 32-Bit: "HKEY_LM\Software\WOW6432Node\..." oder 64-Bit: "HKEY_LM\Software\..."). Wichtig: Meine Lösungen gehen davon, dass das Programm über Abwärtskompatibilität verfügen soll, d.h. je nachdem, ob ein 64-Bit oder 32-Bit Windows entdeckt wurde, wird anders verfahren. Um herauszufinden, ob Windows 64-Bit installiert wurde, kann folgende Funktion (von ![]()
Delphi-Quellcode:
So, um jetzt ordentlich zugreifen zu können, müssen zwei neue Typen deklariert werden (
function IsWow64: Boolean;
type TIsWow64Process = function( // Type of IsWow64Process API fn Handle: Windows.THandle; var Res: Windows.BOOL ): Windows.BOOL; stdcall; var IsWow64Result: Windows.BOOL; // Result from IsWow64Process IsWow64Process: TIsWow64Process; // IsWow64Process fn reference begin // Try to load required function from kernel32 IsWow64Process := Windows.GetProcAddress( Windows.GetModuleHandle('kernel32'), 'IsWow64Process' ); if Assigned(IsWow64Process) then begin // Function is implemented: call it if not IsWow64Process( Windows.GetCurrentProcess, IsWow64Result ) then raise SysUtils.Exception.Create('IsWow64: bad process handle'); // Return result of function Result := IsWow64Result; end else // Function not implemented: can't be running on Wow64 Result := False; end; ![]()
Delphi-Quellcode:
Beispielcode für den LESE-Zugriff (32-Bit-Anwendung) auf einen Unterschlüssel von "HK_LM\Software\...":
const
KEY_WOW64_64KEY = $0100; KEY_WOW64_32KEY = $0200;
Delphi-Quellcode:
Der Schreibzugriff ist jetzt ein wenig aufwendiger, ich habe mir dazu eine kleine Function gebaut, die immer - je nach Bedarf - in den einen oder anderen Schlüssel schreibt. Läuft die Anwendung auf einem 32-Bit-Windows, wird der Standard-AccessMode zurückgegeben.
var
s1,s2: String; begin // Auf Schlüssel "HKEY_LM\Software\WOW6432Node\Microsoft\Windows" zugreifen (umgeleitet!) with TRegistry.Create do begin try RootKey := HKEY_LOCAL_MACHINE; if OpenKey('\Software\Microsoft\Windows', false) then begin s1 := ReadString(''); CloseKey; end; finally free; end; end; // Und jetzt auf den Schlüssel "HKEY_LM\Software\Microsoft\Windows" zugreifen with TRegistry.Create(KEY_ALL_ACCESS OR KEY_WOW64_64KEY) do begin try RootKey := HKEY_LOCAL_MACHINE; if OpenKey('\Software\Microsoft\Windows', false) then begin s2 := ReadString(''); CloseKey; end; finally free; end; end; Showmessage(s1 + #13 + s2); end; Dabei wird wird an die Function der zu schreibende Schlüsselname gegeben, also bspw. "HKEY_LM\Software\WOW6432Node\Microsoft\Window s" oder "HKEY_LM\Software\Microsoft\Windows". Der Witz ist jetzt, dass durch die Function tatsächlich auch in den angegebenen Schlüssel geschrieben wird, es erfolgt keine "Umleitung". Achtung: Beispiel verwendet Smartpos() der Unit ![]()
Delphi-Quellcode:
Eingebaut wird dass dann in den .Create-Aufruf von TRegistry:
function GetRegAccessMode(sOrtID: String): Cardinal;
begin // Bei 32-Bit-Windows kein spezieller Accessmode erforderlich if not Is64BitWindows then begin Result := KEY_ALL_ACCESS; exit; end; if SmartPos('Wow6432Node', sOrtID, false) > 0 then // 32-Bit-Wert schreiben? result := (KEY_ALL_ACCESS OR KEY_WOW64_32KEY) else result := (KEY_ALL_ACCESS OR KEY_WOW64_64KEY); // Alternativ: Mit pos() -> case-sensitive! { if Pos('Wow6432Node', sOrtID) > 0 then // 32-Bit-Wert schreiben? result := (KEY_ALL_ACCESS OR KEY_WOW64_32KEY) else result := (KEY_ALL_ACCESS OR KEY_WOW64_64KEY); } end;
Delphi-Quellcode:
Fertig!! :-)
var
AccessMode: Cardinal; sKey: String; begin sKey := '\Software\Microsoft\Windows'; AccessMode := GetRegAccessMode(sKey); with TRegistry.Create(AccessMode) do begin try {.........} finally free; end; end; [edit=CalganX]Code-Style und Ressourcenschutz. Mfg, CalganX[/edit] |
Re: Registry: WOW6432NODE
Zitat:
HKEY_LOCAL_MACHINE\Software HKEY_USERS\*\Software\Classes HKEY_USERS\*_Classes zugreifen will. ![]() Es gibt allerdings auch Schlüssel, die für alle Anwendungen (32 oder 64 Bit) gleich sind: ![]() Zitat:
![]() Auf jeden Fall wird das Schreiben von Anwendungen ziemlich ätzend auf dieser Ebene, da ständig die 64-Bit Varianten der Schlüssel ebenfalls abgefragt werden müssen. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:39 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz