How to Find the Public Key Token for a Strongly-Named Assembly

Posted on Updated on


In another post, we discussed why you should strongly name assemblies and how to do it via the Strong Name Tool (sn.exe). In this quick post we will consider another scenario – how to get the public key token string value of a strongly named assembly (dll).

This is easily accomplished by using the Strong Name Tool as well by simply using the -T switch and specifying the path and name of the dll for which to retrieve the public key token. It can also be done in code using the System.Reflection.Assembly class. We will take a quick look at each approach.

Using the Strong Name Tool

To use the Strong Name Tool (sn.exe), simply open the Microsoft Visual Studio Developer Command Prompt and use the following syntax:

sn.exe -T <assembly path and name>

For this example, we will retrieve the public key token for an assembly named SampleClassLibrary.dll that is located in the c:\Temp folder.

Get Public Key Token of Strongly Named Assembly using Strong Name Tool

For this example, the public key token is ba27e13c07659075.

Using the System.Reflection.Assembly Class – Getting the Public Key Token in Code

The manner in which we get the public key token for an assembly depends upon our point of reference. For example, we can do it for the currently executing assembly, do it for a specific assembly based on a file path, or do it for one or all assemblies that have been loaded within the current AppDomain.

Let’s consider two of these scenarios:

Getting the Public Key Token for the Currently Executing Assembly

To demonstrate this approach, I have created a simple method in a sample class:

public void GetPublicKeyTokenForThisAssembly()
{
    byte[] token = Assembly.GetExecutingAssembly().GetName().GetPublicKeyToken();
}

Now, if we execute this code, and place a breakpoint on the line that gets the byte array, we can use Visual Studio debugging to view the results of our token retrieval.

PublicKeyTokenDebuggerView

Since the return type is a byte array, the results are exactly as we would expect. So how do we convert that to the same string that we saw when we did it through the Strong Name Tool?

We write a little bit of C# code to do this as shown below:

byte[] token = Assembly.GetExecutingAssembly().GetName().GetPublicKeyToken();

StringBuilder sb = new StringBuilder();

for (int i = 0; i < token.GetLength(0); i++)
{
     sb.Append(String.Format("{0:x2}", token[i]));
}

string publicKeyToken = sb.ToString();

The result of this is the public key token that we retrieved using the Strong Name Tool above.

If you are wondering what the “{0:x2}” formatter does, this is something known as Composite Formatting. The hexadecimal format specifier (X) converts a number to a string of hexadecimal digits. The “2” instructs the runtime to produce a string with a length of 2.

Getting the Public Key Token for Assemblies in the Current AppDomain

Though the point of this post is not to discuss Reflection or how to use the methods of the Assembly class, it is beneficial to take a look at how this same logic could be applied to all assemblies loaded within the current AppDomain.

To do this, we merely have to change our code to get the assemblies and iterate through them to retrieve the public key tokens.

byte[] token;

StringBuilder publicKeyTokens = new StringBuilder();
Assembly[] loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies();

foreach (Assembly assembly in loadedAssemblies)
{
    token = assembly.GetName().GetPublicKeyToken();
    StringBuilder sb = new StringBuilder();

    for (int i = 0; i < token.GetLength(0); i++)
    {
        sb.Append(String.Format("{0:x2}", token[i]));
    }

    publicKeyTokens.AppendLine("The public key token for assembly " + assembly.FullName + " is:  " + sb.ToString());
}

string allPublicKeyTokens = publicKeyTokens.ToString();

The output of our StringBuilder is as follows:

The public key token for assembly mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 is:  b77a5c561934e089
The public key token for assembly Microsoft.VisualStudio.HostingProcess.Utilities, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a is:  b03f5f7f11d50a3a
The public key token for assembly System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 is:  b77a5c561934e089
The public key token for assembly System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a is:  b03f5f7f11d50a3a
The public key token for assembly System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 is:  b77a5c561934e089
The public key token for assembly Microsoft.VisualStudio.HostingProcess.Utilities.Sync, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a is:  b03f5f7f11d50a3a
The public key token for assembly Microsoft.VisualStudio.Debugger.Runtime, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a is:  b03f5f7f11d50a3a
The public key token for assembly vshost32, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a is:  b03f5f7f11d50a3a
The public key token for assembly System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 is:  b77a5c561934e089
The public key token for assembly System.Xml.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 is:  b77a5c561934e089
The public key token for assembly System.Data.DataSetExtensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 is:  b77a5c561934e089
The public key token for assembly Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a is:  b03f5f7f11d50a3a
The public key token for assembly System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 is:  b77a5c561934e089
The public key token for assembly System.Deployment, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a is:  b03f5f7f11d50a3a
The public key token for assembly System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 is:  b77a5c561934e089
The public key token for assembly WindowsFormsApplication2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null is:
The public key token for assembly SampleClassLibrary, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ba27e13c08759075 is:  ba27e13c08759075

If you notice the assembly for my sample WinForms assembly shows a PublicKeyToken that is null. Why is this? Because I did not strongly name that assembly! Also, notice that in our code we extracted the FullName value for each assembly. This is an important point when talking about strong naming because the FullName shows us the name, version, public key token, and culture information.

In this simple little sample, I utilized a solution with two projects: a WinForms project and a class library that is referenced by the WinForms project. In this sample, the class library is strongly named and the WinForms project is not. This is okay, but the opposite scenario is not. Suppose that we strongly name the WinForms assembly but remove the strong name from the class library. The compiler will bark at us then we try to build the solution because as we said before, a strongly named assembly requires all referenced assemblies to be strongly named as well. The output below is generated when we try to build under the second scenario:

strongnamedcompilererror

 

 

Leave a comment