Question

I'm writing a small program in Visual Basic 2008 that flips the values of specific DWORDs in a registry key

The registry key in question is:

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

The dword I'm manipulating is "{e0a941a0-88a2-4df5-8d6b-dd20bb06e8fb},4"

This is the line of code I wrote to set the DWORD's value is this:

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")

But I get a UnauthorizedAccessException at runtime stating that "Access to the registry key [KEY_NAME] is denied."

I ran the program with Administrator privileges, changed the app's manifest to include:

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

But that didn't work either. So I searched a few forums and tried this:

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")

But that threw a NullReferenceException at me stating "Object reference not set to an instance of an object."

Is there any way I can modify that that key without having to run my program with SYSTEM privileges?

Was it helpful?

Solution 2

Thanks Matt, I tried running it with requireAdministrator as well but that didn't help either. Anyway, I found the solution to this and it seems the problem lied with the permissions on the registry key that I was trying to modify.

Full Control access was only given to the TrustedInstaller group, so I granted Full Control to the users in the Administrators group as well.

I started 'regedit' with SYSTEM privileges using Sysinternals' PsExec tool [psexec -si regedit] and navigated to the key I wished to manipulate using my program and used [Edit -> Permissions] to grant write access to myself.

After doing that, my code worked and this:

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)

could successfully flip the value of the DWORD. Although this worked, I would like to know if there's a way to do this without having to manually change permissions on the registry subkey.

I found a similar problem and solution for this in C# given here but I couldn't successfully convert the C# code mentioned there to VB.NET code. Could you help with that?

OTHER TIPS

You should probably try with requireAdministrator in your manifest because highestAvailable may not actually be an administrator.

I would also try specifying the data type (in your case I think it is binary):

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

However the value you are setting may need to be a byte array (something else you could try)

Here is the vb.net code for the c# link referenced below. You will need to set a reference to 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

I had this same problem, and setting requireAdministrator didn't help. Then I realized VS2010 never asked me to restart with Administrative rights. I closed and reopened VS2010, ran the program, and then it asked me to start with Administrative privileges. I'm used to changing to requireAdministrator and it asking me to restart at the next time I debug.

So, to clarify, requireAdministrator does help, but may require a manual restart of VS2010 (or just run VS2010 as Administrator).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top