In our final post in this series, we’ll be discussing how to integrate the Subversion information into the file version automatically with .NET. Building on these previous posts, I’ll be discussing how to do this for a .NET project using Visual Studio 2010 Professional and TortoiseSVN.
The source code for this post is available here.
Step 1: Add a Version Project
I find adding a specific Version project to the solution is beneficial. The reason is that we are generating common version info to be used across the entire solution, however the first project in the build order needs to be the one to generate this info. Depending on your project dependencies there may not be an obvious or good place to do this. By adding a Version project and making all other projects depend on it we have an easy place to generate the necessary files.
- Add a project named Version to your Solution
- Add a reference to Version from all the other projects in your Solution
Step 2: Add a GlobalAssemblyInfo Template
Create a file named GlobalAssemblyInfo.cs.tmpl in the Properties folder of the Version project. Copy the code below into the template and make any desired customizations to match your environment.
Notice the $WCNOW$, $WCNOW$ and $WCMODS?M:$ tokens. We’ll use these to place the necessary Subversion information in the file we generate using SubWCRev.exe.
// This file contains common AssemblyVersion data to be shared across all projects in this solution. using System.Reflection; [assembly: AssemblyCompany("Zach Burlingame")] [assembly: AssemblyProduct("DotNetSVNAutoVersion")] [assembly: AssemblyCopyright("Copyright © Zach Burlingame 2011")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] #if DEBUG [assembly: AssemblyConfiguration("Debug")] #else [assembly: AssemblyConfiguration("Release")] #endif // Version information for an assembly consists of the following four values: // // Major Version // Minor Version // Revision // Build [assembly: AssemblyVersion("1.0.0.$WCREV$")] [assembly: AssemblyTitle("Built $WCNOW$ from r$WCREV$$WCMODS?M:$")] // This is visible as the "File Description" on the Details tab of the Explorer pane
NOTE: Originally I also had set the AssemblyFileVersion in the template as well. However, for .NET projects, placing string data in this attribute will generate a warning (like the one below), unlike the FileVersionStr in native projects.
[assembly: AssemblyFileVersion(“1.0.0.$WCREV$$WCMODS?M:$”)]
Warning 1 Assembly generation — The version ‘1.0.0.118M’ specified for the ‘file version’ is not in the normal ‘major.minor.build.revision’ format Version
Step 3: Using SubWCRev to Generate GlobalAssemblyInfo
Next we need to add a pre-build step to our Version project to generate the GlobalAssemblyInfo.cs file from the template using the TortoiseSVN tool called SubWCRev.
The extracted version info includes the revision number, the date time of the build and if there are any local modifications to the working copy. Note that in counter-intuitive fashion, the AssemblyTitle attribute is what sets the Description field when viewed from the Details tab of the Properties pane in Explorer. Meanwhile the AssemblyDescription field isn’t displayed at all and rather is only accessible through API calls against the binary. Why MS did this, I do not know…
- Right-click on the Version project
- Select Properties
- Select the Build Events tab
- In the Pre-build event command line box, enter:
subwcrev.exe "$(SolutionDir)\" "$(ProjectDir)Properties\GlobalAssemblyInfo.cs.tmpl" "$(SolutionDir)Code\App\GlobalAssemblyInfo.cs"
Step 4: Add a link to the GlobalAssemblyInfo.cs file in each project
- In Visual Studio, right-click on a project
- Select Add->Existing Item
- Browse to GlobalAssemblyInfo.cs
- Select the file
- Click the drop-down arrow next to Add and select Add As Link
- Move the link to your Properties folder (optional, but keeps things neat)
Step 5: Update the AssemblyInfo.cs for each project
In order to avoid duplicate annotations for assembly information, you must remove entries from the AssemblyInfo.cs file that appear in the GlobalAssemblyInfo.cs file. In our example here, this is what we end up with:
using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyDescription("")] // This is not visible on the Details tab of the Explorer pane // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("dad09178-814d-43f4-b76d-0fbe29a32544")]
Other Posts in this Series
- Mapping Binaries in the Field to Source Code in the Repository
- Versioning a Native C/C++ Binary with Visual Studio
- Versioning a .NET Assembly with Visual Studio
- Integrating the Mercurial Revision into the Version Automatically with Native C/C++
- Integrating the Mercurial Revision into the Version Automatically with .NET
- Integrating the Subversion Revision into the Version Automatically with Native C/C++
- Integrating the Subversion Revision into the Version Automatically with .NET