Skip to content

Instantly share code, notes, and snippets.

@michaellwest
Last active August 29, 2015 14:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save michaellwest/63a417d35fa27ffff071 to your computer and use it in GitHub Desktop.
Save michaellwest/63a417d35fa27ffff071 to your computer and use it in GitHub Desktop.
Provides reflection methods to extract version details.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
using System.Text;
using Sitecore.SharedSource.Reflection;
using Sitecore.Pipelines.GetAboutInformation;
namespace Sitecore.SharedSource.Pipelines
{
public class ApplicationDetails
{
public void Process(GetAboutInformationArgs args)
{
var text = new StringBuilder();
text.Append("<span>Build</span></br><span>");
text.Append(ReflectionUtil.GetExecutingAssemblyDetail(ReflectionUtil.AssemblyDetailType.Date));
text.Append("</span></br><span>");
text.Append(ReflectionUtil.GetExecutingAssemblyDetail(ReflectionUtil.AssemblyDetailType.Version));
text.Append("</span>");
args.LoginPageText = text.ToString();
}
}
}
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
using System;
using System.IO;
using System.Reflection;
namespace Sitecore.SharedSource.Reflection
{
public sealed class ReflectionUtil
{
/// <summary>
/// Represents the type of detail to retrive from the assembly. The data is formatted and therefore will
/// not appear exactly is seen through Microsoft Windows Explorer.
/// </summary>
public enum AssemblyDetailType
{
/// <summary>
/// Indicates that no detail type is indicated.
/// </summary>
NotSpecified = 0,
/// <summary>
/// Indicates that the detail type is the name of the assembly.
/// </summary>
Name = 1,
/// <summary>
/// Indicates that the detail type is the version of the assembly.
/// </summary>
Version = 2,
/// <summary>
/// Indicates that the detail type is the date the assembly was compiled.
/// </summary>
Date = 3
}
#region Assembly
/// <summary>
/// Returns the details of the executing assembly specified by the <see cref="AssemblyDetailType"/>.
/// </summary>
public static string GetExecutingAssemblyDetail(AssemblyDetailType detail)
{
return AssemblyDetailHelper(detail, Assembly.GetExecutingAssembly());
}
/// <summary>
/// Returns the details of the calling assembly specified by the <see cref="AssemblyDetailType"/>.
/// </summary>
/// <param name="detail">The type of information to extract from the assembly.</param>
/// <returns></returns>
public static string GetAssemblyDetail(AssemblyDetailType detail)
{
return AssemblyDetailHelper(detail, Assembly.GetCallingAssembly());
}
#region Helper
private static string AssemblyDetailHelper(AssemblyDetailType detail, Assembly assembly)
{
switch (detail)
{
case AssemblyDetailType.Date:
return GetAssemblyDate(assembly);
case AssemblyDetailType.Name:
return GetAssemblyName(assembly);
case AssemblyDetailType.Version:
return GetAssemblyVersion(assembly);
case AssemblyDetailType.NotSpecified:
default:
return "No method implemented to return the requested details.";
}
}
private static string GetAssemblyName(Assembly assembly)
{
var filepath = assembly.Location;
var info = new FileInfo(filepath);
var name = String.Format("Assembly: {0}", info.Name);
return name;
}
private static string GetAssemblyVersion(Assembly assembly)
{
var version = assembly.GetName().Version;
var versionMessage = String.Format("Version: {0}.{1}.{2}.{3}",
version.Major, version.Minor, version.Build, version.MinorRevision);
return versionMessage;
}
private static string GetAssemblyDate(Assembly assembly)
{
var date = RetrieveLinkerTimestamp(assembly);
var dateMessage = String.Format("Date: {0}", date.ToString());
return dateMessage;
}
private static DateTime RetrieveLinkerTimestamp(Assembly assembly)
{
var filePath = assembly.Location;
const int cPeHeaderOffset = 60;
const int cLinkerTimestampOffset = 8;
var b = new byte[2048];
Stream s = null;
try
{
s = new FileStream(filePath, FileMode.Open, FileAccess.Read);
s.Read(b, 0, 2048);
}
finally
{
if (s != null)
{
s.Close();
}
}
var i = BitConverter.ToInt32(b, cPeHeaderOffset);
var secondsSince1970 = BitConverter.ToInt32(b, i + cLinkerTimestampOffset);
var dt = new DateTime(1970, 1, 1, 0, 0, 0).AddSeconds(secondsSince1970);
dt = dt.AddHours(TimeZone.CurrentTimeZone.GetUtcOffset(dt).Hours);
return dt;
}
#endregion Helper
#endregion Assembly
}
}
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<pipelines>
<getAboutInformation>
<!-- Pipeline to render application version details on the login page. -->
<processor type="Sitecore.SharedSource.Pipelines.ApplicationDetails, Sitecore.SharedSource.Version" />
</getAboutInformation>
<initialize>
</pipelines>
</sitecore>
</configuration>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment