Did you know… that MD5 hash is a valid GUID?! 😲

/// <summary>
/// Convert string to Guid
/// </summary>
/// <param name="value">the string value</param>
/// <returns>the Guid value</returns>
public static Guid ConvertToMd5HashGUID(string value)
{
  // convert null to empty string - null can not be hashed
  if (value == null)
  {
    value = string.Empty;
  }

  // get the byte representation
  var bytes = Encoding.Default.GetBytes(value);

  // create the md5 hash
  MD5 md5Hasher = MD5.Create();
  byte[] data = md5Hasher.ComputeHash(bytes);

  // convert the hash to a Guid
  return new Guid(data);
}

 

Embedding git commit hash inside of a .net assembly

The need

The need is to easily identify which version of the code is deployed in an environment. Since the project in question wasn’t being build with TeamCity I needed a custom solution.

msbuild to the rescue

msbuild fires BeforeBuild and AfterBuild events during build process for .net application. We can use these events to modify (and reset) AssemblyInfo.cs file to include git commit hash as metadata. Problem with AfterBuild is that it doesn’t run if the build fails so after quite some research I found a PostBuildEvent target which does the job nicely.

The solution looks like this:

In AssemblyInfo.cs file define an attribute to store git commit hash metadata

[assembly: AssemblyMetadata("GitCommitHash", "")]

Then in the csproj file inside some property group without any conditions set this property. Without it PostBuildEvent doesn’t fire on failed builds and you are left with a modified AssemblyInfo.cs which you don’t want.

<RunPostBuildEvent>Always</RunPostBuildEvent>

Then use this joy 🙂

<UsingTask TaskName="SetGitCommitHash" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
  <ParameterGroup>
    <ProjectPath ParameterType="System.String" Required="True" Output="False" />
    <GitCommitHash ParameterType="System.String" Required="False" Output="False" />
  </ParameterGroup>
  <Task>
    <Using Namespace="System" />
    <Using Namespace="System.IO" />
    <Code Type="Fragment" Language="cs"><![CDATA[
var lines = File.ReadAllLines(ProjectPath + @"\Properties\AssemblyInfo.cs");
int hashIndex = Array.FindIndex(lines, l => l.StartsWith("[assembly: AssemblyMetadata(\"GitCommitHash\""));
lines[hashIndex] = "[assembly: AssemblyMetadata(\"GitCommitHash\", \"" + GitCommitHash + "\")]";
File.WriteAllLines(ProjectPath + @"\Properties\AssemblyInfo.cs", lines);
]]></Code>
  </Task>
</UsingTask>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
      Other similar extension points exist, see Microsoft.Common.targets.-->
<Target Name="BeforeBuild">
  <Exec Command="git rev-parse HEAD" ConsoleToMSBuild="true" ContinueOnError="True" Condition=" '$(GitCommitHash)' == '' ">
    <Output TaskParameter="ConsoleOutput" PropertyName="GitCommitHash" />
  </Exec>
  <SetGitCommitHash ProjectPath="$(MSBuildProjectDirectory)" GitCommitHash="$(GitCommitHash)" />
</Target>
<Target Name="PostBuildEvent">
  <SetGitCommitHash ProjectPath="$(MSBuildProjectDirectory)" GitCommitHash="" />
</Target>
<Target Name="AfterBuild" />

On line 1 we define a SetGitCommitHash task which finds the line with target attribute inside of AssemblyInfo.cs file and sets the hash value to whatever is passed to it.
On line 20 a git command is executed to retrieve current commit hash and then on line 21 it’s outputted to a GitCommitHash property. The condition is there for the cases when git command is not available and you are passing in this parameter to msbuild from the outside.
Finally lines 23 and 26 call the SetGitCommitHash to set the hash before build and clean it up after. This leaves no trace that AssemblyInfo.cs was ever modified.

Using the hash

I ended up with this solution. Extracting commit hash from assembly into a static variable during app start and then using it wherever necessary.

public class Global : HttpApplication
{
    public static string CommitHash = string.Empty;

    private void Application_Start(object sender, EventArgs e)
    {
        SetCommitHash();
    }

    private static void SetCommitHash()
    {
        string hash = typeof(Global).Assembly
            .GetCustomAttributes(typeof(System.Reflection.AssemblyMetadataAttribute), false)
            .Cast<System.Reflection.AssemblyMetadataAttribute>()
            .First(a => a.Key == "GitCommitHash").Value;

        CommitHash = hash;
    }
}

The caveat

One caveat to remember is that if the build is happening locally and and you xcopy Release folder output or Publish from VS, make sure that the latest changes are committed or otherwise the code in assemblies will not reflect the commit hash captured during build.

Giving F1 key more action

Visual Studio is the software I use and care about the most and so naturally I tend to customize it to meet my needs better.

One of the more recent customizations is mapping F1 to SolutionExplorer.SyncWithActiveDocument action. So far I’m very happy with this. F1 is getting a whole lot more action now than it used to. Try it 😉

Keyboard mapping options

Did you know that you can do port forwarding with built-in tools?

We needed to forward 300 ports and to do that with AUTAPF 1.1 (port forwarding app that we were using since Windows XP days) would take a whoooole lot of clicks.

A little googling and it turns out that Windows 7/8/2008R2 can do that natively! [source]

That’s superb! Here’s an example:

netsh interface portproxy add v4tov4 listenport=12345 listenaddress=192.168.1.1 connectport=443 connectaddress=192.168.1.1

Happy forwarding 😉

ILSpy plugin to copy Fully Qualified Type Name

Long ago when evil dudes from Red Gate started charging for Reflector an open source alternative called ILSpy emerged.

Like original Reflector it’s very useful for searching classes and methods inside of assemblies.

In projects that I work on we use Unity IoC and we do configuration fully in XML. This of course can suck monkey balls when it’s necessary to map 5 or more interfaces to their implementation which means copying class, interface, namespace and assembly names for each on of them separately.

Being lazy and optimizing close to everything I do, I wrote a small plugin to help with generating fully qualified type names and published it on GitHub (I _LOVE_ GitHub!).
Simply drop all files from Bin folder into ILSpy; find what you need and copy the type name.

Enjoy!

context_menu

Showing Jenkins some love :)

Few days ago I’ve created CruiseControl.NET project for the first time. That was an OK experiance… I played around with dynamic variables, custom labeler, custom NAnt job and automated deployment of one project at work. Results were really satisfying. But then I though.. hey, there was nothing THAT .NET specific with the whole deployment process. So since Hudson/Jenkins are older and I suppore more activly developed projects, next I’ll try to show Jenkins some love 🙂 After all the company I work at is (bigger)half  Java and half .NET so it would make sense to use same technologies throughout all projects.

p.s. For now I’ll just say that I was pleasantly surprised that installing Jenkins was a next next next finish kind of experiance 🙂

C# 5 ir async/await skaidrės ir pavyzdžiai iš .NET vartotojų grupės susitikimo

Neseniai turÄ—jau progÄ… per .NET vartotojų grupÄ—s susitikimÄ… daryti praneÅ¡imÄ… apie C# 5 versijos asinchronijos naujoves su async ir await kalbos keyword’ais. Jei trumpai, tai labai patiko 🙂

Prikabinu skaidres ir rodytus kodo pavyzdžius. Solution’as yra skirtas Visual Studio 11 Developer Preview.

SkaidrÄ—s

AsyncPresentationSamples