New Registry syntax in MSBuild v3.5

During development of the multi-targeting feature of the next version of MSBuild, we found it convenient to expose a new method for accessing the registry from project and target files.  I hadn't really thought much more about it since we implemented it, but today I needed to make a change to Microsoft.Common.targets for which this new syntax was perfect, so I thought I'd share.

So here's how it works:  suppose there's some value in the registry you're interested in consuming.  Using the 2.0 version of MSBuild, you may have written a task which took the names of the key and value, and output the value of the value (ha, I always think it's funny saying that).  Now, with the 3.5 version of MSBuild, it's very simple.  Say the key you're interested in is "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework" and the value at that key you'd like to retrieve is "InstallRoot".  On my machine, this value is set to "C:\WINDOWS\Microsoft.NET\Framework\".  In your project/targets file - anywhere a property reference is allowed (which is pretty much everywhere), you could obtain this value with the property

$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework@InstallRoot)

This sort of shows off the pieces of the new syntax, which can be described like this

$(Registry: <key name>[@<value name>] )

Note the value name is optional - this is because the registry supports a notion of default values.  If you omit the value from the specification, MSBuild will simply retrieve the default value (if it exists).

I think this is a neat new feature which hopefully many of you will find useful.  Enjoy!

[ Author: Jeffery Callahan ]

Comments

  • Anonymous
    May 06, 2007
    That's pretty neat.  But... is the syntax extensible?  Can I create new property accessor plugins similar to "Registry"? Frankly, I don't access the registry very often at all.  But I might find it interesting to access WMI data in a deployment script or to present a chunk of the filesystem as a bunch of properties...

  • Anonymous
    May 07, 2007
    Jeff (Brown) -- no, it's not extensible right now, but I see the usefulness. Could you give us some examples of how you see the syntax looking? Dan [msbuild team]

  • Anonymous
    July 04, 2007
    Yes, it will be perfect, if this feature will be extensible. Maybe it should be possible to access any custom task with parameters Key and Value in such way/ Or something like that...

  • Anonymous
    August 15, 2007
    First off, thanks for adding this feature! It is extremely useful, and makes a number of tasks much easier. Second, just FYI, I've posted a suggestion at the Connect website that non-string values (at least REG_DWORDs) be supported using this mechanism. This would seem to be pretty easy to add (although I could be missing some hidden complication), and it would make an already great feature even better. The feedback ID of the suggestion is 293263, and it is accessible at https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=293263.

  • Anonymous
    April 04, 2008
    Talk about Fools&#39; Day joke - but on 1st of April we have released version 2.1 of MSBuild Sidekick

  • Anonymous
    April 15, 2008
    So with this new stuff how do you get the path to aspnet_regiis if you are using a msBuildBinpath of 3.0 or 3.5?

  • Anonymous
    October 31, 2008
    It would be nice if this syntax could somehow work with item metadata.  For example, I want to have an item that my build uses to aggregate registry entries to validate, something like: <ItemGroup>   <ValidateRegistry Include="Item1">      <Path>HKEY_LOCAL_MACHINESoftwareCorporationPath</Path>      <Value>Value</Value>      <Expected>$(DeployTo)/MyFile.dll</Expected>   </ValidateRegistry> </ItemGroup> And then use target batching on %(ValidateRegistry) to test.  But it would require support for...   $(Registry:%(ValidateRegistry.Path)@%(ValidateRegistry.Key) ...which fails miserably. P.S. Even using HKLM instead of HKEY_LOCAL_MACHINE didn't work.

  • Anonymous
    January 27, 2010
    Very useful information. I used this to fix the hintpath to fiddler.exe for a plugin my friend was writing. I elaborate on it, referencing this blog post at http://www.justaprogrammer.net/2010/01/28/using-the-registry-to-resolve-visual-studio-reference-paths/

  • Anonymous
    February 11, 2010
    Our msbuild runs in the x86 Visual Studio Command Prompt window.  I tried several variations of this syntax to read the 64 bit registry, but it never finds the value.  What is the syntax to read the 64bit registry from x86 window? I tried: <Target Name="VBA">    <PropertyGroup>          <VBA>          $(registry:HKEY_LOCAL_MACHINESOFTWAREMicrosoftVBA@Vbe7DllPath)      </VBA>    </PropertyGroup>    <Message Text="VBA: $(VBA)"/>  </Target> and <Target Name="VBA">    <PropertyGroup>          <VBA>          $(registry:HKEY_LOCAL_MACHINESOFTWAREWOW6432MicrosoftVBA@Vbe7DllPath)      </VBA>    </PropertyGroup>    <Message Text="VBA: $(VBA)"/>  </Target> but no results are displayed.

  • Anonymous
    April 28, 2010
    Does this work for key names with spaces in them? $(Registry:HKEY_LOCAL_MACHINESOFTWAREMicrosoftMicrosoft SDKsWindowsv6.0@InstallationFolder does not seem to work.  Is there a special syntax for this?

  • Anonymous
    December 21, 2012
    While this still works in Visual Studio 2010, it fails to view certain Registry keys on a 64 bit OS. GetRegistryValueFromView in MSBuild 4.0 (and Visual Studio 2010) solves this problem and is doccumented here: msdn.microsoft.com/.../dd633440.aspx. I also discuss it on my blog post:www.justaprogrammer.net/.../how-to-reference-the-registry-in-msbuild4-0-visual-studio-2010-and-later-on-a-64-bit-os FInally it is mentioned on this StackOverflow question stackoverflow.com/.../referencing-a-property-in-when-using-registry-properties-in-msbuild