Introduction
This two part tutorial will cover various ways to programmatically extract the assembly full name signature that is used in configuration files etc. in .NET. I have written all examples in C#, but they can easily be converted to VB. I am using standard C# and therefore it should work in .NET Framework v2.0 and above.
What does a full name mean? It means the fully qualified name for the assembly. This name will include the assembly name, version, culture, and if signed the public key token. The full name is used to identify the correct assembly to be loaded when required.
The full name validates that the assembly found has the correct version or higher (depending on the configuration requirements), the correct culture (if specified) and if the public key token is correct.
The public key token is the last eight bytes of the SH1 hash of the public key.
Depending on your requirements, you may need all of these or only assembly name. Generally, you will need all four parts if used with external systems or if you wish to make it more secure.
I have developed all the examples in VS 2008 with .NET 2.0 framework selected. At the end of the tutorial, you should have a working utility that will extract the assembly full name string from any assembly.
As this article is going to retrieve the full name from the assembly, it would be advisable to make sure that the test assemblies are signed.
The signing file can be auto generated in Visual Studio in the project properties page.
As this tutorial is not required to be secure, I did not specify a password in the dialog.
When clicking on ok, the strong name key file will be created in the project. If you leave the extension off the Key file name, then it will automatically be created with the snk extension. This strong name key file will be used in all the projects.
Background
The basic methods used in this article are taken from the Reflection group of methods in .NET.
Other Tools that do the Same Thing
There are various tools and utilities which will allow you to extract this information for you. With a clean installation of .NET and Visual Studio, you will only have the first two. The downside is that you have to use both to get all the parts.
Ildasm.exe
This is a GUI utility that will load an assembly and show you all the information related to it.
As you can see, it shows various bits of information from the assembly. If you double click on the Manifest node, you will see all the attributes at the assembly level and which assemblies it references. Also you can view the public key from here, but not the public key token! You will be able to see the public token key from the referenced assemblies though.
SN.exe
This is a command line utility primary used for signing assemblies with strong names and key management. If you used with the –T parameter, it will extract the public key token for you on the assembly specified.
Red Gate’s .NET Reflector
This is a free tool provided by Red Gate. It is a very good tool for exploring assembly information. You have to register your name, but that is the only requirement that I can find. It was originally developed by Lutz Roeder.
As you can see, it does give you the full name with public key token as well.
Now why would you continue with the rest of the tutorial, well you don't really have to unless you want to be able to extract this information programmatically yourself.
Extracting Assembly Information
So how do you extract this information from an assembly? The answers is to use reflection coding techniques that are embedded in the .NET Framework.
Full Name Information
If you just want the full name of the assembly that a known class is in, then all you just need is your friendly typeof
operator. One of the properties the typeof
operator will return is the Assembly
object that the class belongs to.
using System;
namespace Test1
{
internal class Program
{
private static void Main(string[] args)
{
Console.WriteLine("Assembly Full Name : "
+ typeof (Program).Assembly.FullName);
}
}
}
The above code will return all of the following:
Assembly Full Name : Test1, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=f74250691b571752
Extracting Public Key Token
To extract the public key token as a string
takes a bit of extra coding. The token is a byte array and will be returned from the method GetPublicKeyToken()
, which is buried in the GetName()
method of the Assembly
class.
byte[] ivtemp = assembly.GetName().GetPublicKeyToken();
From the byte array, we can then construct a string
.
StringBuilder comp = new StringBuilder();
foreach (byte ivt in ivtemp)
{
if (ivt < 16)
{
comp.AppendFormat("0{0:x}", ivt);
}
else
{
comp.AppendFormat("{0:x}", ivt);
}
}
Extracting Assembly Attributes
All the attributes in the AssemblyInfo.cs can be extracted from the assembly easily.
Using the Attribute.GetCustomAttribute static
method, you can retrieve any custom attributes from an assembly and then cast them to the attribute you require.
The following will extract the company name from the assembly.
AssemblyCompanyAttribute compAttr = Attribute.GetCustomAttribute(
typeof(Program).Assembly,
typeof(AssemblyCompanyAttribute)) as AssemblyCompanyAttribute;
if ( compAttr != null )
{
Console.WriteLine("Company : " + compAttr.Company );
}
Version Information
There are various types of versions that can be added to an assembly. For a full description on each type, see MSDN.
- Assembly Version (used by runtime to see if it meets the version requirements of the system)
- File Version (used primary by MSI installer to check to see if upgrade is required, it will set the Win32 file version information in the assembly)
- Information Version (Additional version information if required, only used really for documentation)
The assembly version and assembly file versions can be different, so if you don't want to break existing installations, but do wish to upgrade them, then just increment the AssemblyFileVersion
attribute.
The Assembly Version is the only one that cannot be retrieved using the Attribute.GetCustomAttribute static
method. You can use the following to extract the assembly version:
Console.WriteLine("Assembly Version : " + typeof(Program).Assembly.GetName().Version);
Use the Attribute.GetCustomAttribute static
method to extract out the other version information.
AssemblyFileVersionAttribute fileAttr = Attribute.GetCustomAttribute(
typeof(Program).Assembly,
typeof(AssemblyFileVersionAttribute))
as AssemblyFileVersionAttribute;
if (fileAttr != null)
{
Console.WriteLine("Assembly File Version : " + fileAttr.Version);
}
AssemblyInformationalVersionAttribute infoAttr = Attribute.GetCustomAttribut(
typeof(Program).Assembly,
typeof(AssemblyInformationalVersionAttribute)) as
AssemblyInformationalVersionAttribute;
if (infoAttr != null)
{
Console.WriteLine("Assembly Information Version : "
+ infoAttr.InformationalVersion);
}
Retrieve Information from Non-Loaded Assembly
Now the above code is all well and good, but what happens if you don't already have the assembly loaded in memory! This is handled by Assembly
class’s LoadFrom
method. This method will take in a string
which will contain the path and filename of the assembly to load. It has an optional Evidence
property that you can construct to validate that the assembly can be loaded in your current security context (I will not cover this here as it is outside the scope of this beginner guide, maybe I will cover it in a later guide).
This method will throw various exceptions depending on if it exists in security exceptions (see MSDN help for full details).
Assembly assembly = Assembly.LoadFrom("Test2.exe");
Now you can replace all the typeof(Program).Assembly
commands in the above examples with the assembly
variable.
What's Next?
In part 2, we will be putting together what we learnt into a utility that can be run from Visual Studio External Tools.
This utility will display the following:
- Full Name
- File Version
- Information Version (if exists)
- Culture
- Public Key Token
By default, it will load the Full Name into the clipboard as a handy feature.
I will also show you a way to handle the fact that once an assembly is loaded we have a lock on it, so it cannot be recompiled, etc.
History
- 13th July, 2009 - Initial release