2

我正在用 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

4 回答 4

2

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

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

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

但是,您设置的值可能需要是字节数组(您可以尝试其他方法)

于 2012-10-23T12:46:09.037 回答
1

谢谢马特,我也尝试过运行它,requireAdministrator但这也无济于事。无论如何,我找到了解决方案,似乎问题在于我试图修改的注册表项的权限。

Full Control访问权限仅授予TrustedInstaller组,因此我也授予Full ControlAdministrators组中的用户。

我使用Sysinternals 的 PsExec工具 [ ] 以SYSTEM权限启动了“regedit”,并导航到我希望使用我的程序操作的密钥,并使用 [ ] 授予我自己的写访问权限。psexec -si regeditEdit -> 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 的值。虽然这有效,但我想知道是否有办法做到这一点,而无需手动更改注册表子项的权限。

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

于 2012-10-23T19:57:42.700 回答
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
于 2013-10-23T18:39:42.040 回答
0

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

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

于 2015-08-17T21:41:41.063 回答