Skip to content

Query installed TwinCAT HMI version and build time

The information in this post can be used with:

  • VisualStudio 2013, 2015, 2017, 2019
  • TE2000-HMI-Engineering 1.10.*.* (Download) and future releases
  • Sources of this post: GitHub Repository

Sometimes it can be very handy to know the currently installed TwinCAT HMI SDK and runtime, e.g. to allow build switches for different versions. Therefor, you only have to query the product version and linker date-time of any installed TwinCAT HMI DLL, e.g. “TcHmiCore.dll” or “TcHmiMSBuild.Publish.dll” etc.

using System;

class Program
{
   static void Main(string[] args)
   {
     var pathToAnyTcHmiDll = @"C:\TwinCAT\Functions\TE2000-HMI-Engineering\MSBuild\TcHmiCore.dll";

     Console.WriteLine("TwinCAT HMI Version:\t{0}", TcHmiDllHelper.GetVersion(pathToAnyTcHmiDll));
     Console.WriteLine("TwinCAT HMI Build:\t{0}", TcHmiDllHelper.RetrieveLinkerTimestamp(pathToAnyTcHmiDll));
     Console.WriteLine("Enter any key...");
     Console.ReadKey();
  }
}

The output will be:

The helper class TcHmiDllHelper is:

using System;
using System.IO;
using System.Reflection;
using System.Diagnostics;

public static class TcHmiDllHelper
{
  public static Version GetVersion(string pathToDll)
  {
    try
    {
      if (!File.Exists(pathToDll)) return null;

      var productVersion = FileVersionInfo.GetVersionInfo(pathToDll).ProductVersion;
      
      if (string.IsNullOrEmpty(productVersion))
      {
        try
        {
          var assembly = Assembly.LoadFrom(pathToDll);
          var ver = assembly.GetName().Version;
          if (ver != null)
            return new Version(ver.ToString());
        }
        catch
        {
          // ignore
        }

        try
        {
          var assembly = Assembly.Load(File.ReadAllBytes(pathToDll));
          var ver = assembly.GetName().Version;
          if (ver != null)
            return new Version(ver.ToString());
        }
        catch
        {
          // ignore
        }
      }
      else
      {
        return new Version(productVersion);
      }
    }
    catch
    {
      // ignore
    }

     return null;
   }

   // StackOverflow: 
   // https://stackoverflow.com/questions/2234969/adding-compilation-date-to-the-code/2235211#2235211
   public static DateTime RetrieveLinkerTimestamp(string pathToDll)
   {
     var filePath = pathToDll;
     const int peHeaderOffset = 60;
     const int linkerTimestampOffset = 8;
     var b = new byte[2048];
     Stream s = null;

     try
     {
       s = new FileStream(filePath, FileMode.Open, FileAccess.Read);
       s.Read(b, 0, 2048);
     }
     finally
     {
       s?.Close();
     }

     var i = BitConverter.ToInt32(b, peHeaderOffset);
     var secondsSince1970 = BitConverter.ToInt32(b, i + linkerTimestampOffset);
     var dt = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
     dt = dt.AddSeconds(secondsSince1970);
     dt = dt.ToLocalTime();
     return dt;
  }
}

Be First to Comment

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.