I’ve just spent the morning helping a client with a few team build problems they were having using a newly installed TFS2008 server and a new build server.

Where’s LC.exe?

The first problem they had was that when they were running their build they were getting an error as follows:

Task failed because "LC.exe" was not found, or the .NET Framework SDK v2.0 is not installed.  The task is looking for "LC.exe" in the "bin" subdirectory beneath the location specified in the SDKInstallRootv2.0 value of the registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework.  You may be able to solve the problem by doing one of the following:  1.) Install the .NET Framework SDK v2.0.  2.) Manually set the above registry key to the correct location.  3.) Pass the correct location into the "ToolPath" parameter of the task.

LC.exe is the program the is used to processes the *.licx files when dealing with 3rd party custom controls (they were using Janus controls) and for some reason the file couldn’t be loaded even though the LC.exe file could be found on the disk.

The thing to note for this is that they were using a new build server.  It has TeamBuild 2008 and VS2008 SP1 installed and was successfully building a separate project (that didn’t have licx files).

As it turns out, the problem related to the fact that they were trying to build a VS2005 sln file.  Since the build server didn’t have VS2005 installed on it many of the settings the installer normally creates were present, including the ones that set the paths for the LC.exe.

Instead of mucking around with VS2005 solutions, we simply converted it to a VS2008 solution and the LC.exe problem went away.

As a note we could have installed VS2005 on the build server as well but since the team was moving to VS2008 anyway the solution conversion option was deemed to be the better choice.

However, once we’d done this we ran into another problem.

Strong Naming Shenanigans

The solution being built included a strong named assembly, with the signing processing using a .pfx file instead of the usual .snk file.  When the build ran we saw this error message:

Target ResolveKeySource: 
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Microsoft.Common.targets(1718,7): error MSB4018: The "ResolveKeySource" task failed unexpectedly.
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Microsoft.Common.targets(1718,7): error MSB4018: 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.
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Microsoft.Common.targets(1718,7): error MSB4018: at System.Windows.Forms.Form.ShowDialog(IWin32Window owner)
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Microsoft.Common.targets(1718,7): error MSB4018: at System.Windows.Forms.Form.ShowDialog()
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Microsoft.Common.targets(1718,7): error MSB4018: at Microsoft.Build.Tasks.ResolveKeySource.ResolveManifestKey()
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Microsoft.Common.targets(1718,7): error MSB4018: at Microsoft.Build.Tasks.ResolveKeySource.Execute()
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Microsoft.Common.targets(1718,7): error MSB4018: at Microsoft.Build.BuildEngine.TaskEngine.ExecuteTask(ExecutionMode howToExecuteTask, Hashtable projectItemsAvailableToTask, BuildPropertyGroup projectPropertiesAvailableToTask, Boolean& taskClassWasFound)
Done building target "ResolveKeySource" in project "xxx.yyy" -- FAILED.

Since MSBuild runs non-interactively any time a dialog box appears the build will break (as the dialog box can’t be shown).

So what was actually happening here to cause a dialog to appear?

The eagle eyed amongst you will probably have figured it out already, but for those who couldn’t be bothered thinking too much I’ll tell you.  As it turns out when you do a compile and sign your assemblies with a .pfx file Visual Studio will look in the local certificate store to see if the certificate is already known.  If it’s a certificate that hasn’t been used before then Visual Studio will attempt add it to the local certificate store and in doing so will prompt you to enter the private key as part of the installation process.  This is where a dialog box will appear.

Since this was a new build server the .pfx file obviously hadn’t been seen yet and so Team Build was trying to prompt for the private key so it could install the certificate.

The solution to this was to simply log on to the build server as the build service account, run the build manually via Visual Studio and enter the private key when prompted.

Subsequent builds then worked as expected as the certificate was now loaded in the certificate store.

(Thanks to Ed Blankenship and his blog for the info on this one)