How do I make automatic version numbers work in Visual Studio - c#

I've been asked to add automatic numbering to assemblies in our code library. I've been changing versions from the default 1.0.0.0 to 1.0.* like this:
[assembly: AssemblyVersion("1.0.*")]
It generates a number as I'd like.
However, the code library has many hundreds of DLLs, with many referencing each other. Now when I compile some projects they complain that the version of a DLL needed by a referenced component is not correct and they won't build :(
How can I make this work? We need it so that when a DLL at the bottom of our code library hierarchy is compiled, all other DLLs that reference it work correctly without needing recompiling.
The error I get is like this:
Error 1 CA0058 : The referenced assembly 'Library1, Version=1.0.4146.17993
, Culture=neutral, PublicKeyToken=d9c65edd2096ad48' could not be found. This assembly
is required for analysis and was referenced by:
D:\Work\Source Code\Library\Library2\bin\Release\Library2.dll.
The version 1.0.4146.17993 is not correct - the DLL has a higher value. The DLLs are set to Copy Local because the software we deliver requires it (don't ask why). The DLL that's copied locally is the one with the higher version number, which is the one we want it to be.
So far I've tried changing the references to set the "Specific Version" flag to false but this didn't help.

The version numbers that VS generates when you use the 1.0.* syntax are not necessarily going to increment in sequence. The documentation has this to say (emphasis added):
You can specify all the values or you can accept the default build number, revision number, or both by using an asterisk (). For example, [assembly:AssemblyVersion("2.3.25.1")] indicates 2 as the major version, 3 as the minor version, 25 as the build number, and 1 as the revision number. A version number such as [assembly:AssemblyVersion("1.2.")] specifies 1 as the major version, 2 as the minor version, and accepts the default build and revision numbers. A version number such as [assembly:AssemblyVersion("1.2.15.*")] specifies 1 as the major version, 2 as the minor version, 15 as the build number, and accepts the default revision number. The default build number increments daily. The default revision number is random.
If it's vital that you get versioning exactly right, I highly recommend that you use a third-party solution. The Build Version Increment add-in is excellent.
What you want to do is manage the assembly version yourself. Only increment this when you make a breaking change to the assembly's public interface. Changing this attribute makes your assembly incompatible with other assemblies that reference it, even if you didn't change a thing in your code. Instead, the only thing you want to automatically increment is the assembly file version. Unlike the assembly version, this attribute is not checked by the CLR to determine compatibility.
The Build Version Increment add-in gives you the kind of fine-grained control over what is incremented that you need to get this right. It's what probably should be included in VS to begin with.

This is actually a pretty indepth question, and I hope someone answers this in detail for you, but my 2 cents after you get the assembly infos under control is you should look at using Nuget to manage your dependencies. This way when team A releases v2 of assembly X, all they do is put it on your Nuget repo (network share probably) and then you can basically right click < update inside your projects that consume the DLLs.
I would also recommend looking at http://semver.org/ and use Semantic Versioning, if you don't want to follow a system like this one (or institute a similar standard for your shop), it's probably not worth even trying to version your DLLs you're just going to give yourself massive headaches. However using Semantic Versioning will make your version numbers actually MEAN something. And not just be whatever felt like being tagged onto the current version.

Note that the Revision number is not random. It is the time of day of the build. The Build is the day number.
See VisualStudio: translating a build version to a calendar date

delete your reference (in the project that uses it) and re-do it by pointing to the project reference type.
PS: If when you are adding the reference, you choose browse and point to a place the dll will always be, the reference will not be broken!

> However, the code library has many hundreds of DLLs,
If it is ok for you that all source projects and their generated dll-s have the same version-number you can put the versionnumber into one file that is shared between all dlls as described in
shared AssemblyInfo.cs. So you (or the version-number-generator you are using) have to update only one file if there is a new relase/Version.
This does not answer your original question but may be a simple workaroud for the dependency problem.

Related

Asp.Net 5 Semantic Versioning

It seems that versioning works differently than in previous versions of .Net. The project.json seems to use semantic versioning (from what I have seen online) with the format Major.Minor.Patch-Special.
Does this replace the Assembly version idea or add to it? Or does it just get used with Nuget.
How does one access the version during runtime. I came across Nuget.SemanticVersion object online in the Microsoft.Framework.Runtime package but I can't find out how to retrieve it in code.
Is there a programmatic way to update this value on a build or just custom scripts?
I wouldn't say that versioning has changed in a particularly dramatic way. In a version number x.y.z, the "x" means "big changes / breaking changes," the "y" means "minor additions and fixes," and the "z" means "very minor fixes." That's pretty close to what Semantic Versioning (SemVer) states.
In a project.json-based project, there is only one place to specify the version, and that's in the project.json file itself. That one version is a SemVer (e.g. x.y.z-prerel) and is used for the NuGet package version and the assembly version, and the assembly informational version. If you've explicitly set the assembly version or informational version in the assembly, those will be respected and not overridden. (You can see the code here.)
At runtime you can read the assembly version through reflection (just like you always could).
When running in a DNX application there's also an ILibraryManager interface that you can use to inspect the running application. However, that's a fairly advanced scenario.
Lastly, in the project.json file you can hard-code the x.y.z part of the version, e.g. 1.2.3 but you can also specify a * for the pre-release specifier, e.g. 1.2.3-*. If you use * for the pre-release specifier, you can set an environment variable named DNX_BUILD_VERSION to specify the value of the *, e.g. beta1 or rc2-54289.
There are some feature requests logged to allow more flexibility in specifying the entire version number externally.

Versioning software without having to edit lots of config files

We have a project that uses a couple of assemblies.
Is there an easy way of handling the version of all those assemblies at once?
We have a version like
major.minor.patch.revision
Most of the times on a release, just the minor version gets a change.
A critical part is the revision which is the fileversion in the repository.
At the moment I think this makes impossible to use one AssemblyInfo.cs for all assemblies.
How can I avoid to change the AssemblyInfo.cs of all those assemblies?
If you want all of the assemblies to have the same version, you can make a single .cs file for the versioning in one of your libraries, and add it as a link to the other projects.
This will cause the single file to be part of all three assemblies, and keep the version constant across them all.
I've found that this is easiest to do when you're going to create your build artifacts. From a process standpoint, you would:
1. Tag/Label Source
2. Get by Tag/Label
3. Edit AssemblyInfo files
4. Build, Test, Etc
5. Capture Build Artifact
This is all pretty easy to do in BuildMaster(disclaimer: I work for Inedo as a set of actions. In this case it'd be just using the Write Assembly Versions action after doing a Get Latest action.
You can see this pattern used a lot in the specifics libraries. When we build ProGet, for example, you'll notice that Write Assembly Versions shortly after comparing the directories for changings, and right before running msbuild.

AssemblyInfo.cs , .net applications versions

I would like to keep version in my .net applications and let the .net to manage it. I don't really understand how it works. Is the version number per project ? How .net manages versions? If anyone could please explain it briefly i will be grateful.
What I usually do is to keep a SolutionInfo.cs that contains all the attributes that are common for the projects of my solution, for example the version-number. I keep this file in the solution root.
I then link that file into the project (right click the project and Add->Exsiting item... -> Add as link (the little arrow on the add button)).
I then can increment the version number in a single place and it will be updated in all the projects that links that file.
For more information on that for example see: http://jebsoft.blogspot.com/2006/04/consistent-version-numbers-across-all.html
The version number is per-project (.csproj file), so per built .dll or .exe file. The version number is embedded in the .dll or .exe, and can be viewed using (for example) Windows Explorer by right-clicking on the file and selecting Properties.
MSDN contains an explanatory article about how to use AssemblyVersion and AssemblyFileVersion at http://support.microsoft.com/kb/556041
[AssemblyVersion] is a very big deal in .NET. Every type in your program is imprinted with the assembly version, it is part of the type identity. In other words, when the version of your type changes then you should also change the assembly version. This forces all other assemblies that use your type to be recompiled.
One thing you can do is to let the build system automatically increment the version. You can't call this 'managing the version' by any stretch of imagination. Because now just rebuilding your assembly, even without making any change in the source code, will make your assembly incompatible with other code that uses the types in that assembly.
Clearly this can only work well if you recompile all the code in your solution.
Well, that's not great unless you like sword fighting. Furthermore, sometimes you want to make a simple bug-fix in your code. The result is an assembly that's still 100% compatible with the original version. And you don't need nor want to recompile everything else that uses it. You just want to send that one assembly to your customer. Clearly that can only work well if you don't let the version increment automatically.
So what you really need is some kind of tool that can magically determine that your source code, the publicly visible part of it, is no longer compatible with a previous version. Or the changes you made to the non-visible part of it are changing the behavior of the code too much to disallow other code that use your types to continue to use it without some changes in their code.
There's only one tool that I know of that can do this, the one we have between our ears.

How to configure build numbers in Visual Studio to enable dll comparison

I am building a C# solution in Visual Studio 2008 that has several projects and project dependencies. I am looking for a way to change dll version numbers ONLY when the code that builds the project changes. I currently use Beyond Compare to compare my locally built version to the production file system. The goal is to ONLY deploy updated dlls. I am using autoincrementing version numbers, and each time you open visual studio and do a build, all dll version numbers increment. The same goes for a full solution rebuild and when a different developer does a build and tries to deploy. Is there a way that i can configure Visual Studio to ONLY increment the build number based on changed file contents? Is there an add in that will do this?It seems a binary comparison of these files will also fail because of the different version numbers within the dlls. Does anyone know of a better tool compare only the contents of dlls?Thanks in advance.
One option is to move to a continuous integration solution such as Cruise Control .Net this allows builds to be triggered on check in to a source control system.
Regarding assembly versioning what I usually do is create a single SolutionVersion.cs (to replace the default assembly version cs) that is linked to each project (use the add existing item but change the button to add as link)
Then I use a NAnt or MSBuild task to take the cruise control build label number and overwrite the SolutionVersion.cs verison numbers before the solution gets built
That way I can take an assembly and trace it back to the code via CruiseControl build version (even better I usually get CC.net to label the source with the same number in source control)
Its not quite what you are asking, but I found this helpful in dealing with large solutions: Versioning Controlled Build. According to its doc it detects the changes you are interested in :
"If there is a file with a more recent timestamp (which means that the source code has been modified after the previous version change), the project will be marked for version update."
The recommended, supportable solution would be for your project to NOT auto-increment the build number using the visual studio way. Then you would need to manually, or write a pre-build script/ MS Build Task to do the increment.
There is an interesting sample in this codeproject article which you should check it out... it involves a prebuild task which does the task of updating the build number based on the day of the year
I would suggest that you look into options that your revision control system provides to embed revision information into source files. I've had enough problems with auto-increment in the past that I promised myself never again. These days I prefer something a little more concrete than a build number though and embed unique identifiers into every product of the build system.
I describe my own system in Embedding mercurial revision information in Visual Studio c# projects automatically. While my solution probably isn't right for you, there were other interesting options suggested in response to my question, so some of the solutions I rejected may, nevertheless, be useful to you, even if you have to adapt them to whatever VCS you use.

How to keep the installer's version number in sync with the installed assemblies' version numbers?

In my current project, I'm producing weekly releases. I've been using the technique described in this post to keep the version numbers of all of the assemblies in my project in sync. (I don't presently have any good reason to track the assemblies' version numbers separately, though I'm sure that day will eventually come.)
When I push out a release, I build a new version of the installer. Unlike all of the assemblies, which can get their version numbers from a shared SolutionInfo.cs file, the version number of the installer isn't, as best I can tell, an assembly property. So my release process includes manually advancing the version number in the setup project.
Or, I should say, usually includes doing that. I'd like to turn that into something I can't screw up. I'm finding the documentation of setup and deployment projects to be surprisingly opaque (it was quite a bit harder to find out how to make it possible for the MSI to uninstall properly if the user installed it to a non-default path, which is a pretty freaking common use case to be undocumented) and have no idea if it's even possible to do this.
Any ideas?
Edit:
Just to clarify, this is a Visual Studio setup and deployment project I'm talking about.
CodeProject has a script to set the version number of an MSI file, which you could run in the pre-built step of the setup project. You find it here:
http://www.codeproject.com/KB/install/NewSetupVersion.aspx
More Details
Be aware that with Windows Installer things are a bit more complicated. MSI files (as the one that you create using a VS Setup and Deployment project) not only have a version number but also a product code which is a GUID value. This product code is used by Windows Installer to uniquely identify your product e.g. in Control Panel -> Add Or Remove programs where you can decide to uninstall or repair a product.
However, when changing you MSI version number, this product code must also be changed in a number of cases. MSI technology is poorly documented but you can find some recommendations when to also change the product code on the following MSDN page: http://msdn.microsoft.com/en-us/library/aa367850(VS.85).aspx.
In my projects I always generate a new product code for every new version. The script on CodeProject will also change the product code for you.
And one more thing: Windows Installer only checks the first three places of the version number afaik, anything in the forth place will be ignored, i.e. 2.3.0.1234 is considered equal to 2.3.0.5678. (ProductVersion)
(There is a related article on CodeProject which might also be interesting to you: http://www.codeproject.com/KB/install/VersionVDProj.aspx)
Its going to depend on the installer toolkit you are using.
We use TFS Team Build and WiX v3. I have a custom build task that increments the build number in Team build (5.0.0.X for example), then this version number is pushed to the common AssemblyInfo.cs AssemblyFileVersion field. It is also passed by MSBuild to our solutions/projects as a property which is then passed into WiX and used to update the installer version as well.
We probably will need to do better with the assembly versioning someday as well, but right now this has been working pretty well for us.
I use a workaround for VS2010 Setup projects (.MSI + setup.exe). Open the .vdproj in Notepad and edit the ProductVersion assignment value (3.2.1 in the example below). Save the file and launch VS2010 by double-clicking on the .vdproj file.
"Product"
{
"Name" = "8:Microsoft Visual Studio"
"ProductName" = "..."
...
"ProductVersion" = "8:3.2.1"
"Manufacturer" = "..."
...
}

Categories