Results 1 to 6 of 6

Thread: [RESOLVED] Modifying/Adding to Registry

  1. #1

    Thread Starter
    New Member
    Join Date
    May 2017
    Posts
    4

    Resolved [RESOLVED] Modifying/Adding to Registry

    Hello everyone. I am here to ask about some code I am trying to use to change or add registry values to Windows, specifically Windows 10.
    I'm a noob, but I'm also trying to create a simple application I can use to add registry tweaks that I often use.

    The code I'm using is as follows
    Code:
        Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
            My.Computer.Registry.LocalMachine.CreateSubKey("HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\MTCUVC")
            My.Computer.Registry.SetValue("HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\MTCUVC", "EnableMtcUvc", "00000000", Microsoft.Win32.RegistryValueKind.DWord)
            Dim KeyValue = My.Computer.Registry.GetValue("HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\MTCUVC", "EnableMtcUvc", Nothing)
            Label4.Text = KeyValue
        End Sub
    When starting the application and clicking the Button nothing occurs. Running the application as administrator through the bin\Debug folder and clicking the button results in the following unhandled exception error.

    Code:
    ************** Exception Text **************
    System.IO.IOException: The parameter is incorrect.
    
       at Microsoft.Win32.RegistryKey.Win32Error(Int32 errorCode, String str)
       at Microsoft.Win32.RegistryKey.CreateSubKeyInternal(String subkey, RegistryKeyPermissionCheck permissionCheck, Object registrySecurityObj, RegistryOptions registryOptions)
       at Microsoft.Win32.RegistryKey.CreateSubKey(String subkey, RegistryKeyPermissionCheck permissionCheck)
       at Microsoft.Win32.RegistryKey.CreateSubKey(String subkey)
       at Tweaker.Form1.Button3_Click(Object sender, EventArgs e) in d:\Users\Dingo\Documents\Visual Studio 2017\Projects\Tweaker\Tweaker\Form1.vb:line 24
       at System.Windows.Forms.Control.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
       at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ButtonBase.WndProc(Message& m)
       at System.Windows.Forms.Button.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
    The part that confuses me is the almost identical counterpart I used for testing works completely fine.

    Code:
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            My.Computer.Registry.CurrentUser.CreateSubKey("TestKey")
            My.Computer.Registry.SetValue("HKEY_CURRENT_USER\TestKey", "KeyToTweak", "Enabled Value", Microsoft.Win32.RegistryValueKind.String)
            Dim KeyValue = My.Computer.Registry.GetValue("HKEY_CURRENT_USER\TestKey", "KeyToTweak", Nothing)
            Label2.Text = KeyValue
        End Sub

  2. #2
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,930

    Re: Modifying/Adding to Registry

    Welcome to VBForums

    Editing the registry (in code, or RegEdit, etc) requires appropriate permissions, but CurrentUser is always allowed (because you are only setting values that affect yourself).

    LocalMachine is different because it affects other users, so you need Admin permissions. The reason "nothing happened" when you weren't running as Admin is that Windows realised you didn't have the required permission, but when Windows Vista was released (2007?) it included several automatic fixes to 'poorly written' programs that would otherwise have failed (and thus caused complaints about Microsoft, even tho it was the program writer that did something wrong). In this case it creates a virtual section of the registry that only your program can see.


    As for the issue when you were running as Admin, compare these two lines of your code:
    Code:
    My.Computer.Registry.CurrentUser.CreateSubKey("TestKey")
    Code:
    My.Computer.Registry.LocalMachine.CreateSubKey("HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\MTCUVC")
    The working one contains only the Key, but the one that fails has far more than that... most importantly it includes the root ("HKEY_LOCAL_MACHINE\") which probably shouldn't be there.

  3. #3

    Thread Starter
    New Member
    Join Date
    May 2017
    Posts
    4

    Re: Modifying/Adding to Registry

    Thank you I feel silly for missing the double localmachine part. Now my only problem is running as administrator results in nothing happening, just now without errors. Now running as administrator I fear may be resulting in this "virtual section of the registry" you mentioned as when the program reads the value back to me it shows it as being changed, yet in the actual registry it is untouched.

  4. #4
    You don't want to know.
    Join Date
    Aug 2010
    Posts
    4,578

    Re: Modifying/Adding to Registry

    If you have a peek at Registry Virtualization, the sense you might get is the only thing under HKLM that isn't protected by virtualization is HKLM\Software\Classes.

    It looks like your only workaround might be to update your application manifest and set the appropriate "requested execution level". You can do this by right-clicking your project in Solution Explorer, then looking for a button that (in VS 2017) says "View Windows Settings". That reveals a file named app.manifest. There's a lot of comments around how to set this, here's how I interpret them against the documentation (it feels a little confusing.)

    "The default level is "asInvoker", so unless you've completely turned off UAC it's likely your account doesn't have permission to write to HKLM. When you try, Windows silently writes to a virtualized registry instead.

    If you switch the default level to "requireAdministrator", your application will cause a UAC prompt when it launches. If the user accepts the UAC prompt, you ought to bypass virtualization."

    Maybe you don't want the UAC prompt. That's tough luck, it is a good thing that MS has made it impossible to change certain things without one. What you can do instead is something I've seen a few programs do:

    Write a separate executable for the sole purpose of setting the registry key. Edit THAT program's executable to request "requireAdministrator". When you need your program to change the registry key, use the Process class to start that application, preferably after informing the user you're about to change a setting and a UAC prompt might be displayed. The user will accept the prompt, the program will run, finish, and then you're done.
    This answer is wrong. You should be using TableAdapter and Dictionaries instead.

  5. #5

    Thread Starter
    New Member
    Join Date
    May 2017
    Posts
    4

    Re: Modifying/Adding to Registry

    Actually I had already gone through and added the manifest prior to making my previous post. It appears as follows.
    For problem resolution purposes I have also tried with the access set to highestAvailable

    Code:
    <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
        <security>
          <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
            <!-- UAC Manifest Options
                 If you want to change the Windows User Account Control level replace the 
                 requestedExecutionLevel node with one of the following.
    
            <requestedExecutionLevel  level="asInvoker" uiAccess="false" />
            <requestedExecutionLevel  level="requireAdministrator" uiAccess="false" />
            <requestedExecutionLevel  level="highestAvailable" uiAccess="false" />
    
                Specifying requestedExecutionLevel element will disable file and registry virtualization. 
                Remove this element if your application requires this virtualization for backwards
                compatibility.
            -->
            <requestedExecutionLevel  level="requireAdministrator" uiAccess="false" />
          </requestedPrivileges>
        </security>
    </trustInfo>

  6. #6

    Thread Starter
    New Member
    Join Date
    May 2017
    Posts
    4

    Re: Modifying/Adding to Registry

    I solved the problem, it was something really silly, that surprises me as to why it would even cause this to break on me in the first place.
    I double clicked 'My Project' selected the Compile tab and under the Target CPU setting, unchecked the box that said 'Prefer 32 bit'
    Hopefully this well help anyone else who is experiencing the same problem.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width