Only sign assemblies with strong name during release build

13.1k Views Asked by At

The scenario is: I'm building my solution with TeamCity, I'm not running the build account as an administrator; so I get problems with the strong name keys.

I know of a few solutions out there, like running the build as an administrator and registering the certificates in the proper container.

Is there anyway to sign the assemblies within a solution file only during a release build and not during a debug build. Or are there any similar solutions?

I think it is strange that there isn't a MSBuild parameter that can be set wether the assemblies should be signed or not. Because if you look at the csproj-files there is an option there for signed or not signed

3

There are 3 best solutions below

2
SLaks On

You can use preprocessor directives:

#if SIGN
//Only the Release build is signed
#pragma warning disable 1699  //We can't use the compiler switch
[assembly: AssemblyKeyName("KeyContainerName")]
#pragma warning restore 1699
#endif

Then define the SIGN symbol in the Release configuration.

You must install the key into a key container using sn.exe. Alternatively, you can use [AssemblykeyFile] to specify a path.

The #pragma suppresses this warning.

0
Jehof On

Another option is to edit the project file. By default if you enable assembly signing in Visual Studio it will be used for all build configurations. The project file contains an element like the following.

<PropertyGroup>
  <SignAssembly>true</SignAssembly>
</PropertyGroup>
<PropertyGroup>
  <AssemblyOriginatorKeyFile>YourKeyFile.pfx</AssemblyOriginatorKeyFile>
</PropertyGroup>

If you only want to sign the assemblies during a specifc build configuration, such as RELEASE. You can put the <SignAssembly> and <AssemblyOriginatorKeyFile> in the PropertyGroup element with the Condition that identifies your build configuration.

So if you want to sign your assembly during a release build, you can change your project file to the following.

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
  <!-- other element of this PropertyGroup -->
  <SignAssembly>true</SignAssembly>      
  <AssemblyOriginatorKeyFile>YourKeyFile.pfx</AssemblyOriginatorKeyFile>
</PropertyGroup>

Note: When you change your project file, to the following. you cannot change the signing settings of the Project Properties in Visual Studio. That means in Visual Studio is signing of the assembly disabled, also if you change the build configuration in Visual Studio.

1
tm1 On

Here's a solution where the assembly is signed in Release configuration, but not in Debug configuration. It uses the signing facilities from the project, not using the [AssemblyKeyFile] attribute. It's basically the same as Jehof's answer but in other words.

  1. Set up the project for signing in the Signing tab in project preferences.
  2. Unload the project, and edit it in the XML editor. Locate the SignAssembly property. Move that property into the two configuration dependent property groups. In the Debug configuration, set the property to false.

This will look something like this:

<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
    <!-- ... -->
    <SignAssembly>false</SignAssembly>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
    <SignAssembly>true</SignAssembly>
</PropertyGroup>

Visual Studio works correctly even when changing build configurations, with the exception of the Sign the assembly check box in the Signing tab. I tested with Visual Studio 2008.

Cave-Eats:

  • You need to remove the [AssemblyKeyFile] attribute for this to work.
  • If you have [InternalsVisibleTo] attributes, you need to maintain two versions, like this:
#if DEBUG
[assembly: InternalsVisibleTo("MyLib.NUnit")]
#else
[assembly: InternalsVisibleTo("MyLib.NUnit, PublicKey=<your public key>")]
#endif

In other words, MyLib.NUnit must also be signed in Release configuration.