|
Antwort |
Registriert seit: 1. Nov 2003 182 Beiträge Delphi 2007 Professional |
#1
Problem: Unter einem 64-Bit-Windows (bspw. XP oder Vista) werden Anfragen von 32-Bit und 64-Bit Programmen unterschiedlich beantwortet: MSDN
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 hier) verwendet werden:
Delphi-Quellcode:
So, um jetzt ordentlich zugreifen zu können, müssen zwei neue Typen deklariert werden (MSDN):
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 FastStrings, da SmartPos() nicht case-sensitive ist. Das Beispiel kann natürlich auch mit Pos() benutzt werden.
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] |
Zitat |
Registriert seit: 1. Nov 2003 182 Beiträge Delphi 2007 Professional |
#2
Zitat von Luckie:
Dann könnte ich den Code eventuell für meinen Usermanager gebrauchen. Muss ich mal gucken.
HKEY_LOCAL_MACHINE\Software HKEY_USERS\*\Software\Classes HKEY_USERS\*_Classes zugreifen will. Link Es gibt allerdings auch Schlüssel, die für alle Anwendungen (32 oder 64 Bit) gleich sind: MSDN
Zitat:
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\HCP
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography \Calais\Current HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography \Calais\Readers HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography \Services HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\CTF\SystemSh ared HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\CTF\TIP HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\DFS HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Driver Signing HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\EnterpriseCe rtificates HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSMQ HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Non-Driver Signing HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\RAS HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Software\Mic rosoft\Shared Tools\MSInfo HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SystemCertif icates HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\TermServLice nsing HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Transaction Server HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontDpi HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontMapper HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontSubstitutes HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Ports HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Curr entVersion\Control Panel\Cursors\Schemes HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Curr entVersion\Group Policy HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Curr entVersion\Policies HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Curr entVersion\Setup HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Curr entVersion\Setup\OC Manager HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Curr entVersion\Telephony\Locations HKEY_LOCAL_MACHINE\SOFTWARE\Policies 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. |
Zitat |
Ansicht |
Linear-Darstellung |
Zur Hybrid-Darstellung wechseln |
Zur Baum-Darstellung wechseln |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
LinkBack URL |
About LinkBacks |