Q. I’m trying to write to HKLM on a Vista computer using the following code:
Dim k As Microsoft.Win32.RegistryKey k = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("software", True) k = k.CreateSubKey("subkey1\testprogram") k.SetValue("foo", "bar")
But, when I get to the last line, the UnauthorizedAccessException is thrown. How do I fix this?
A. It is throwing an exception because Microsoft considers writing to HKLM a security risk which requires elevated privileges. When you are programming in .NET, you should not store application specific data in the registry. Instead you should store this information in a file on the hard drive. I’ll give you some tips on how to do that at the end of this article. But, first I want to try to convince you that using the Registry is evil.
Using the registry to store your data, decreases the performance of your computer.
That’s right. The registry is a sequential database. Looking for data in it is similar to opening a file and sequentially reading through the file until you find what it is you are looking for. The larger the registry, the longer it will take to find the item at the end. Therefore, any application that uses the registry to store information will take longer to find the information. Over time, this means your computer will take longer to boot and application will suffer.
Registry data can not be backed up easily.
Most people who do backup their computers expect the data that needs to be backed up in the Documents folder. At a minimum, they expect to be able to xcopy the drive to another drive and still have all the data they need. I recently suffered from a computer malfunction that required me to xcopy my drive to an external drive, re-install Windows (and all my programs) and restore my data from the external drive.
It was then that I found out that one of the programs I was using was storing data I needed to restore in the registry! Arrgh. I’ve since found a different program for that job.
Contrast this to Eudora that I can move from one computer to another by doing nothing but copying from one computer to another!
.NET is suppose to be XCopy deployable
Since .NET released, the intention from Microsoft is that an installation program is not needed to either place the program on a computer or to move from one computer to another. If you are storing data in the registry, you obviously won’t be able to use XCopy deploy to move your application.
Registry security gets in the way.
And of course, there is the question at hand, which reminds me of a story.
A patient comes into the doctor’s office and says, “Doc, it hurts when I do this.” To which the doctor responds, “Well, then… Don’t do that.”
So, what to do instead?
There are two types of data you might need to store. Data that every user who logs into the computer will need to be able to access in common and data that is user specific. Microsoft has provided an API for storing app settings for the current version of the software. But, I personally find that unusable because every version has to start over. If you can use it, it is probably the easiest method. But, it isn’t a cure all.
Store to a file.
The last time I really needed to store configuration data for an application was when I created VSS.NET What I did for this application is that I created a serializable class that held all of the configuration information. By making it serializable, I could store the configuration data either as binary or xml into a file stream anywhere I needed. Since this information was user specific, I stored the information in a file locally.
I’m assuming you already know how to create a serializable class and save it to a file. What you may not be aware of is how to find the various system locations on the computer. Especially since they are in different physical locations depending on what operating system you are running. So, here they are:
System.Environment.GetFolderPath(param), returns the path of one of the system folders and the enum System.Environment.SpecialFolder holds the constants that get passed in as the parameter.
Using this, you can store your data into the Document directory, AppData, or several other folders. I prefer to store into the Document directory whenever I can so that the information will get backed up. Preferably in a clearly marked directory so that it does not get deleted, or as a hidden file. If that doesn’t work. AppData is my second choice.
So, how do you fix the UnauthorizedSecurityException when writing to HKLM? You stop writing to the registry and write to a file instead.
Other post in VB.NET
- Assign Multiple enum Values To One Variable - November 2nd, 2007
- Object Initialization in CSharp 3.0 and VB.NET 9 - November 28th, 2007
- The VB.NET Ternary Operator - November 29th, 2007
- UnauthorizedAccessException writing to HKLM - April 8th, 2008
- Overriding Events in VB.NET - May 8th, 2008
- VB.NET - Char from String with Option Strict - April 8th, 2009
- .Net String Pool – Not Just For The Compiler - April 22nd, 2009
- Manually Adding Event Handlers in VB.NET - July 15th, 2009
- VB.NET Processing Before WinForm Display - August 6th, 2009
- Decimal vs Float (Single) or Double - September 18th, 2012
- VB.NET Hide Module Name - August 28th, 2013
- VB.NET Nullable Types - January 15th, 2014