I'm trying to setup a continuous integration build on TFS 2008. In the project I want to build I use a key for signing. This key uses a password. I can't get it to build, because during the build TFS wants to show a dialog which can't be shown. I think I need to build the project by hand on the server, but only the TFS explorer and build parts are installed on the server. Any suggestions on how to get my project to build properly?
This is the error given by TFS:
C:\WINDOWS\Microsoft.NET\Framework\v3.5\Microsoft.Common.targets(1805,7):
error MSB4018: The "ResolveKeySource"
task failed unexpectedly.
System.InvalidOperationException:
Showing a modal dialog box or form
when the application is not running in
UserInteractive mode is not a valid
operation. Specify the
ServiceNotification or
DefaultDesktopOnly style to display a
notification from a service
application. at
System.Windows.Forms.Form.ShowDialog(IWin32Window
owner) at
System.Windows.Forms.Form.ShowDialog()
at
Microsoft.Build.Tasks.ResolveKeySource.ResolveAssemblyKey()
at
Microsoft.Build.Tasks.ResolveKeySource.Execute()
This blog post below details the exact steps
Setup Key Files
Create a password-protected private/public key pair (KeyPair.pfx) using the Visual Studio “Signing” tab within a project’s properties
Extract the public key from the key pair and copy it to a separate file (Key.snk)
sn.exe -p KeyPair.pfx Key.snk
Copy the KeyPair.pfx to your build server. I use C:\Program Files\MSBuild\KeyFile.pfx, because it can then be accessed by the $(MSBuildExtensionsPath) MSBuild property.
Move the KeyPair.pfx file to a safe & secure location. Keep the password secret as well.
Copy the Key.snk to a shared location where your developers can access it.
Setup Projects for Signing
For each assembly that you want to sign:
- Open the Project Properties | Signing page
- Select the [X] Sign the assembly checkbox.
- Select the [X] Delay sign only checkbox.
- Select from the key file dropdown.
- Browse to the shared location and select the Key.snk file
- The snk file will be copied to each project directory that you assign it to
- Copy the key file from one of your projects into Solution Items so that you can use it for the test run configuration
Setup Test Run Configuration for Re-Signing
If you want to instrument your assemblies and enable Code Coverage for your unit tests, then you need to specify a key file for re-signing.
Open the LocalTestRun.testrunconfig file
On the Code Coverage tab, select the key as the Re-Signing key file
Disable Strong-Name Verification on Developer Workstations
Since you are delay-signing with only the public key, .NET CLR assembly verification will fail with assemblies built locally. When the verification fails you won’t be able to run or debug the assemblies.
To overcome this in development, you need to disable strong-name verification for assemblies that you build locally and delay-sign with your public key.
Open a Visual Studio Command Prompt
Type:
sn.exe -tp Key.snk
This will output some data including the token.
Type:
sn -Vr *,YOUR_KEY_TOKEN
example: sn -Vr *,0123456789abcdef
This will disable strong name verification for all assemblies signed with your public key.
You can list current settings for strong name verification with:
sn -Vl
Installing the Private Key for Team Build
Since the private key (Key.pfx) is password protected – Team Build cannot access it. Thanks to Nagaraju Palla’s Blog: Using Password Protected Signing Keys in Team Build, we have a solution.
Logon to the Team Build server as the build service account
Open the project in Visual Studio
Build the project in Visual Studio
You will be prompted for the password to the private key file.
Enter the password
Close Visual Studio & Log off
The private key file is now installed in the build service account’s local certificate store and Team Build can access it without prompting for the password again. This certificate store is as secure as the build service account’s password. (Hint: Make it just as strong as your keyfile’s password)
Updating TFSBuild.proj Build Script
Team Build has access to the private keyfile and password. This allows it to fully-sign the assemblies.
To override the project settings and instruct Team Build to use the private keyfile and disable partial-signing, we need to set the CustomPropertiesForBuild property in TFSBuild.proj
Check-out your TFSBuild.proj build script
Search for the placeholder property (near line 130 by default)
Replace it with the following:
SignAssembly=true;DelaySign=false;AssemblyOriginatorKeyFile=$(MSBuildExtensionsPath)\Key.pfx
Check-in your changes
Queue a build
Verifying Team Build output
To check that Team Build has correctly strongly named your assemblies, you can use the sn.exe utility to verify the strong name signature.
Open a Visual Studio Command Prompt
Type:
sn.exe -vf assemblyname.dll
You can also verify all your assemblies at the same time:
Open a Visual Studio Command Prompt
Type:
FOR %a IN (*.dll) DO sn.exe -vf %a