|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionMany of your Windows executable files include version information. For example, in the Properties page for my C:\Windows\notepad.exe, the Version tab gives "File version: 5.1.2600.2180" along with other information. In a Visual Studio project, most or all of this information is stored in a resource file (default extension is .rc). I wanted an easy way to add automatic build versioning to my Visual Studio projects that would accomplish the following tasks:
During my initial research I first determined that apparently none of these is natively supported in any version of Visual Studio. I then came across an existing Code Project article about a utility called RCStamp, which parses resource files and modifies the version information within, based on a given format string. This article does not go into the details of RCStamp, so I recommend you read its separate article first. RCStamp solves task #1 on the list. This article explains the steps I took to solve my other requirements. First I outline the utility applications I created, after which I explain how it all comes together within Visual Studio. Build Archiving (VerCopy)The way I chose to solve the problem of archiving each build was to write a tiny utility application that simply takes a file as input, and copies it to a new file, which is named based on the version information. For example, running VerCopy on my notepad.exe would produce a new file called notepad-5-1-2600.exe. The code only uses the first three numbers of the file version because this is what I wanted. However the source code is extremely simple and is easily modified to suit anybody's needs. Here is the meat of the C# source code: FileVersionInfo verInfo = FileVersionInfo.GetVersionInfo(PathFile);
string destFile = fileInfo.Name.Substring(0,
fileInfo.Name.Length-fileInfo.Extension.Length) + "-"
+ verInfo.FileMajorPart + "-" + verInfo.FileMinorPart + "-"
+ verInfo.FileBuildPart + fileInfo.Extension;
File.Copy(PathFile, destFile, true);
As you can see, C# makes it a simple matter to access the version information in a given file. Version Awareness (VerHeader)To solve the task of making my projects easily aware of their own current version information, I decided to write another small utility application that parses a resource file and produces a C++ header file with preprocessor constant definitions ( string line, major, minor, build;
while ((line = RCFile.ReadLine()) != null)
{
int pos;
if ((pos = line.IndexOf("FILEVERSION")) < 0)
continue;
pos += "FILEVERSION".Length + 1;
string[] tempInfo = line.Substring(pos).Split(" .,".ToCharArray());
ArrayList verInfo = new ArrayList(4);
foreach (string s in tempInfo)
if (s.Length > 0)
verInfo.Add(s);
major = verInfo[0].ToString();
minor = verInfo[1].ToString();
build = verInfo[2].ToString();
}
outFile.WriteLine("#define MAJORVERSION {0}", major);
outFile.WriteLine("#define MINORVERSION {0}", minor);
outFile.WriteLine("#define BUILDNUMBER {0}", build);
Integration into Visual StudioHere I describe the method I use to add my three build versioning requirements to a Visual Studio project. It is quick and painless and once again the process is easily customizable to suit your needs. The steps I personally use are as follows:
Adding the Version ResourceTo do this, simply right-click on the project name in Solution Explorer, and select Add->Add Resource... Choose "Version" from the list and click "New". The file will be added to the Resource Files folder for the project and given the same name as the project and the extension ".rc". Double-clicking it will open Resource View. Expanding the Version folder and double-clicking "VS_VERSION_INFO" will show you the contents of the file. Modify it whichever way you like. The " Pre-Build EventBefore we build the application, we want VerHeader to create our header file for us, so we can include it in the application. To do this we add a call to VerHeader in the pre-build event for the project. This is a set of user-defined batch commands that are executed before the build process begins. To access the settings, right-click the project name in Solution Explorer and select Properties... Select "All Configurations" in the Configuration drop-down list and then expand the Build Events folder. In the Command Line field under Pre-Build Event, add: ..\VerHeader "$(ProjectName).rc" version.info
The working directory of the batch commands is the project folder. Usually this is a sub-folder within the solution folder, so VerHeader.exe is contained one step up from the working directory. Visual Studio provides some macros for us to use within these batch commands. Post-Build EventOnce the application has been built, we want to store a copy of it using VerCopy. In addition, we want to increment the build number in our resource file. So we add calls to VerCopy and RCStamp in the post-build event for the project. This works exactly the same as the pre-build event except that it is called directly after a build succeeds. For the desired configurations, add the following to the post-build command line: ..\VerCopy "$(TargetPath)" "..\Builds\$(ConfigurationName)"
..\RCStamp "$(ProjectName).rc" *.*.+.*
Once again, we use the Including the Header FileThe last step is to include the outputted header file in your application. In C++, simply add a You will find that these steps are easy to remember, and once you've gone through them, they can be done in a matter of minutes. Notes and Considerations
ConclusionI personally find this functionality to be greatly useful in projects with experimental code. I can run performance tests on any builds I wish and release the one with the best results, while working to improve any new changes. Coupled with source control, I finally feel like I have optimal control over not only my code revisions, but also the culmination of sets of revisions into new builds. Hopefully future versions of Visual Studio will provide a full-featured build versioning system, but until that time I feel that my solution is quite adequate. Many thanks to Peter Chen for creating RCStamp, which is really the backbone of this system. FeedbackPlease contact me with any and all feedback you have regarding this article and the source code. Anything from a spelling correction, to a simplification of the setup process, to a way to improve the source code would be much appreciated. The utilities I wrote are neither highly functional nor highly robust and I would be happy to make any modifications that are important or popularly requested. I would be particularly interested in learning about a scripting method to quickly perform the setup process for a given project within Visual Studio. Revision History
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||