Registry redirection on Visual Studio 2008 RTM & SP1 (part 1)
First of all a quick overview, I made a VSIP package which originally addresses just Visual Studio 2005, in where I added support to work with the regular hive and with the Experimental hive. In fact there are no much differences between those but in my package I require to know which registry hive is the current one. Since VS 2008 I used the same bits to address VS2005 and VS2008. The only thing that I had to do was just register the same package made for 2005 but, for VS 2008.
As you know using MPF 8.0 as baseline you can inherit from the Package base class then in there you have the ApplicationRegistryRoot property what it basically does is the follow:
Note that if you running on VS 2005 Regular and Experimental hive both are located under HKLM key. So what the GetRegistryRoot method does is determine the value of Software\Microsoft\VisualStudio\* in where * will be the current VS hive (8.0, 8.0Exp or Foo) also that's can be done using IVsShell as follow:
However since 2008 that approach has changed due to the Regular is still running into the HKLM as same as VS2005 but, the Experimental hive is running under de HKCU (CurrentUser) registry hive. Aaron Marten has a post with an overview of that.
Regular (no changes): HKLM\Software\Microsoft\VisualStudio\9.0
Experimental: HKCU\Software\Microsoft\VisualStudio\9.0Exp\Configuration
Note that HKLM\Software\Microsoft\VisualStudio\9.0Exp does not exists!.
So if you still using the 8.0 MPF as baseline (using for example ApplicationRegistryRoot) or even if you have your own implementation you should experience problems accessing the current registry hive, but in fact no :S. If you run a VS 2008 in experimental mode and running as normal user then you try to do the follow:
RegistryKey currentRoot = Registry.LocalMachine.OpenSubKey("Software\Microsoft\VisualStudio\9.0Exp");
Debug.Assert(currentRoot != null);
the expected behavior should be get a null reference due to that registry key doesn't exists but no!, and that's because it will be automatically redirected to HKCU\Software\Microsoft\VisualStudio\9.0Exp\Configuration. The confusion comes when you do something like this
When you do a ToString() you get a "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\VisualStudio\\9.0Exp", but if you try to write some dummy key or value there, the value is going to HKCU\Software\Microsoft\VisualStudio\9.0Exp\Configuration automatically.
The same thing happens if you use the ILocalRegistry2 to get the GetLocalRegistryRoot output that in fact it returns an string with the current UserSettings path (ie: "Software\\Microsoft\\VisualStudio\\9.0Exp\\UserSettings"), eventually you must use the Registry.LocalMachine.OpenSubKey API to get the registry hive, which btw is not so useful due to we really don't know if it's a HKLM or HKCU entry. We're guessing that's a CurrentUser key because it has a Exp suffix, mmmmm :S.
The Problem.
Since VS 2008 SP1 that behavior has been changed or fixed. I'm not sure if it was a feature or not but in any case with the SP1 applied when you probe for "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\VisualStudio\\9.0Exp" you will get HKLM as expected!.
You can avoid those issues if your package is using 9.0 than 8.0 references but in that case you won't be able to addresses VS2005 and VS2008 with the same bits. In 9.0 you already have an implementation of VSRegistry and I already post about that here: http://weblogs.asp.net/jescrich/archive/2008/08/15/how-to-know-which-is-the-current-running-visual-studio-registry-hive.aspx.
I will back with another approach on how to deal with it avoiding to change your project references.
Enjoy!