65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 VB.NET 读取和写入 Windows 注册表的类

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.50/5 (22投票s)

2004 年 6 月 25 日

CPOL

6分钟阅读

viewsIcon

99946

downloadIcon

1354

读取和写入 Windows 注册表,克服 GetSetting 和 SaveSetting 带来的限制。

引言

本文介绍了如何使用 VB.NET 编写一个用于读取和写入 Windows 注册表的类。该类在我几个项目中都被证明非常有用。

注册表

随着 Windows 95 的发布,注册表的概念应运而生。注册表是 Windows 体系结构组件之一。它取代了以前版本的 Windows 中用于存储应用程序重要信息的旧 * .INI 文件。例如,每个应用程序都可以拥有自己的 *.INI 文件来存储其主窗口的初始尺寸和位置、使用的用户名和密码、最近打开的四个文件,以及各种偏好设置。到处都是 .INI 文件。因此,Windows 95 引入了注册表,一个集中且唯一的存储所有系统和应用程序设置的位置。

注册表由六个 *键* 组成(Windows NT/2000 和 XP 中是五个,因为这些操作系统没有 Hkey_Dyn_Data 键)。这六个键中有两个是基本键,另外四个是从这两个派生出来的(实际上它们是另外两个的别名)。注册表的组织结构如下图所示。

Hierarchy of the Windows Registry

图 1 - Windows 注册表层次结构

要检查这一点,您可以单击 Windows 的“开始”按钮,然后选择“运行...”,输入 regedit 并按 Enter。注册表编辑器将会出现。在左侧面板中,您将看到我刚才提到的六个键。

Registry Editor

图 2 - 注册表编辑器

每个键都以 HKEY 开头,代表 Key Handle。我们将这些键称为根键。每个根键都有子键。每个根键都与配置数据的某个方面相关,例如用户或计算机相关的设置。

  • HKEY_CLASSES_ROOT:注册表的此分支包含所有已注册文件类型的名称及其属性。换句话说,这里保存的信息可确保当您在 Windows 资源管理器中双击文件时,会打开正确的程序。此键是 HKEY_LOCAL_MACHINE\Software ** 子键的别名。
  • HKEY_CURRENT_USER:此键包含有关当前登录用户的配置信息。用户配置文件存储在这里:用户的文件夹、屏幕颜色和控制面板设置。此分支是 HKEY_USERS 键的别名。
  • HKEY_LOCAL_MACHINE:包含与所有用户的计算机相关的配置信息。
  • HKEY_USERS:此分支存储计算机上的所有用户配置文件。
  • HKEY_CURRENT_CONFIG:此键包含有关本地计算机在系统启动时使用的硬件配置文件的信息。
  • HKEY_DYN_DATA:此键仅在 Windows 9x/ME 中可用。Windows 98 中的某些信息必须存储在 RAM 中,因为它需要快速修改,并且无法等待注册表刷新到硬盘。所有这些数据都可以在此根键下找到。此分支是 Hkey_Local_Machine \Configs 的别名。

编码 CRegistry 类

GetSettingSaveSetting 是允许您读写注册表的函数。但它们只能让您在 HKEY_CURRENT_USER\Software\VBVBA 键中读写。在您的项目中,您可能希望像专业人士一样编写:在 HKEY_CURRENT_USER\Software\ 中。因此,我们不使用这些函数,而是使用 Win32 中的一个功能强大的对象,它没有限制。我们来看看。

首先,您导入 Microsoft.Win32 命名空间。这允许您使用 Registry 对象,该对象表示 Windows 注册表及其处理基本操作的方法。您知道该类将具有属性和方法,属性将是上面描述的六个主键,您可以访问它们的值来指定需要读取或写入的路径。我们需要的方法将是以下几种:一种用于在任何主键下创建子键(或多个嵌套子键),一种用于删除子键,一种用于写入,一种用于读取,以及一种用于删除注册表中的数据。

好了,这是公共属性。由于您可能需要从类外部使用它们——用于传递您的设置的完整路径——因此它们必须是公共的。

Public ReadOnly Property HKeyLocalMachine() As RegistryKey
    Get  
        Return Registry.LocalMachine 
    End Get 
End Property


Public ReadOnly Property HkeyClassesRoot() As RegistryKey 
    Get 
        Return Registry.ClassesRoot
    End Get 
End Property

//..and so on until you have the six keys
//.
//.

Public ReadOnly Property HKeyDynData() As RegistryKey
    Get 
        Return Registry.DynData
    End Get 
End Property

让我们来看方法。我们将编写 CreateSubKey 方法,用于在注册表中的任何主键下创建新的子键。

Public Function CreateSubKey(ByVal ParentKey As RegistryKey, _
                             ByVal SubKey As String) As Boolean 
    Try
        'create the specified subkey 
        ParentKey.CreateSubKey(SubKey)
        Return True 
    Catch e As Exception
        Return False
    End Try
End Function

现在,您可能会想如何使用此方法。假设您想在 HKEY_LOCAL_MACHINE\Software 子键下创建另一个子键,该子键实际上是软件供应商存储其应用程序设置的路径。如果您再次运行注册表编辑器并查看此子键(HKEY_LOCAL_MACHINE\Software),您很可能会找到大量的子键,每个子键都有一个软件公司的名称,如 Adobe、Apple Computer、McAfee、Microsoft、Novell 等。所以,让我们在其中创建一个我们自己的软件品牌子键,比如 MySoftCorp。您需要做的就是输入几行这样的代码:

'We are assuming our class is called CRegistry  
Dim objReg As New CRegistry
objReg.CreateSubKey(objReg.HKeyLocalMachine, "Software\MySoftCorp")

在此调用之后,HKEY_LOCAL_MACHINE\Software 下应该有一个名为 MySoftCorp 的新子键。我们所有的成功方法都将返回 True,否则返回 False。您可以在此处创建更多子键,每个应用程序一个。如果您的公司开发了两个应用程序,一个会计应用程序和一个股票市场应用程序,每个应用程序都应该在其自己的子键下安装其子键,位于 HKEY_LOCAL_MACHINE\Software\MySoftCorp 下。例如,您将拥有 HKEY_LOCAL_MACHINE\Software\MySoftCorp\AccountingAppHKEY_LOCAL_MACHINE\Software\MySoftCorp\StockMarketApp。如果像这样调用该方法,我们还可以一次创建多个子键。

objReg.CreateSubKey(objReg.HKeyLocalMachine, _
                     "Software\MySoftCorp\AccountingApp")

第二种方法是删除子键。代码如下:

Public Function DeleteSubKey(ByVal ParentKey As RegistryKey, _
                             ByVal SubKey As String) As Boolean 
        Try 
            'destroys the subkey and returns a False when the subkey doesn't 
            'exist 
            ParentKey.DeleteSubKey(SubKey, False)
            Return True
        Catch e As Exception
            Return False
        End Try
End Function

我们已经有了创建所有所需子键的机制,但我们需要编写一个方法来创建值并将其存储在子键中。查看任何子键,例如 HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion。您可以在右侧面板中看到一堆值。每个值都有一个名称、一个类型和一个数据。可能的数据类型如下: REG_SZ(可以是字符串或布尔值)、REG_EXPAND_SZ(可变长度文本字符串)、REG_DWORD(32 位整数)或 REG_MULTI_SZ(文本字符串数组)。要创建新的值名称并为其分配一个值,我们需要键、子键、要创建的值的名称以及值本身(数据)。这是 WriteValue 方法的代码:

Public Function WriteValue(ByVal ParentKey As RegistryKey, _
                           ByVal SubKey As String, _
                           ByVal ValueName As String, _
                           ByVal Value As Object) As Boolean 
    Dim Key As RegistryKey

    Try 
        'Open the given subkey 
        Key = ParentKey.OpenSubKey(SubKey, True)
        
        If Key Is Nothing Then 'when subkey doesn't exist create it 
            Key = ParentKey.CreateSubKey(SubKey)
        End If 

        'Once we have a handle to the key, set the value(the data) 
        Key.SetValue(ValueName, Value)

        Return True 
    Catch e As Exception
        Return False
    End Try 
End Function

注意:我们在方法参数中将 Value 声明为 Object,以便我们可以传递字符串或数值,并且对 Key.SetValue() 的调用将使用匹配的数据类型在注册表中写入该值。因此,我们不需要指定我们值的数据类型。很酷,不是吗?查看此示例以创建字符串或数值:

Dim strUsrName As String = "Sinhue"
'this value will be created as a REG_SZ(string) 
objReg.WriteValue(objReg.HKeyLocalMachine, _
                  "Software\MySoftCorp\StockMarketApp", _
                  "UserName", strUsrName)

Dim intMaxDocs As Integer = 10
'this value will be created as an REG_DWORD(integer) 
objReg.WriteValue(objReg.HKeyLocalMachine, _
                  "Software\MySoftCorp\StockMarketApp", _
                  "MaxDocsOpened", intMaxDocs)

接下来,我将向您展示一个从值读取数据的方法。如您所见,参数相同。我们将把数据作为引用参数返回给 Value 参数。

Public Function ReadValue(ByVal ParentKey As RegistryKey, _
                          ByVal SubKey As String, _
                          ByVal ValueName As String, _
                          ByRef Value As Object) As Boolean 
    Dim Key As RegistryKey

    Try
        'open the given subkey
        Key = ParentKey.OpenSubKey(SubKey, True)
        
        If Key Is Nothing Then 'when the key doesn't exist throw an 
                               'exception 
            Throw New Exception("the subkey doens't exist")
        End If 

        'Get the value 
        Value = Key.GetValue(ValueName)

        Return True 
    Catch e As Exception 
        Return False 
    End Try
End Function

最后,我们将添加一个删除值名称的方法:

Public Function DeleteValue(ByVal ParentKey As RegistryKey, _
                                ByVal SubKey As String, _
                                ByVal ValueName As String) As Boolean 
    Dim Key As RegistryKey

    Try 
        'open the given subkey 
        Key = ParentKey.OpenSubKey(SubKey, True)

        'when the key exists then delete the value 
        If Not Key Is Nothing Then 
            Key.DeleteValue(ValueName)
            Return True 
        Else 
            Return False
        End If
    Catch e As Exception
        Return False
    End Try

End Function

结论

好了,就这些了。我提供了该类的源代码,以及一个获取给定子键下所有子键的方法。我已将此类转换为 DLL,并在需要访问 Windows 注册表时将其添加到我的项目中。毫无疑问,代码还有很多改进的空间。我希望您觉得它和我有一样有用。

© . All rights reserved.