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 (11)

  1. Jeff Brown says:

    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…

  2. msbuild says:

    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]

  3. Alexander says:

    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…

  4. kevinowen says:

    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.

  5. Talk about Fools&#39; Day joke – but on 1st of April we have released version 2.1 of MSBuild Sidekick

  6. chuck123q says:

    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?

  7. spiderM9 says:

    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.

  8. 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/

  9. mgb69 says:

    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.

  10. ericandjacksdad says:

    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?

  11. Justin Dearing says:

    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:http://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