Link to home
Start Free TrialLog in
Avatar of brian_appliedcpu
brian_appliedcpu

asked on

Read Registry Key Values on Windows 7

I have a VB.NET app that has been working fine on Windows XP Pro. Within the app, it initializes a variable as follows:

    Dim strPath As String = My.Computer.Registry.LocalMachine.OpenSubKey("Software", True).OpenSubKey("Microsoft", True).OpenSubKey(".NETFramework", True).GetValue("InstallRoot")

I deployed the application to a Windows 7 machine and when the app attempts to initialize the above variable, it encounters the following run-time error:

    Object reference not set to an instance of an object.

I am logged into the Windows 7 machine with a user account that is a member of the local Admins group. I have verified that the registry key and value exist on the Windows 7 machine. I have also verified that the local Administrators group and the Users group have at least Read permission to this registry key. On Windows 7, if you click Start, type in Regedit.exe, and press Enter, you then have to click Yes or No on the Warning dialog before you can enter the Registry Editor. Thinking that this Warning may somehow be the cause of my error, I disabled the warning, and Windows 7 prompted me to reboot in order for the change to be applied. After the reboot, however, the application still encounters the error listed above.

I do not understand why this error is occurring.
Avatar of Todd Gerbert
Todd Gerbert
Flag of United States of America image

Administrative access is required to open the LocalMachine registry keys with write access.

Under Windows Vista and Windows 7, by default, even if you log in with an administrative user programs are run with limited access.

You must specifically ask for Windows to elevate your access rights to an Administrator level by right-clicking the the shortcut/program and choosing Run as Administrator...
Avatar of brian_appliedcpu
brian_appliedcpu

ASKER

tgerbert,

Is there any way at runtime that I can instantiate a "User Account" object within the .NET app and define that object as Local Admin. In turn, this object would be used to access the registry, and then disposed of after the reg values have been read???

It's not going to be cool to have to tell Vista and Win7 end-users that they have to right-click the application icon and choose Run as Admin. Plus, if you are running VS2005 on Win7, how would you start and run the debugger as admin?
The short answer is: no, this behavior is by design, it is part of User Account Control (UAC). You can read up on UAC on Microsoft's site (http://msdn.microsoft.com/en-us/library/aa905330.aspx).

The longer answer:

Microsoft's position is that it's bad practice to write programs that assume the user has administrative privileges.  If you're only reading the value at HKLM\Software\Microsoft\.NETFramework\InstallRoot, then don't open the keys with write access.  As a standard user you can open and read these keys read-only, bypassing the need for elevation on Windows Vista/7. Use OpenSubKey(keyName, False) to open a subkey without write access.

You can also include a UAC manifest in your project, which will cause Windows to automatically prompt for elevation. This will eliminate the need for users to right-click and choose Run as Adminstrator, but will still require a response to the elevation prompt (http://msdn.microsoft.com/en-us/library/bb756929.aspx).

Visual Studio should be run elevated, i.e. Run as Administrator.

One other note, you don't need to use .OpenSubkey(theKey).OpenSubKey(someotherkey).OpenSubKey... etc.  You can just use Registry.LocalMachine.OpenSubkey("Software\Microsoft\.NETFramework", False). You should also put it inside a Try/Catch block to handle exceptions.
Dim rk As RegistryKey = Nothing
        Dim strPath As String = String.Empty

        Try
            rk = Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\.NETFramework", False)
        Catch ex As Exception
            MessageBox.Show("Cannot open registry key. The error message is:" & vbCrLf & ex.Message)
            Application.Exit()
        End Try

        Try
            strPath = rk.GetValue("InstallRoot")
        Catch ex As Exception
            MessageBox.Show("Cannot read InstallRoot value. The error message is: " & vbCrLf & ex.Message)
            Application.Exit()
        End Try

        MessageBox.Show(strPath)

Open in new window

tgerbert,

I have other Registry.Keys that I need to be able to Write to. Sounds like I need to rethink this. Maybe I need to consider adding an external file to the application used for storing user settings and abandon the use of the Registry; kind of like going back to the INI file concept. That's too bad.

Thanks for all the info.

BTW, I'm currently using VS2005. Do you know whether VS *2008* will offer any better methods for massaging the Registry; particularly in Debug mode. I can "run as admin" VS2005, but when stepping thru code, it does not recognize that VS is running under an elevated account, and an exception is thrown on any registry manipulations. I'm guessing I would I see this same behavior under VS 2008, yes?
ASKER CERTIFIED SOLUTION
Avatar of Todd Gerbert
Todd Gerbert
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
"...must be something else causing your exceptions."

Rather, I should say it might be something else causing the exceptions. ;)
One last thing, you can get Microsoft Visual Basic .Net 2008 Express, which excludes some features of the full version of Visual Studio, but is actually an excellent product, for free at http://www.microsoft.com/express.
This code has been running for a couple of years (or close to it). Nothing has changed. I was moved to a new development PC this week, which happens to be running Win7 (old dev machine was WinXP). I migrated all of my VS projects over to the new machine today and that's when I discovered this registry accessibility issue.

I too thought that it was most likely something else causing my exceptions. But as a tested, I simply change the order in which certain command-lines are executed. It didn't matter, I would always get the same error that you see listed in the first thread that I posted on this issue today, that is the exception that I get on every variable that the code tries to set equal to some registry value.

I think I'm going to look into app.config. Thanks for all your help.