How to run MSBuild from Powershell without spawning msbuild.exe process? How to run MSBuild from Powershell without spawning msbuild.exe process? powershell powershell

How to run MSBuild from Powershell without spawning msbuild.exe process?


The simplest embedded-build invocation that worked and produced output was:

[void][System.Reflection.Assembly]::Load('Microsoft.Build.Engine, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a')$engine = New-Object Microsoft.Build.BuildEngine.Engine$engine.RegisterLogger((New-Object Microsoft.Build.BuildEngine.ConsoleLogger))$engine.BuildProjectFile('fullPath\some.proj')

However, it turns out embedding MSBuild directly in Powershell (V1) is problematic:

'MSBUILD : warning MSB4056: The MSBuild engine must be called ona single-threaded-apartment. Current threading model is "MTA".Proceeding, but some tasks may not function correctly.'

Why oh why are we still paying COM tax in 2009 while working in a managed environment?

My conclusion is that embedding MSBuild in Powershell (V1) is not a good idea. For reference, I'm also including the process-based approach I ended up using:

[void][System.Reflection.Assembly]::Load('Microsoft.Build.Utilities.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a')$msbuild = [Microsoft.Build.Utilities.ToolLocationHelper]::GetPathToDotNetFrameworkFile("msbuild.exe", "VersionLatest")&$msbuild fullPath\some.proj


I would very highly suggest looking at PSake.

Let me quote a portion of that page:

Remember that psake is syntactic sugar around PowerShell. So anything you can do in PowerShell, you can do in psake. That means that you can run MSBuild, NAnt, or other scripts. There is no need to completely replace your current build system. You can use psake to automate and extend it!

psake automatically adds the appropriate version of .NET Framework to its path. So you can access MSBuild, csc.exe, vbc.exe, or any other tools installed in $env:windir\Microsoft.NET\Framework\$version\ without the fully qualified path.


A different and potentially more usable approach would be to make an msbuild cmdlet. MsBuild has a nice API and there are many samples out there on how to use it from a compiled language such as C#/VB. It would be very easy to build a cmdlet that would provide a much nicer syntax to your powershell scripts.