vb.net注册表重定向32位应用访问操作64位系统注册表

  • A+
所属分类:vb.net

在网上搜索了很多关于VB.NET注册表的文章,但是都是复制转载的没有经过测试,作为新手的我对应操作注册表有的头大。单纯的操作,还没有什么,但是我想32位系统和64位系统通用一个软件,做兼容。遇到注册表,32位软件在64位系统上读取注册表正常的也只能读取32应用的注册表。我的目的是相互读取

经过长时间的搜索加测试,终于有了结果,结果来之不易啊,在此做个笔记。

方法就是和网上说的关闭重定向和打开重定向来实现的。

第一步,在代码头部引入以下头文件

Imports System
Imports System.Collections.Generic
Imports System.Text
Imports Microsoft.Win32
Imports System.Runtime.InteropServices
复制

第二步,封装重定向函数,及声明代码

#Region "32位程序读写64注册表"
    Private Shared HKEY_CLASSES_ROOT As New UIntPtr(&H80000000UI)
    Private Shared HKEY_CURRENT_USER As New UIntPtr(&H80000001UI)
    Private Shared HKEY_LOCAL_MACHINE As New UIntPtr(&H80000002UI)
    Private Shared HKEY_USERS As New UIntPtr(&H80000003UI)
    Private Shared HKEY_CURRENT_CONFIG As New UIntPtr(&H80000005UI)
    ' 关闭64位(文件系统)的操作转向
    <DllImport("Kernel32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
    Public Shared Function Wow64DisableWow64FsRedirection(ByRef ptr As IntPtr) As Boolean
    End Function
    ' 开启64位(文件系统)的操作转向
    <DllImport("Kernel32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
    Public Shared Function Wow64RevertWow64FsRedirection(ByVal ptr As IntPtr) As Boolean
    End Function
    ' 获取操作Key值句柄
    <DllImport("Advapi32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
    Public Shared Function RegOpenKeyEx(ByVal hKey As UIntPtr, ByVal lpSubKey As String, ByVal ulOptions As UInteger, ByVal samDesired As Integer, <System.Runtime.InteropServices.Out()> ByRef phkResult As IntPtr) As UInteger
    End Function
    '关闭注册表转向(禁用特定项的注册表反射)
    <DllImport("Advapi32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
    Public Shared Function RegDisableReflectionKey(ByVal hKey As IntPtr) As Long
    End Function
    '使能注册表转向(开启特定项的注册表反射)
    <DllImport("Advapi32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
    Public Shared Function RegEnableReflectionKey(ByVal hKey As IntPtr) As Long
    End Function
    '获取Key值(即:Key值句柄所标志的Key对象的值)
    <DllImport("Advapi32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
    Private Shared Function RegQueryValueEx(ByVal hKey As IntPtr, ByVal lpValueName As String, ByVal lpReserved As Integer, ByRef lpType As UInteger, ByVal lpData As System.Text.StringBuilder, ByRef lpcbData As UInteger) As Integer
    End Function
    Private Shared Function TransferKeyName(ByVal keyName As String) As UIntPtr
        Select Case keyName
            Case "HKEY_CLASSES_ROOT"
                Return HKEY_CLASSES_ROOT
            Case "HKEY_CURRENT_USER"
                Return HKEY_CURRENT_USER
            Case "HKEY_LOCAL_MACHINE"
                Return HKEY_LOCAL_MACHINE
            Case "HKEY_USERS"
                Return HKEY_USERS
            Case "HKEY_CURRENT_CONFIG"
                Return HKEY_CURRENT_CONFIG
        End Select
        Return HKEY_CLASSES_ROOT
    End Function
    Public Shared Function Get64BitRegistryKey(ByVal parentKeyName As String, ByVal subKeyName As String, ByVal keyName As String) As String
        Dim KEY_QUERY_VALUE As Integer = (&H1)
        Dim KEY_WOW64_64KEY As Integer = (&H100)
        Dim KEY_ALL_WOW64 As Integer = (KEY_QUERY_VALUE Or KEY_WOW64_64KEY
        Try
            '将Windows注册表主键名转化成为不带正负号的整形句柄(与平台是32或者64位有关)
            Dim hKey As UIntPtr = TransferKeyName(parentKeyName)
            '声明将要获取Key值的句柄
            Dim pHKey As IntPtr = IntPtr.Zero
            '记录读取到的Key值
            Dim result As New StringBuilder("".PadLeft(1024))
            Dim resultSize As UInteger = 1024
            Dim lpType As UInteger = 0
            '关闭文件系统转向
            Dim oldWOW64State As New IntPtr()
            If Wow64DisableWow64FsRedirection(oldWOW64State) Then
                '获得操作Key值的句柄
                RegOpenKeyEx(hKey, subKeyName, 0, KEY_ALL_WOW64, pHKey)
                '关闭注册表转向(禁止特定项的注册表反射)
                RegDisableReflectionKey(pHKey)
                '获取访问的Key值
                RegQueryValueEx(pHKey, keyName, 0, lpType, result, resultSize)
                '打开注册表转向(开启特定项的注册表反射)
                RegEnableReflectionKey(pHKey)
            End If
            '打开文件系统转向
            Wow64RevertWow64FsRedirection(oldWOW64State)
            '返回Key值
            Return result.ToString().Trim()
        Catch ex As Exception
            Return Nothing
        End Try
    End Function
#End Region

复制

第三步;实例调用函数,例子

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
,测试请更改成你的对应注册表
Dim HKEY_KeyName As String = "HKEY_LOCAL_MACHINE"
Dim mySubKeyName As String = "SOFTWARE\AAAA4"
Dim myKeyName As String = "Service"

Dim value As String = String.Empty
value = Get64BitRegistryKey(HKEY_KeyName, mySubKeyName, myKeyName) '32位应用访问64位注册表,获取键值
Console.WriteLine(value)

'32位应用访问64位系统里面的32位应用注册表,系统默认访问,自动定向
'默认读取定向 HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node 下面
Dim va As String = My.Computer.Registry.GetValue("HKEY_LOCAL_MACHINE\SOFTWARE\AAAA4", "Service", "") '获取值
Console.WriteLine(va) '打印到输出
End Sub

复制

 

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: