C# 32位/64位系統下程序讀寫註冊表之差異
摘要:微軟爲了讓32位程序不做任何修改就能運行在64的操作系統上,添加了一個十分重要的WOW64子系統來實現這個功能,WOW64是Windows-32-on-Windows-64的簡稱,從總體上來說,WOW64是一套基於用戶模式的動態鏈接庫,它可以把32位應用程序的發出的命令翻譯成64位系統可以接受的格式
用C#操作註冊表主要用到的兩個函數爲(已經滲透到下面的實例程序中,注:要引入Microsoft.Win32命名空間):
1:讀取鍵值-->Registry.LocalMachine.OpenSubKey(“..Key的路徑...”, true),這裏的第2個bool類型的參數含義爲:標誌打開的鍵值是否可以更改(即:是否可以用SetValue()給鍵賦值),然後調用GetValue()方法就能把鍵值讀取出來。
2:寫入鍵值-->Registry.LocalMachine.CreateSubKey("..Key的路徑..."),然後調用SetValue()寫入鍵值。
這裏主要講解一下32位程序和64位程序在64位平臺上讀\寫註冊表的區別【注:32位程序是-->Build的Platform target爲X86;64位程序-->Build的Platform target爲X64;並且VS2010在默認的狀態下爲X86編譯環境(即:32位)】
簡要複述一下理論基礎:微軟爲了讓32位程序不做任何修改就能運行在64的操作系統上,添加了一個十分重要的WOW64子系統來實現這個功能,WOW64是Windows-32-on-Windows-64的簡稱,從總體上來說,WOW64是一套基於用戶模式的動態鏈接庫,它可以把32位應用程序的發出的命令翻譯成64位系統可以接受的格式,即:WOW 層處理諸如在 32 位和 64 位模式之間切換處理器以及模擬 32 位系統的事務。
32位與64位特點的兩個重要表現方面爲:文件系統與註冊表。
文件系統:32位進程不能加載64位Dll,64位進程也不可以加載32位Dll。
註冊表:爲了防止註冊表鍵衝突,64位機器註冊表信息分成了兩個部分。一部分是專門給64位系統(即:64位程序)訪問的,另一部分是專門給32位系統(即:32位程序)訪問的,放在Wow6432Node下面。(Wow6432Node這個節 點存在於HKEY_LOCAL_MACHINE和HKEY_CURRENT_USER下面)
既然知道了註冊表信息分成了兩部分,那麼就可以想到:用32位程序和64位程序去操作註冊表的時候會操作不同位置的註冊表信息。下面例子可以充分證明這種說法。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Win32;
namespace OperateRegistrationTable
{
class Programe
{
static void Main(string[] args)
{
OperatingRegistryKey();
}
public static void OperatingRegistryKey()
{
string keyValue = string.Empty;
try
{
//向註冊表中寫信息
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\EricSun\MyTestKey", true))
{
if (key == null)
{
using (RegistryKey myKey = Registry.LocalMachine.CreateSubKey(@"SOFTWARE\EricSun\MyTestKey"))
{
myKey.SetValue("MyKeyName", "Hello EricSun." + DateTime.Now.ToString());
}
}
else
{
key.SetValue("MyKeyName", "Hello EricSun." + DateTime.Now.ToString());
}
}
//讀取註冊表信息
using (RegistryKey currentKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\EricSun\MyTestKey", false))
{
if (currentKey == null)
{
Console.WriteLine("Hello EricSun, The Key you tried to open doesn't exist.");
}
else
{
keyValue = currentKey.GetValue("MyKeyName").ToString();
Console.WriteLine("The Key Value is: {0}", keyValue);
}
}
}
catch (Exception ex)
{ }
}
}
}
將此段程序在X86(32位)平臺下編譯、運行,會發現在註冊表的WOW6432Node節點下創建了子鍵:
EricSun\MyTestKey,並且填充了鍵MyKeyName的值(用時間加以區分其值),而在SoftWare的第一層子節點中並沒有發現此EricSun。可以確定32位程序是操作註冊表信息是放在WOW6432Node節點下的。
若我們對這段程序不做任何修改,在X64(或Any Cpu)的平臺下編譯、運行的話,會發現在註冊表的SoftWare節點的第一層子節點中創建出了EricSun節點(並在此節點下創建相應的註冊表信息),然後我們用同樣的程序去讀註冊表的時候也會發現他們讀取的地方不同(以程序中的時間信息加以區分)