Assembly Display Name

Every assembly has so-called "Display name". As of today, the display name of an assembly is shown as "name, Version=xx.xx.xx.xx, Culture=xx, PublicKeyToken=xx". It starts with a "name", then a bunch of "key=value" pairs, separated by comma. Thos keys are called "attributes". The "name" part needs a little explanation, while the other parts are obvious.

The "name" part is usually the file name of the assembly, excluding the extension. So for assembly foo.dll, the "name" part is "foo". Of course, since I said "usually", there are times when the "name" part is not the same as the file name excluding extension. I will discuss this in a bit.

Before we talk about that, first let's talk about what characters are allowed in the "name" part. We know the assembly will exist in file system in as a file. So the "name" must be acceptable by file system. This means path separators ('\' and '/') are illegal in the "name" part. The "name" may also need to be presented in an XML config file. So the characters in the "name" must be within the range defined by XML specification. Specifically,

https://www.w3.org/TR/REC-xml/

2.2 Characters

Character Range
[2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] /* any Unicode character, excluding the surrogate blocks, FFFE, and FFFF. */

Now back to when the "name" part is different from the file name excluding extension. The display name must be able to round trip. Say you have an AssemblyName class, you can get its display name by calling either AssemblyName.FullName, or AssemblyName.ToString(). Now once you have the display name, you should be able to parse the display name, and get back the original AssemblyName class. If you can't do that, it will be utterly confusing.

This requirement means we may have to escape a few characters. At minimum, we have to escape the comma character(',') when it is in the file name, since we are using the comma as the delimiter in assembly display name.

Here is an example:

C:\>more "test,comma.cs"
using System;
using System.Reflection;

class test
{
public static void Main()
{
Console.WriteLine(Assembly.GetExecutingAssembly().FullName);
Console.WriteLine(new AssemblyName(Assembly.GetExecutingAssembly().GetNa
me().FullName).FullName);
}
}

C:\>"test,comma.exe"
test\,comma, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
test\,comma, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null

You can see that we escaped the comma with character '\'. The example also shows we round tripped the display name.

The example is compiled and running under v2.0 beta1. In v1.0/v1.1, we did not handle comma in "name" correctly.

We did not provide a way to translate assembly display name to AssemblyName class in v1.0/v1.1. This is added in v2.0 (public AssemblyName(String assemblyName)).

You should never attempt to parse the display name manually. Use AssemblyName's constructor, and copy the interesting properties.

In v1.0/v1.1, if the display name contains attributes we don't understand, we will happily ignore those attributes. This has been causing problems for us. In v2.0, we change the behavior so that when we see unknown attributes, we will fail the parsing. If this causes problem for you, you can set registry [HKLM\Software\Microsoft\Fusion!UseLegacyIdentityFormat] to 1 to go back to the old behavior.

https://lab.msdn.microsoft.com/productfeedback/viewfeedback.aspx?feedbackid=bab82d4a-62c8-484a-a0aa-149646076b18 is an example when the new behavior breaks applications. But this is a rare example where the MSI package is mis-authored in the first place.