首頁 後端開發 C#.Net教程 C# 32位元程式存取64位元註冊表的範例程式碼

C# 32位元程式存取64位元註冊表的範例程式碼

Mar 10, 2017 pm 02:14 PM


  我的上一篇文章已經闡述了“32位元程式和64位元程式在64位元平台上讀取\寫入註冊表的區別”,那麼接下來將要回答上篇所留下來的一個問題:32位元程式如何存取64位元系統登錄(即:64位元程式所存取的登錄位置)。

  我們已經知道:

    ①:本機模式64 位元程式運行在純模式下,並且存取鍵和儲存在以下註冊表子鍵中的值:HKEY_LOCAL_MACHINE\Software

#    ②:32 位元程式運行在WOW64 模式下,並且存取鍵和值儲存在下列登錄子項目中:HKEY_LOCAL_MACHINE\SoftCAL_MACHINE\SoftCAL_MACHINE \WOW6432nod

  那麼要實現32為程式存取64位元註冊表信息,還要知道如下概念:1:檔案系統轉向。 2:註冊表重定向(轉向)。 3:註冊表反射。

    ①:檔案系統轉向

    32 位元進程不能載入64位元Dll,64位元進程也不可以加載32位Dll。 Windows的系統目錄包含了所有安裝的應用程式和它們的Dll文件,根據我們所述  的規則,

    它應該被分為給64位元應用程式的目錄和給32位元應用程式的目錄。如果不這樣,我們就無法分辨32位元和64位元的Dll檔案。對於64位元應用程序,其 檔案通常被

    放在%windir%\system32和%programfiles%(例如:c:\program  files)。對於32位元應用程序,其檔案通常在%windir%\syswow64和

    C:\program files  (x86)下面。如果我們用32位元程式去存取%windir%\system32,不管我們用硬編碼還是其它的方式,系統都會自動地給我們

    轉向到%windir%\syswow64下面。這種轉向對於每個32位元應用程式預設都是開啟的。但是這種轉向對我們來說並不總是需要的。那我們可以在

    C#裡面呼叫相關的API來關閉和開啟這個轉向。常用的函數有3個:

        Wow64DisableWow64FsRedirection(關閉系統轉 系統轉向),

        Wow64EnableWow64FsRedirection(開啟系統轉向)。

    但是Wow64EnableWow64FsRedirection在巢狀使用的時候不可靠,所以通常用上面的 Wow64RevertWow64FsRedirection來開啟檔案系統轉向## 

  」功能。在C#中,我們可以利用DllImport直接呼叫這兩個函數。

    

②:註冊表重定向(轉向)

    若要支援的32 位元和64 位元註冊和程式共存狀態,WOW64 子系統提供32 位元程式使用的註冊表的另一個視圖。在 WOW64 子系統使用登錄機碼

    重定向截獲位元層級的登錄呼叫。註冊表重定向還可以確保註冊表呼叫被定向到在註冊表中正確的分支。

    當我們安裝新程式或Windows x64 版的電腦上執行程式時,所做的64 位元程式的登錄機碼會呼叫存取HKEY_LOCAL_MACHINE\Software 登錄子鍵

#    不重定向。 WOW64 截獲由 32 位元程式的登錄呼叫到 HKEY_LOCAL_MACHINE\Software,然後將它們重定向到

    HKEY_LOCAL_MACHINE\Software\WOW6432node 子鍵。  透過重定向僅 32 位元程式調用,WOW64 可確保程式始終寫入對應的登錄子鍵。

    註冊表重定向不要求程式碼修改,和此程序是對使用者透明。

   

 ③:註冊表反射

    反射使兩個相同的註冊表,以支援同時進行的本機器和WOW64 操作的實體副本的存在,

    開啟註冊表的64 位元節在所有時間和登錄機碼反射提供了一種容納32 位元的即時方法。

  簡單的了解了這些,下面說一下具體的

實作步驟:


    關閉64位元(檔案系統)的操作轉向

      取得操作Key值的「句柄

                   (禁止特定項目的登錄機碼反射)

      取得存取的Key值

              )

    開啟64位元(檔案系統)的操作轉向


#  【註:由於我們在程式中用了DllImport,所以要引入命名空間:System.Runtime.InteropServices】

  下面請看程式碼範例

#

1 using System;
  2  using System.Collections.Generic;
  3  using System.Linq;
  4  using System.Text;
  5  using Microsoft.Win32;
  6  using System.Runtime.InteropServices;
  7 
  8  namespace OperateRegistrationTable
  9 {
 10     class Programe
 11     {
 12         static void Main(string[] args)
 13         {
 14             string myParentKeyName = "HKEY_LOCAL_MACHINE";
 15             string mySubKeyName = @"SOFTWARE\EricSun\MyTestKey";
 16             string myKeyName = "MyKeyName";
 17 
 18             string value = string.Empty;
 19             value = Utility.Get64BitRegistryKey(myParentKeyName, mySubKeyName, myKeyName);
 20             Console.WriteLine("The Value is: {0}", value);
 21         }
 22     }
 23 
 24     public class Utility
 25     {
 26         #region 32位程序读写64注册表
 27 
 28         static UIntPtr HKEY_CLASSES_ROOT = (UIntPtr)0x80000000;
 29         static UIntPtr HKEY_CURRENT_USER = (UIntPtr)0x80000001;
 30         static UIntPtr HKEY_LOCAL_MACHINE = (UIntPtr)0x80000002;
 31         static UIntPtr HKEY_USERS = (UIntPtr)0x80000003;
 32         static UIntPtr HKEY_CURRENT_CONFIG = (UIntPtr)0x80000005;
 33 
 34         // 关闭64位(文件系统)的操作转向
 35          [DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
 36         public static extern bool Wow64DisableWow64FsRedirection(ref IntPtr ptr);
 37         // 开启64位(文件系统)的操作转向
 38          [DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
 39         public static extern bool Wow64RevertWow64FsRedirection(IntPtr ptr);    
 40    
 41         // 获取操作Key值句柄
 42          [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
 43         public static extern uint RegOpenKeyEx(UIntPtr hKey, string lpSubKey, uint ulOptions, 
                                  int samDesired, out IntPtr phkResult);
 44         //关闭注册表转向(禁用特定项的注册表反射)
 45         [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
 46         public static extern long RegDisableReflectionKey(IntPtr hKey);
 47         //使能注册表转向(开启特定项的注册表反射)
 48         [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
 49         public static extern long RegEnableReflectionKey(IntPtr hKey);
 50         //获取Key值(即:Key值句柄所标志的Key对象的值)
 51         [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
 52         private static extern int RegQueryValueEx(IntPtr hKey, string lpValueName, int lpReserved,
 53                                                   out uint lpType, System.Text.StringBuilder lpData,
 54                                                   ref uint lpcbData);
 55 
 56         private static UIntPtr TransferKeyName(string keyName)
 57         {
 58             switch (keyName)
 59             {
 60                 case "HKEY_CLASSES_ROOT":
 61                     return HKEY_CLASSES_ROOT;
 62                 case "HKEY_CURRENT_USER":
 63                     return HKEY_CURRENT_USER;
 64                 case "HKEY_LOCAL_MACHINE":
 65                     return HKEY_LOCAL_MACHINE;
 66                 case "HKEY_USERS":
 67                     return HKEY_USERS;
 68                 case "HKEY_CURRENT_CONFIG":
 69                     return HKEY_CURRENT_CONFIG;
 70             }
 71 
 72             return HKEY_CLASSES_ROOT;
 73         }
 74 
 75         public static string Get64BitRegistryKey(string parentKeyName, string subKeyName, string keyName)
 76         {
 77             int KEY_QUERY_VALUE = (0x0001);
 78             int KEY_WOW64_64KEY = (0x0100);
 79             int KEY_ALL_WOW64 = (KEY_QUERY_VALUE | KEY_WOW64_64KEY);
 80 
 81             try
 82             {
 83                 //将Windows注册表主键名转化成为不带正负号的整形句柄(与平台是32或者64位有关)
 84                 UIntPtr hKey = TransferKeyName(parentKeyName);
 85 
 86                 //声明将要获取Key值的句柄
 87                 IntPtr pHKey = IntPtr.Zero;
 88 
 89                 //记录读取到的Key值
 90                 StringBuilder result = new StringBuilder("".PadLeft(1024));
 91                 uint resultSize = 1024;
 92                 uint lpType = 0;
 93 
 94                 //关闭文件系统转向 
 95                 IntPtr oldWOW64State = new IntPtr();
 96                 if (Wow64DisableWow64FsRedirection(ref oldWOW64State))
 97                 {
 98                     //获得操作Key值的句柄
 99                     RegOpenKeyEx(hKey, subKeyName, 0, KEY_ALL_WOW64, out pHKey);
100 
101                     //关闭注册表转向(禁止特定项的注册表反射)
102                     RegDisableReflectionKey(pHKey);
103 
104                     //获取访问的Key值
105                     RegQueryValueEx(pHKey, keyName, 0, out lpType, result, ref resultSize);
106 
107                     //打开注册表转向(开启特定项的注册表反射)
108                     RegEnableReflectionKey(pHKey);
109                 }
110 
111                 //打开文件系统转向
112                 Wow64RevertWow64FsRedirection(oldWOW64State);
113 
114                 //返回Key值
115                 return result.ToString().Trim();
116             }
117             catch (Exception ex)
118             {
119                 return null;
120             }
121         }
122 
123         #endregion
124     }
125 }
登入後複製

#Get64BitRegistryKey函數的三個參數分別代表:主鍵名(如:HKEY_LOCAL_MACHINE等),子鍵名,Key名,傳回的是Key的Value(64位元系統登錄的鍵值),透過上面的方法就完全可以實現用32程式存取64位元系統登錄(即:64位元程式所存取的註冊表位置)。

 ###

以上是C# 32位元程式存取64位元註冊表的範例程式碼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
威爾R.E.P.O.有交叉遊戲嗎?
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

使用 C# 的活動目錄 使用 C# 的活動目錄 Sep 03, 2024 pm 03:33 PM

使用 C# 的 Active Directory 指南。在這裡,我們討論 Active Directory 在 C# 中的介紹和工作原理以及語法和範例。

C# 序列化 C# 序列化 Sep 03, 2024 pm 03:30 PM

C# 序列化指南。這裡我們分別討論C#序列化物件的介紹、步驟、工作原理和範例。

C# 中的隨機數產生器 C# 中的隨機數產生器 Sep 03, 2024 pm 03:34 PM

C# 隨機數產生器指南。在這裡,我們討論隨機數產生器的工作原理、偽隨機數和安全數的概念。

C# 資料網格視圖 C# 資料網格視圖 Sep 03, 2024 pm 03:32 PM

C# 資料網格視圖指南。在這裡,我們討論如何從 SQL 資料庫或 Excel 檔案載入和匯出資料網格視圖的範例。

C# 中的模式 C# 中的模式 Sep 03, 2024 pm 03:33 PM

C# 模式指南。在這裡,我們討論 C# 中模式的介紹和前 3 種類型,以及其範例和程式碼實作。

C# 中的質數 C# 中的質數 Sep 03, 2024 pm 03:35 PM

C# 質數指南。這裡我們討論c#中素數的介紹和範例以及程式碼實作。

C# 中的階乘 C# 中的階乘 Sep 03, 2024 pm 03:34 PM

C# 階乘指南。這裡我們討論 C# 中階乘的介紹以及不同的範例和程式碼實作。

c#多線程和異步的區別 c#多線程和異步的區別 Apr 03, 2025 pm 02:57 PM

多線程和異步的區別在於,多線程同時執行多個線程,而異步在不阻塞當前線程的情況下執行操作。多線程用於計算密集型任務,而異步用於用戶交互操作。多線程的優勢是提高計算性能,異步的優勢是不阻塞 UI 線程。選擇多線程還是異步取決於任務性質:計算密集型任務使用多線程,與外部資源交互且需要保持 UI 響應的任務使用異步。

See all articles