2006-08-04

Signing the Enterprise Library for .NET Framework 2.0 - January 2006

So I've been messing with the Enterprise Library for .NET Framework 2.0 - January 2006 a bit lately (see also patterns & practices: Enterprise Library: Home). Since I'm using strong-named assemblies, I needed to sign the assemblies from the Enterprise Library in order to use them. It seems, however, that this scenario was given little thought since it is quite tedious to do this. Ultimately, through sheer brute force I did manage to get them signed using a key container rather than a key file. Here's how...


Use Windows' "Search" function to find *.csproj in the root installation folder for the Enterprise Library ("C:\Program Files\Microsoft Enterprise Library January 2006" by default) and all sub-folders. Select all of the files (102 of them), right-click, and choose "Properties". Click the box to clear the "Read-only" check box, and "OK" the changes.

Then, open Visual Studio 2005 and use the "Find In Files" feature to find files containing a space, of type *.csproj, in the root installation folder for the Enterprise Library (again, "C:\Program Files\Microsoft Enterprise Library January 2006" by default) and all sub-folders. Also tick the "Display file names only" box.


The names of the 102 files will display in the "Find Results 1" area. In each (EACH!) CSPROJ project file, add <KeyContainerName>ContainerName</KeyContainerName> to the first <PropertyGroup> section, as described in Signing Assemblies in Visual Studio 2005 with Key Containers . If I wouldn't have been so adept at the "click, paste, F8" trio (position the iBeam, paste the key container blurb, go to the next CSPROJ file), I probably would have automated the process with some code or something. Anyway, if this is all one does and one saves the files and then tries to build the Enterprise Library, one gets several CS1726 compiler errors.

Compiler Error CS1726 Error Message
Friend assembly reference 'reference' is invalid. Strong-name signed assemblies must specify a public key token in their InternalsVisibleTo declarations.

To get past the CS1726 errors, more details need to be added to the "InternalsVisibleTo" attribute for various assemblies - specifically, the public key. The public key can be obtained by starting a Visual Studio 2005 Command Prompt or SDK Command Prompt and using SN.EXE (the "Microsoft (R) .NET Framework Strong Name Utility") to extract the public key from the key container:
sn -pc ContainerName PubKeyFile

Then, SN.EXE is used again to display the public key:
sn -tp PubKeyFile

Copy the public key from the console to the clipboard and paste it into Notepad to do a bit of massaging. While you're at it, prefix the public key with ", PublicKey=" so you have something that looks like:
, PublicKey=002400000480000[...]559ea [truncated for brevity]

Copy that whole blurb to the clipboard. Next, use Windows' Search function to find all files named "AssemblyInfo.cs" in the root installation folder for the Enterprise Library and all sub-folders, containing the text "InternalsVisibleTo". Again, select all of the files (15 of them), right-click, and choose "Properties". Click the box to clear the "Read-only" check box, and "OK" the changes.

Then, bring up "Find In Files" in Visual Studio 2005 again, and search the root installation folder for the Enterprise Library for files named AssemblyInfo.cs containing "InternalsVisibleTo". Again, make sure the "Display file names only" box is checked. There should be 15 hits, but note that some files have more than one "InternalsVisibleTo" attribute. Place the iBeam in the attribute after the assembly name, and paste the public key. The attribute should change from something like:
[assembly: InternalsVisibleTo( "Microsoft.Practices.
EnterpriseLibrary.Caching.Tests" )]


to something like:
[assembly: InternalsVisibleTo( "Microsoft.Practices.EnterpriseLibrary.
Caching.Tests, PublicKey=002400000480000[...]559ea" )]
[truncated for brevity]


Change all of the files, save the changes, and build the Enterprise Library. The library should now build successfully.


Note that you can use the "Build Enterprise Library" shortcut in the "Microsoft patterns & practices\Enterprise Library - January 2006" program group, but by default it builds a debug configuration. To build the release configuration, open a Visual Studio 2005 Command Prompt or SDK Command Prompt, navigate to the root installation folder for the Enterprise Library, and run BuildLibrary.bat specifying "Release":
BuildLibrary Release

Then, to copy the assemblies to the bin folder, run CopyAssemblies.bat, also specifying "Release":
CopyAssemblies Release

To copy the assemblies elsewhere, supply the location to CopyAssemblies.bat, like:
CopyAssemblies Release C:\EntLibJan2006

2 comments:

Anonymous said...

Seen this?

http://blogs.msdn.com/tomholl/archive/2005/04/05/405764.aspx

I was going down the same path you were on till a college googled that link.

I tested it out and works fine, only issue was adding the public key to tests assemblyinfo didn't work, so I had to comment them out.

«/\/\Ø|ö±ò\/»®© said...

Not really sure if that applies to this situation, though...

1) While the suggestions are general, and solid, that blog post is from April of 2005 and as such doesn't deal with the Enterprise Library for the .NET Framework 2.0.

2) GlobalAssemblyInfo.cs is great, but as Signing Assemblies in Visual Studio 2005 with Key Containers notes the C# compiler warning CS1699 in the VC# Reference states that "Prior to Microsoft Visual C# 2005, you specified the key file using CLR attributes in source code. These attributes are now deprecated". In the blog post you specified, use of a key container is not covered (only a key file).

Tom Hollander does discuss signing the Enterprise Library for the .NET Framework 2.0 in a comment to his blog post on "Enterprise Library Update". Again, only the notion of signing with a key file is covered. VS 2005's UI for Signing doesn't let one specify a key container, though it is possible to do so by editing the .csproj file (C# tint) as noted here.

... And the method specified in this blog post works, even for the "tests". :)