Sharing a Strong Name Key File Across Projects

v2.0 of the .NET Framework deprecated the use of the AssemblyKeyFileAttribute and AssemblyKeyContainerAttribute.  Often times, these attributes were used to share a common key file across several projects.

If you try to share key files using the Visual Studio 2005 <Browse ...> function on the signing property page, you'll find that the key file is copied into your project directory.  In a lot of cases this is exactly the desired behavior since it helps to group all of the artifacts that go into building your project into one location.  However, it is a common requirement that the key file not be copied into every project directory and instead referenced from a single common location.  You can still pull this off using Visual Studio 2005:

Step 1: Add the key file to your project using the Add Existing Item menu.

Add an existing item to the project

Step 2: In the add dialog, instead of choosing to add the key directly (which will make a copy into your project directory), hit the arrow next to the Add button and choose to add the key as a link.

Add a link to the key

Step 3: Go to the signing page of the project properties.  Your key file should now be on the drop down list of available keys.

Select the key on the signing page

Since the key is already a part of the project, Visual Studio will not  make a new copy of it.  One thing to notice, Visual Studio will reference your key as a relative path from the project file.  This may be exactly what you want -- but if you'd rather have a hard coded path, you can open up the project file and change the AssemblyOriginatorKeyFile (and the Include path of the Link to your key).

You'll also want to make sure that on the property sheet of the key file, the Build Action is set to None and Copy to Output Directory is set to "Do not copy" -- You don't want to accidentally start distributing your key file as an embedded resource!

Finally, there are a couple of tweaks you can make for asthetics. After setting up signing, some people like to add the key as a solution item, then edit the project files and add a <Visible>False</Visible> tag to the None tag including the key.  This presents the key in the Solution Explorer at the solution level rather than in each individual project.

Personally, I like to see the key file that each assembly will be signed with, but I don't want it cluttering the root level of the project's files.  The tweak I make is to edit the project files and change the Link tag to have a Properties prefix.  For instance, I might have:

<ItemGroup>
  <None Include="..\App.snk">
    <Link>Properties\App.snk</Link>
  </None>
</ItemGroup>

This puts the key in the properties node of the project, which I think is a more appropriate location for it than the project root.