访问注册表项“[KEY_NAME]”被拒绝

时间:2012-10-23 11:52:15

标签: vb.net registry unauthorizedaccessexcepti

我正在Visual Basic 2008中编写一个小程序,用于翻转注册表项中特定DWORD的值

有问题的注册表项是:

'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render\{91801674-82d9-459a-9358-6e5cf3d81d21}\FxProperties'

我正在操纵的dword是“ {e0a941a0-88a2-4df5-8d6b-dd20bb06e8fb},4

这是我写的用于设置DWORD值的代码行:

Dim keyString = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render\{91801674-82d9-459a-9358-6e5cf3d81d21}\FxProperties"
My.Computer.Registry.SetValue(keyString, "{ad75efc0-8f48-4285-bfa8-40fb036cdab2},2", "00000000")

但是我在运行时遇到 UnauthorizedAccessException ,声明“拒绝访问注册表项[KEY_NAME]。”

我使用管理员权限运行程序,将应用程序的清单更改为包括:

<requestedExecutionLevel level="highestAvailable" uiAccess="false" />

但这也不起作用。所以我搜索了几个论坛并尝试了这个:

Dim rkLM As RegistryKey = Registry.LocalMachine
Dim pRegKey As RegistryKey = rkLM.OpenSubKey("\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render\{91801674-82d9-459a-9358-6e5cf3d81d21}\FxProperties", True)
pRegKey.SetValue("{ad75efc0-8f48-4285-bfa8-40fb036cdab2},2", "00000000")

但是我向 NullReferenceException 引用了“对象引用没有设置为对象的实例。”

有没有办法可以修改那个密钥,而无需使用 SYSTEM 权限运行我的程序?

4 个答案:

答案 0 :(得分:2)

您应该在清单中尝试requireAdministrator,因为highestAvailable实际上可能不是管理员。

我也会尝试指定数据类型(在你的情况下我认为它是二进制的):

My.Computer.Registry.SetValue(keyString, _
"{ad75efc0-8f48-4285-bfa8-40fb036cdab2},2", _ 
"00000000", _
RegistryValueKind.Binary)

但是,您设置的值可能需要是一个字节数组(您可以尝试的其他内容)

答案 1 :(得分:1)

感谢Matt,我尝试用requireAdministrator运行它,但这也没有帮助。无论如何,我找到了解决方案,似乎问题在于我试图修改的注册表项的权限。

Full Control访问权限仅授予 TrustedInstaller 组,因此我也将Full Control授予管理员组中的用户。< / p>

我使用Sysinternals' PsExec工具使用 SYSTEM 权限开始'regedit' [psexec -si regedit]并导航到我希望使用我的程序进行操作的密钥,并使用[Edit -> Permissions]授予我自己的写入权限。

在这之后,我的代码工作了,并且:

Dim keyString = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\" _
+ "MMDevices\Audio\Render\{91801674-82d9-459a-9358-6e5cf3d81d21}\FxProperties"

Dim regKey = "{ad75efc0-8f48-4285-bfa8-40fb036cdab2},2"

My.Computer.Registry.SetValue( _
keyString, regKey, "00000000", RegistryValueKind.DWord)

可以成功翻转DWORD的值。虽然这有效,但我想知道是否有办法在不必手动更改注册表子项的权限的情况下执行此操作。

我在给定here的C#中发现了类似的问题和解决方案,但是我无法成功地将那里提到的C#代码转换为VB.NET代码。你可以帮忙吗?

答案 2 :(得分:1)

以下是引用的c#链接的vb.net代码。您需要设置对System.Security的引用。

    Imports System.Security
    Imports System.Security.Principal
    Imports System.Security.AccessControl

    Imports Microsoft.Win32

    Private Sub TestMethod(ByVal subkey As String)
        ' Create access rule giving full control to the Administrator user.
        Dim rs As New RegistrySecurity()
        rs.AddAccessRule( New RegistryAccessRule( _
            "Administrator", _
            RegistryRights.FullControl, _
            InheritanceFlags.ContainerInherit Or InheritanceFlags.ObjectInherit, _
            PropagationFlags.InheritOnly, _
            AccessControlType.Allow))

        ' Get the registry key desired with ChangePermissions Rights.
        Dim rk As RegistryKey = Registry.LocalMachine.OpenSubKey( _
            subkey, _
            RegistryKeyPermissionCheck.ReadWriteSubTree, _
            RegistryRights.ChangePermissions Or RegistryRights.ReadKey)

        ' Apply the new access rule to this Registry Key.
        rk.SetAccessControl(rs)

        ' Get the registry key desired with ChangePermissions Rights.
        rk = Registry.LocalMachine.OpenSubKey( _
            subkey, _
            RegistryKeyPermissionCheck.ReadWriteSubTree, _
            RegistryRights.ChangePermissions Or RegistryRights.ReadKey)

        ' Apply the new access rule to this Registry Key.
        rk.SetAccessControl(rs)

        ' Open the key again with full control.
        rk = Registry.LocalMachine.OpenSubKey( _
            subkey, _
            RegistryKeyPermissionCheck.ReadWriteSubTree, _
            RegistryRights.FullControl)

        ' Set the security's owner to be Administrator.
        rs.SetOwner(New NTAccount("Administrator"))

        ' Set the key with the changed permission so Administrator is now owner.
        rk.SetAccessControl(rs)
    End Sub

答案 3 :(得分:0)

我遇到了同样的问题,设置requireAdministrator没有帮助。然后我意识到VS2010从未要求我重新启动管理权限。我关闭并重新打开VS2010,运行该程序,然后它让我开始使用管理权限。我习惯改为requireAdministrator,并要求我在下次调试时重新启动。

因此,澄清一下,requireAdministrator 可以帮助,但可能需要手动重启VS2010(或者只是以管理员身份运行VS2010)。