狠狠色丁香婷婷综合尤物/久久精品综合一区二区三区/中国有色金属学报/国产日韩欧美在线观看 - 国产一区二区三区四区五区tv

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

C# 32位程序訪問64位系統(tǒng)注冊表

admin
2021年2月18日 18:28 本文熱度 3707

  我的上一篇文章已經(jīng)闡述了“32位程序和64位程序在64位平臺上讀\寫注冊表的區(qū)別”,那么接下來將要回答上篇所留下來的一個問題:32位程序如何訪問64位系統(tǒng)注冊表(即:64位程序所訪問的注冊表位置)。

  我們已經(jīng)知道:

    ①:本機模式 64 位程序運行在純模式下,并且訪問鍵和存儲在以下注冊表子鍵中的值:HKEY_LOCAL_MACHINE\Software

    ②:32 位程序運行在 WOW64 模式下,并且訪問鍵和值存儲在以下注冊表子項中:HKEY_LOCAL_MACHINE\Software\WOW6432nod

  那么要實現(xiàn)32為程序訪問64位注冊表信息,還要知道如下概念:1:文件系統(tǒng)轉(zhuǎn)向。2:注冊表重定向(轉(zhuǎn)向)。3:注冊表反射。

    ①:文件系統(tǒng)轉(zhuǎn)向

    32 位進程不能加載64位Dll,64位進程也不可以加載32位Dll。Windows的系統(tǒng)目錄包含了所有安裝的應用程序和它們的Dll文件,根據(jù)我們所述 的規(guī)則,

    它應該被分為給64位應用程序的目錄和給32位應用程序的目錄。如果不這樣,我們就無法區(qū)分32位和64位的Dll文件。對于64位應用程序,其 文件通常被

    放在%windir%\system32和%programfiles%(比如:c:\program files)。對于32位應用程序,其文件通常在%windir%\syswow64和

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

    轉(zhuǎn)向到%windir%\syswow64下面。這種轉(zhuǎn)向?qū)τ诿總€32位應用程序默認都是打開的。但是這種轉(zhuǎn)向?qū)τ谖覀儊碚f并不總是需要的。那么我們可以在

    C#里面調(diào)用相關的API來關閉和打開這種轉(zhuǎn)向。常用的函數(shù)有3個:

        Wow64DisableWow64FsRedirection(關閉系統(tǒng)轉(zhuǎn) 向),

        Wow64RevertWow64FsRedirection(打開系統(tǒng)轉(zhuǎn)向),

        Wow64EnableWow64FsRedirection(打 開系統(tǒng)轉(zhuǎn)向)。

    但是Wow64EnableWow64FsRedirection在嵌套使用的時候不可靠,所以通常用上面的 Wow64RevertWow64FsRedirection來打開文件系統(tǒng)轉(zhuǎn)向

    功能。在C#中,我們可以利用DllImport直接調(diào)用這兩個函數(shù)。

    ②:注冊表重定向(轉(zhuǎn)向)

    若要支持的 32 位和 64 位 COM 注冊和程序共存狀態(tài),WOW64 子系統(tǒng)提供 32 位程序使用的注冊表的另一個視圖。在 WOW64 子系統(tǒng)使用注冊表

    重定向截獲位級別的注冊表調(diào)用。注冊表重定向還可以確保注冊表調(diào)用被定向到在注冊表中正確的分支。
    當我們安裝新程序或 Windows x64 版的計算機上運行程序時,所做的 64 位程序的注冊表調(diào)用訪問 HKEY_LOCAL_MACHINE\Software 注冊表子鍵

    不重定向。WOW64 截獲由 32 位程序的注冊表調(diào)用到 HKEY_LOCAL_MACHINE\Software,然后將它們重定向到

    HKEY_LOCAL_MACHINE\Software\WOW6432node 子鍵。 通過重定向僅 32 位程序調(diào)用,WOW64 可確保程序始終寫入相應的注冊表子鍵。

    注冊表重定向不要求程序代碼修改,和此過程是對用戶透明。

    ③:注冊表反射

    反射使兩個相同的注冊表,以支持同時進行的本機和 WOW64 操作的物理副本的存在,

    打開注冊表的 64 位節(jié)在所有時間和注冊表反射提供了一種容納 32 位的實時方法。

 

  簡單的了解了這些,下面說一下具體的實現(xiàn)步驟:

    關閉64位(文件系統(tǒng))的操作轉(zhuǎn)向

      獲得操作Key值的句柄

        關閉注冊表轉(zhuǎn)向(禁止特定項的注冊表反射)

      獲取訪問的Key值

        打開注冊表轉(zhuǎn)向(開啟特定項的注冊表反射)

    開啟64位(文件系統(tǒng))的操作轉(zhuǎn)向

 

  【注:由于我們在程序中用了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位(文件系統(tǒng))的操作轉(zhuǎn)向
35   [DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
36 public static extern bool Wow64DisableWow64FsRedirection(ref IntPtr ptr);
37 // 開啟64位(文件系統(tǒng))的操作轉(zhuǎn)向
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 //關閉注冊表轉(zhuǎn)向(禁用特定項的注冊表反射)
45 [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
46 public static extern long RegDisableReflectionKey(IntPtr hKey);
47 //使能注冊表轉(zhuǎn)向(開啟特定項的注冊表反射)
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注冊表主鍵名轉(zhuǎn)化成為不帶正負號的整形句柄(與平臺是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 //關閉文件系統(tǒng)轉(zhuǎn)向
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 //關閉注冊表轉(zhuǎn)向(禁止特定項的注冊表反射)
102 RegDisableReflectionKey(pHKey);
103
104 //獲取訪問的Key值
105 RegQueryValueEx(pHKey, keyName, 0, out lpType, result, ref resultSize);
106
107 //打開注冊表轉(zhuǎn)向(開啟特定項的注冊表反射)
108 RegEnableReflectionKey(pHKey);
109 }
110
111 //打開文件系統(tǒng)轉(zhuǎn)向
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函數(shù)的三個參數(shù)分別代表:主鍵名(如:HKEY_LOCAL_MACHINE等),子鍵名,Key名,返回的是Key的Value(64位系統(tǒng)注冊表的鍵值),通過上面的方法就完全可以實現(xiàn)用32程序訪問64位系統(tǒng)注冊表(即:64位程序所訪問的注冊表位置)。

該文章在 2021/2/18 18:28:44 編輯過
關鍵字查詢
相關文章
正在查詢...
點晴ERP是一款針對中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內(nèi)大量中小企業(yè)的青睞。
點晴PMS碼頭管理系統(tǒng)主要針對港口碼頭集裝箱與散貨日常運作、調(diào)度、堆場、車隊、財務費用、相關報表等業(yè)務管理,結(jié)合碼頭的業(yè)務特點,圍繞調(diào)度、堆場作業(yè)而開發(fā)的。集技術的先進性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點晴WMS倉儲管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質(zhì)期管理,貨位管理,庫位管理,生產(chǎn)管理,WMS管理系統(tǒng),標簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務都免費,不限功能、不限時間、不限用戶的免費OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved