Friday, January 24, 2014

Versioning Assemblies in C#

While working on an ASPX page there was some process that was supposed to copy over new DLL's for the page.  It was handy since it did all the registration and whatnot needed to make them work.  Until the page stopped working correctly, inexplicably new code wasn't being pushed to the site.

The errors make sense looking back at it, but when the pages are being updated but not the libraries the run time exceptions can seem pretty vague.  It didn't help that my compiler and debugger were on my laptop while the server hosting the page was in another building.  I could tell that the pages were updated since any old text editor would show it, but the libraries didn't have any useful markers beyond file size.

To finally prove that the libraries were being dropped somewhere I needed to give them version numbers so there was something more concrete to test with.
When dealing with COM Interop I needed to mark class methods to be exposed via the COM interface, this was done by applying the ComVisible() attribute.  I didn't call it an attribute when I wrote that because I didn't really know what those sort of keywords were.  Putting square brackets around an expression like that will be interpreted as applying an attribute by the compiler.

Normally an attribute will be applied to the next object in the file; a namespace, class, or function.  You can put in the assembly keyword to have them applied to the generated assembly instead.  This is what we need to put a version number on the libraries and executables created.

The attributes used to specify version are in the System.Reflection namespace, so we'll need to be sure that's referenced in the code.

Then we set the AssemblyVersion() and AssemblyFileVersion() attributes and mark them to be applied at the assembly level:
1:  using System.Reflection;  
2:    
3:  [assembly: AssemblyVersion("1.2.3.4")]  
4:  [assembly: AssemblyFileVersion("1.2.3.4")]  

We can also put in product descriptions, copyright, and trademark details as well by setting a few more attributes:
1:  [assembly: AssemblyProduct("Just a Test")]  
2:  [assembly: AssemblyCopyright("Copyright © Jason Beighel")]  
3:  [assembly: AssemblyTrademark("We Can Has Learning!")]  

To see the version numbers on Windows you just right click the executable or DLL and choose properties.  Then head to the Details tab and you'll see something like this:

Unfortunately Linux doesn't have any method to get all this information back out.  The best suggestion seems to be to run the assembly through the mono decompiler then look for the version number.  This command should do it:
1:  monodis --assembly XMLTest.exe  

Not  quite as convenient as on Windows, but it suffices.  There are ways to programatically retrieve this information, but I haven't had need for them as of yet.  For now this suits my needs.

No comments:

Post a Comment