2012-10-23 74 views
2

我正在写在Visual Basic 2008年一个小程序,翻转在注册表项中的DWORD特定的值的注册表项访问“[KEY_NAME]”被拒绝

有问题的注册表项是:

'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特权?

回答

1

感谢马特,我试着用requireAdministrator来运行它,但那也没有帮助。无论如何,我找到了解决这个问题的办法,看起来问题在于我试图修改注册表项的权限。

Full Control访问只给予的TrustedInstaller组,所以我的管理员组授予Full Control给用户也是如此。

我开始“注册表编辑器”与SYSTEM特权使用Sysinternals' PsExec工具 [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的值。虽然这工作,我想知道是否有办法做到这一点,而不必手动更改注册表子项上的权限。

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

+0

你可能正在寻找我在 [这里的问题]中描述的相同的东西(http://stackoverflow.com/questions/21961913/how-to-set-speaker-sound-enhancement-settings)。这是您找到访问音频强化的最佳方式吗? – natenho

+0

@natenho我能够更改注册表中的值,但除了选中/取消选中扬声器属性窗口中的相关复选框之外,它没有任何操作。 – Vinayak

+0

我必须重新启动音频服务才能使其工作'net stop audiosrv',然后'net start audiosrv'或使用[ServiceController类](http://www.csharp-examples.net/restart-windows-service/) 。 – natenho

2

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

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

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

但是您设置的值可能需要一个字节数组(别的东西,你可以试试)

+0

谢谢马特。我试过'requireAdministrator',但没有奏效。尽管我找到了解决方案。我将在删除自我回复时间限制后的几个小时后发布。 – Vinayak

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 
0

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

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