当前位置:编程学习 > C#/ASP.NET >>

C# 32和64对注册表的操作

RegistryKey rk = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows NT\\CurrentVersion\\PrinterPorts");
string[] pssc = rk.GetValueNames();


以上这段程序是获取32位下的系统安装的打印机信息  但是到了64位服务器上就读不到内容了。。求指导。。。 --------------------编程问答-------------------- 32 位和 64 位的注册表实际上是各自一套的,楼主不妨用用配置文件,如 ini。 --------------------编程问答--------------------
引用 1 楼 tcmakebest 的回复:
32 位和 64 位的注册表实际上是各自一套的,楼主不妨用用配置文件,如 ini。


我在读取的时候还要判断系统是否32位的。。我们这个项目这边制定要读取注册表。。。 --------------------编程问答-------------------- 用C#实现注册表的读\写是一件很容易的事情,在此不做详细的讲解。

  用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位程序去操作注册表的时候会操作不同位置的注册表信息。下面例子可以充分证明这种说法。

 1 using System;
 2  using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using Microsoft.Win32;
 6 
 7 namespace OperateRegistrationTable
 8 {
 9     class Programe
10     {
11         static void Main(string[] args)
12         {
13             OperatingRegistryKey();
14         }
15 
16         public static void OperatingRegistryKey()
17         {
18             string keyValue = string.Empty;
19             try
20             {
21                 //向注册表中写信息
22                 using (RegistryKey key = 
                     Registry.LocalMachine.OpenSubKey(@"SOFTWARE\EricSun\MyTestKey", true))
23                 {
24                     if (key == null)
25                     {
26                         using (RegistryKey myKey = Registry.LocalMachine.CreateSubKey(@"SOFTWARE\EricSun\MyTestKey"))
27                         {
28                             myKey.SetValue("MyKeyName", "Hello EricSun." + DateTime.Now.ToString());
29                         }
30                     }
31                     else
32                     {
33                         key.SetValue("MyKeyName", "Hello EricSun." + DateTime.Now.ToString());
34                     }
35                 }
36 
37                 //读取注册表信息
38                 using (RegistryKey currentKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\EricSun\MyTestKey", false))
39                 {
40                     if (currentKey == null)
41                     {
42                         Console.WriteLine("Hello EricSun, The Key you tried to open doesn't exist.");
43                     }
44                     else
45                     {
46                         keyValue = currentKey.GetValue("MyKeyName").ToString();
47                         Console.WriteLine("The Key Value is: {0}", keyValue);
48                     }
49                 }
50             }
51             catch (Exception ex)
52             { }
53         }
54     }
55 }
56
  将此段程序在X86(32位)平台下编译、运行,会发现在注册表的WOW6432Node节点下创建了子键:EricSun\MyTestKey,并且填充了键MyKeyName的值(用时间加以区分其值),而在SoftWare的第一层子节点中并没有发现此EricSun。可以确定32位程序是操作注册表信息是放在WOW6432Node节点下的

  若我们对这段程序不做任何修改,在X64(或Any Cpu)的平台下编译、运行的话,会发现在注册表的SoftWare节点的第一层子节点中创建出了EricSun节点(并在此节点下创建相应的注册表信息),然后我们用同样的程序去读注册表的时候也会发现他们读取的地方不同(以程序中的时间信息加以区分)

  总结:X64,(或者Any Cpu) Platform下的程序会操作64位机器存放注册表位置的注册表信息,X86 Platform下的程序会操作32位机器存放注册表位置的注册表信息(即:WOW6432Node节点下的注册表信息) --------------------编程问答-------------------- 怎么能不大改代码的情况下修改让其在64位系统下读取相应的注册表信息。。 --------------------编程问答--------------------
引用 2 楼 cxy521 的回复:
Quote: 引用 1 楼 tcmakebest 的回复:

32 位和 64 位的注册表实际上是各自一套的,楼主不妨用用配置文件,如 ini。


我在读取的时候还要判断系统是否32位的。。我们这个项目这边制定要读取注册表。。。

把程序编译选项改成 X86 模式,就是编译成 32 位的吧,运行没有多少差别。 --------------------编程问答--------------------
引用 5 楼 tcmakebest 的回复:
Quote: 引用 2 楼 cxy521 的回复:

Quote: 引用 1 楼 tcmakebest 的回复:

32 位和 64 位的注册表实际上是各自一套的,楼主不妨用用配置文件,如 ini。


我在读取的时候还要判断系统是否32位的。。我们这个项目这边制定要读取注册表。。。

把程序编译选项改成 X86 模式,就是编译成 32 位的吧,运行没有多少差别。


程序已经是32位的程序了。。但是运行在64位的服务器上。。。。。 --------------------编程问答--------------------
引用 6 楼 cxy521 的回复:
程序已经是32位的程序了。。但是运行在64位的服务器上。。。。。

真搞不懂,要读其他 64 位系统写的注册表吗?那就用 Any CPU 编译啊,运行的时候自动选择 32 还是 64 位 --------------------编程问答-------------------- 获取打印机列表这样:
PrinterSettings.InstalledPrinters --------------------编程问答--------------------
引用 7 楼 tcmakebest 的回复:
Quote: 引用 6 楼 cxy521 的回复:

程序已经是32位的程序了。。但是运行在64位的服务器上。。。。。

真搞不懂,要读其他 64 位系统写的注册表吗?那就用 Any CPU 编译啊,运行的时候自动选择 32 还是 64 位


这是一个产品。不知道客户的服务器是32的还是64的。最好是能做一个兼容
 if (Distinguish64or32System() == "32")
            {
                key = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows NT\\CurrentVersion\\PrinterPorts");
            }
            else
            {
                //key = RegUtil.GetValueWithRegView(RegistryHive.CurrentUser, "Software\\Microsoft\\Windows NT\\CurrentVersion\\PrinterPorts", RegistryView.Registry64);
                key = RegUtil.OpenSubKey(Registry.CurrentUser, "Software\\Microsoft\\Windows NT\\CurrentVersion", false, RegUtil.eRegWow64Options.KEY_WOW64_64KEY);
            }

            string[] pssc = key.GetValueNames();


试了一系列 方法貌似没有找到解决方案。
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,