I thought I could get away with installing .Net 4.5 without VS2012 or any of the SDK’s so that I could get a manual copy of code analysis working on our build server.
I was very wrong.
The very act of installing .Net 4.5 threw a number of errors to my previously working builds.
C:WindowsMicrosoft.NETFramework64v4.0.30319Microsoft.Common.targets(2836,5): error MSB3086: Task could not find “AL.exe” using the SdkToolsPath “” or the registry key “HKEY_LOCAL_MACHINESOFTWAREMicrosoftMicrosoft SDKsWindowsv8.0AWinSDK-NetFx40Tools-x86″. Make sure the SdkToolsPath is set and the tool exists in the correct processor specific location under the SdkToolsPath and that the Microsoft Windows SDK is installed [C:x.csproj]
C:x2.csproj(178,3): error MSB4019: The imported project “C:Program Files (x86)MSBuildMicrosoftVisualStudiov11.0WebApplicationsMicrosoft.WebApplication.targets” was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.
What I did find is if i browsed to the registry key:
And renamed the key ‘11.0’ to ‘11.0-DoNotUseYet’. it seemed to revert back to windows SDK 7.0.
The worst part is it is running Windows Server 2008 which means I can’t install the 8.0 SDK anyway.
Who would have thought!
I have been doing some serious modifications to our build libraries and I modified all sorts of parameters. I used to set the msbuild property <OutDir>C:lol</OutDir> before the call to main project imports, however with the fantastic introduction of MSBuild 4 now there is the ability for targets to specify ‘BeforeTargets’ and ‘AfterTargets’. This means no longer is it required to mess around with properties in the common targets (BeforeBuildDependsOn) that rudely does NOT care about what is set before it came along.
So I try and achieve the goal of my target being able to included anywhere in the project. This works mostly fine but setting OutDir after common means there are a few properties which are wrongly set such as TargetDir and Target Path.
<TargetDir Condition="'$(OutDir)' != ''">$([MSBuild]::Escape($([System.IO.Path]::GetFullPath(`$([System.IO.Path]::Combine(`$(MSBuildProjectDirectory)`, `$(OutDir)`))`))))</TargetDir>
<TargetPath Condition=" '$(TargetPath)' == '' ">$(TargetDir)$(TargetFileName)</TargetPath>
This meant my wix project was now pointing to the wrong location for the TargetDir and TargetPath variables. So I add in the code to also modify TargetDir when OutDir is changed and wix does not care.
On further invesigation i hardcoded TargetPath to ‘C:ILikeCheeselolrofl.proj’ and even though TargetDir was something sensible wix would still assume targetpath was C:ILikeCheese.
Realistically, TargetDir property is used so little that It should be on the way out yet is still used so critically in Wix and in DesignTimeResolveAssemblyReferences .
Conclusion is that you can not trust the build system to be simple!