The real solution to 'error MSB4175: The task factory 'CodeTaskFactory' could not be loaded from the assembly'

I now have a real solution to the problem that I outlined on Saturday night and this solution, unlike the one developed during my “Macallan driven development” session on Saturday evening actually works.

The problem is that when using code to run build using VS2010 by running a project into devenv.com I get the following error message:

C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v12.0\CodeAnalysis\Microsoft.CodeAnalysis.targets(214,5):
error MSB4175: The task factory "CodeTaskFactory" could not be loaded from the assembly
"C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Build.Tasks.v12.0.dll".
Could not load file or assembly 'file:///C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Build.Tasks.v12.0.dll'
or one of its dependencies. The system cannot find the file specified.

The project builds correctly from the command window using the exact same command line as I use in my calls to CreateProcess().

I was on the right track on Saturday evening. It is an environment issue, just not the one that I thought it was. I also now understand why I thought I’d solved the problem on Saturday night only to discover that the fix didn’t work when I checked it again on Sunday morning.

The problem is caused by the presence of “VisualStudioVersion” in the environment. This variable is set to 12.0 when my task runner program is run from within VS2013 either when debugging or running without the debugger attached but launching from within VS2013. The presence of this variable in the task runner’s environment somehow causes VS2010 to use the latest version of MSBuild that ships with VS2013. When doing this MSBuild gets confused about which .Net framework directory to load assemblies from and fails to locate its dll. Removing the “VisualStudioVersion” from the inherited environment before launching VS2010 programmatically fixes the problem.

Running my task running from a normal command prompt, rather than from inside of VS2013, allows it to work correctly without needing to remove the variable (as the variable is only added by VS2013 itself). I expect that I tested like this on Saturday night and that’s what made me think I’d solved the problem them.

VS2013 actually adds several “VisualStudio” variables to the environment and I now remove all of them before running any task from my task runner.