Tag Archives: C#

Understanding AssemblyFileVersion

A few days ago, I was messing around trying to update the information of a DLL that was built on a central TFS server.  I was using a custom activity to interpret AssemblyInfo.cs, and change certain values before the final DLL was generated.  I came across an interesting observation and would like to share these findings, and maybe shed some insights to people who encounter such a behaviour.

For my test, I set the AssemblyInfo.cs as follows, then proceeded to build that DLL:

  • AssemblyVersion =
  • AssemblyFileVersion = 1.0.<SourceControlNumber>.<Date:yyMMddHHmm>, which happen to be 1.0.427.1403112154

I then queried that DLL using 3 different methods

  • Using ls *.dll -r | % versioninfo
    • ProductVersion = 1.0.427.1403112154 (Qn: Where did Product Version come from?)
    • FileVersion = 1.0.427.1403112154
  • Using PS with .NET classes, I get (as expected)
    • FileVersion = 1.0.427.1403112154
    • AssemblyVersion =
  • Using the view file properties in windows explorer, I get
    • FileVersion = 1.0.427.51930 (Qn: Where did this value come from?)
    • Product Version = 1.0.427.1403112154 (Qn: Where did Product Version come from?)

The results of these queries are show below



Let’s tackle the Product Version question first.  MSDN says

ProductVersion first looks to see if the assembly containing the main executable has the AssemblyInformationalVersion attribute on it. If this attribute exists, it is used for bothProductVersion and CommonAppDataPath. If this attribute does not exist, both properties use the version of the executable file instead.

So, since we did not set a AssemblyInformationalVersion, the DLL defaults to use FileVersion instead.  From what we see, this seems like the observed behaviour.  However, when I subsequently tried injecting a AssemblyInformationalVersion, the DLL still continues to show the File Version.  This will need further research.  Please share if you know why this is happening.


Next,  the File Version value presented in the file properties window differs from the actual value retrieved via powershell/.NET.  This different may cause confusion to anyone looking at the FileVersion information.  I spent a fair bit of time trying out various permutation to try to understand the behaviour.  The breakthrough came when I set FileVersion = 1.0.427.2014, which gave me this:


In this scenario, both File Version report the same result.  Looking up MSDN yields the following:

A file version number is a 64-bit number that holds the version number for a file as follows:

Putting together a quick test app, we see that a ushort (unsigned short, 16 bit number) parse of the original 1403112154 yields 51930!


So it seems that although you can push values larger than 16bit into each subset of fileversion, file properties renders it as a 16 unsigned short.  Hence, if you need to use file properties to retrieve such information, keep each subset of version to be no larger than what ushort can hold.

Hopes this helps someone someday.


Customising VS2010 project files.

Just a quick snippet for doing the following (mainly for myself):

  • Performing actions conditionally as part of a build process
  • List of available variables
  • Invoking the TransformXml Tasks
  • Invoking the Copy Tasks
Code Snippet
  1. <Target Name="AfterBuild" >    
  2.     <CallTarget Condition="$(IsTFSPackagingBuild)=='True'" Targets="TFSBuild" />
  3.     <CallTarget Condition="$(IsTFSPackagingBuild)!='True'" Targets="LocalBuild" />
  4.   </Target>
  5.   <Target Name="TFSBuild" >
  6.     <ItemGroup>
  7.       <DeleteAfterBuild Include="$(WebProjectOutputDir)\Web.*.config" />
  8.     </ItemGroup>
  9.     <TransformXml Source="Web.config" Transform="Web.TEST.config" Destination="$(WebProjectOutputDir)\Web.TEST.config.transform" />
  10.     <TransformXml Source="Web.config" Transform="Web.QA.config" Destination="$(WebProjectOutputDir)\Web.QA.config.transform" />
  11.     <TransformXml Source="Web.config" Transform="Web.PROD.config" Destination="$(WebProjectOutputDir)\Web.PROD.config.transform" />
  12.     <Delete Files="@(DeleteAfterBuild)" />
  13.   </Target>
  14.   <ItemGroup>
  15.     <MySourceFiles Include="Web.config.transform" />
  16.     <MyDestinationFiles Include="Web.config" />
  17.   </ItemGroup>
  18.   <Target Name="LocalBuild" >  
  19.     <Message Text="MSBuild: $(MSBuild)"/>
  20.     <Message Text="MSBuildBinPath: $(MSBuildBinPath)"/>
  21.     <Message Text="MSBuildExtensionsPath: $(MSBuildExtensionsPath)"/>
  22.     <Message Text="MSBuildExtensionsPath32: $(MSBuildExtensionsPath32)"/>
  23.     <Message Text="MSBuildExtensionsPath64: $(MSBuildExtensionsPath64)"/>
  24.     <Message Text="MSBuildLastTaskResult: $(MSBuildLastTaskResult)"/>
  25.     <Message Text="MSBuildNodeCount: $(MSBuildNodeCount)"/>
  26.     <Message Text="MSBuildOverrideTasksPath: $(MSBuildOverrideTasksPath)"/>
  27.     <Message Text="MSBuildProgramFiles32: $(MSBuildProgramFiles32)"/>
  28.     <Message Text="MSBuildProjectDefaultTargets: $(MSBuildProjectDefaultTargets)"/>
  29.     <Message Text="MSBuildProjectDirectory: $(MSBuildProjectDirectory)"/>
  30.     <Message Text="MSBuildProjectDirectoryNoRoot: $(MSBuildProjectDirectoryNoRoot)"/>
  31.     <Message Text="MSBuildProjectExtension: $(MSBuildProjectExtension)"/>
  32.     <Message Text="MSBuildProjectFile: $(MSBuildProjectFile)"/>
  33.     <Message Text="MSBuildProjectFullPath: $(MSBuildProjectFullPath)"/>
  34.     <Message Text="MSBuildProjectName: $(MSBuildProjectName)"/>
  35.     <Message Text="MSBuildStartupDirectory: $(MSBuildStartupDirectory)"/>
  36.     <Message Text="MSBuildThisFile: $(MSBuildThisFile)"/>
  37.     <Message Text="MSBuildThisFileDirectory: $(MSBuildThisFileDirectory)"/>
  38.     <Message Text="MSBuildThisFileDirectoryNoRoot: $(MSBuildThisFileDirectoryNoRoot)"/>
  39.     <Message Text="MSBuildThisFileExtension: $(MSBuildThisFileExtension)"/>
  40.     <Message Text="MSBuildThisFileFullPath: $(MSBuildThisFileFullPath)"/>
  41.     <Message Text="MSBuildThisFileName: $(MSBuildThisFileName)"/>
  42.     <Message Text="MSBuildToolsPath: $(MSBuildToolsPath)"/>
  43.     <Message Text="MSBuildToolsVersion: $(MSBuildToolsVersion)"/>    
  44.     <Copy
  45.             SourceFiles="@(MySourceFiles)"
  46.             DestinationFiles="@(MyDestinationFiles)"
  47.         />
  48.   </Target>

Additionally, links to the resources that dive into the details.

Hope this helps!

C# Screen Capture App using Win32 API

As part of a mini project that I’m working on, I needed a way to allow the user to select a portion of the screen.  Hit the link for the bit of code that does that.


I’m looking to improve the code in the following aspects, so let me know if you have any ideas on how to get it done:

#1 Speed up the screen capture in any way.

#2 Some how get the thumbnail from Desktop Window Manager (DWM-Windows 7) to be drawn on a surface or memory for further image processing.