Category 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!

Migrating WF Application to Azure via Windows Azure Accelerator for Web Roles

While wrapping up my demos for my presentation “Moving WF applications to Azure”, I decided to repackage my demos using Windows Azure Accelerator to conserve the number of Web Roles I was using in Azure. 

A quick summary of the issue is as follows:

  1. Create a Windows Azure Accelerator project, and upload it to Azure (Steps performed according to instructions provided by WAA)
  2. From the base address (i.e. <application>, create a IIS Site name.  I just typed a random, non-active hostname for the Hostname, as I was intending to use the test link instead.
  3. Create a Windows WF 4.0 project, and browse to it. The generated screen with a link to the WSDL is displayed.image
  4. Publish the WF Application to the IIS web site.  It doesn’t matter if the deployment is marked as an IIS application.image
  5. Browse to the test site where a page showing that metadata publishing is disabled. (i.e the /test/testwf/ location, rather than from the host name)image
  6. No amount of web.config changes will enable the metadata publishing, such as an example below.image

Logging onto the Azure Web Role instance revealed the following IIS setup.


I’m guessing that the test sites use URL Rewrite, but somehow the web.config is not picked up.

What finally worked for me is as follows:

  1. Get a DNS Alias (CNAME) to point to my base cloud application, e.g. using a free domain name from
  2. Reconfigure WAA to accept the new Host Nameimage
  3. Browse to the WF Service using the Site address instead of the test site address, and voila, the no configuration setup now works.
  4. image

I hope this helps someone save a couple of hours of sleep.  Now onto figuring out Azure Composite Applications.

Presentation: "Moving WF Applications to Azure”


My presentation "Moving WF Applications to Azure" to the Azure User Group Singapore ( on 29th Nov 2011 covered the following topics:
– What is Window Workflow Foundation?
– What are the features, and how does one implement them?
– Why is it relevant to applications moving into Azure?
– What are my migration / development options for using WF in Azure?


Slides have been uploaded to Slideshare:

Demo codes have been uploaded to Azure Storage
– WFSoln:
– AzureWFSoln:

[Updated] Migrations using Windows Azure Accelerator for Web Roles has been resolved.  Please take a look at

Windows Workflow Receive Activity–Parameter Behaviour

I recently had an experience where I had created a workflow service that was invoked using a channel factory and accepts 2 String arguments. However, after some base component refactoring, and porting the old workflow use the new components, the invocation failed with incorrect numbers of parameters.

I came across Ron Jacob’s post on making WF Services work like WCF and did a small spike project based on this blog post :


Definition image
WCF Test Client Proxy image
XML Message image


The corresponding WF Service was created, and I updated the Receive configuration to use parameters, but the behaviour did not yet match that of the WCF method.

  Workflow Service
Definition image
Receive Configuration image


Apparently, the Send Parameters also has to be configured so that the behaviour is consistent.

  WF / Non-WCF behaviour WF / WCF behaviour
Send Configuration image image
WCF Test Client Proxy image image
XML Message image


With this change on my workflow, my channel factory invocation now works again!

Performing an XPath query on a Windows Workflow XAML

I was working on parsing the information from a Microsoft .Net 4.0 Workflow XAML and was stuck trying to perform an XPath query to extract out the various “State Machine State” from the XAML.

After spending some time on good old MSDN,  we find the following piece of information.


With this in hand, we add a dummy namespace prefix using the XmlNamespaceManager and viola, the query now works~!


I hope this helps someone.

Alert: Security Refresh for Windows Azure SDK v1.3

The Windows Azure Team has released a security refresh for the v1.3 SDK aimed to fix the issue where by the client to determine the content of the state information passed by the web role.

If you have downloaded the V1.3 SDK prior to 3 Feb 2011, perform the quick check to see if you need to have it patched.

Control Panel > Programs > Programs and Features

Scroll to Windows Azure SDK and note the version number.  Anything less than 1.3.20121.1237 means that your web role(s) may be vulnerable.



Download the patch files from Microsoft (links below), and install in.  Zip through the various EULA and install options.  You may be prompted to shut down some services for the patch to go through.image

Verify that the installation was successful (or you already have a patch SDK)



Full details and patch links available directly from Microsoft: