I'm using the BuildInParallel attribute of the MSBuild task to run build projects in parallel. The root project is building four child projects. The child projects are using a custom MSBuild task which starts a new process using System.Diagnostics.Process.
For some reason the spawned process fail to run properly when UseShellExecute is false. I've no idea why this is and I can't figure out what the error is - all that happens is the Process.ExitCode is 1, no exception..
Here's the custom MSBuild task:
using System;
using Microsoft.Build.Utilities;
using System.Diagnostics;
public class MSBuildProcessTask : Task
{
public string Executable { get; set; }
public string Arguments { get; set; }
public override bool Execute()
{
using (var p = new Process())
{
try
{
p.StartInfo = new ProcessStartInfo(Executable, Arguments)
{
UseShellExecute = false,
//RedirectStandardOutput = true
};
//p.OutputDataReceived += (o, e) =>
//{
// if (e.Data != null)
// {
// Log.LogMessage(MessageImportance.Normal, e.Data);
// }
//};
p.Start();
//p.BeginOutputReadLine();
p.WaitForExit();
}
catch (Exception e)
{
throw; // for setting breakpoint
}
finally
{
if (p.ExitCode != 0)
{
Log.LogError("Error. Exit code: " + p.ExitCode);
}
p.Close();
}
}
return true;
}
}
And here's the root MSBuild project file (Test.proj, actually I'm only building two child project here but still get the error..):
<?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask TaskName="MSBuildProcessTask" AssemblyFile="C:\Users\Tom\Sandbox\repository_trunk\MSBuildProcessTask\MSBuildProcessTask\bin\Debug\MSBuildProcessTask.dll" />
<Target Name="Default">
<ItemGroup>
<ProjectFiles Include="$(MSBuildProjectDirectory)\Test.1.proj" />
<ProjectFiles Include="$(MSBuildProjectDirectory)\Test.2.proj" />
<!--<ProjectFiles Include="$(MSBuildProjectDirectory)\Test.3.proj" />
<ProjectFiles Include="$(MSBuildProjectDirectory)\Test.4.proj" />-->
</ItemGroup>
<MSBuild BuildInParallel="true" Projects="@(ProjectFiles)" />
</Target>
</Project>
And here's an example of the child project files (Test.1.proj):
<?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask TaskName="MSBuildProcessTask" AssemblyFile="C:\Users\Tom\Sandbox\repository_trunk\MSBuildProcessTask\MSBuildProcessTask\bin\Debug\MSBuildProcessTask.dll" />
<Target Name="Default">
<Message Text="Hello" />
<MSBuildProcessTask Executable="sqlcmd" Arguments="-S .\SQLEXPRESS -Q "SELECT @@VERSION"" />
</Target>
</Project>
My command line is: C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe /m /nr:false C:\Users\Tom\Sandbox\repository_trunk\MSBuildProcessTask\MSBuild ProcessTask\Test.proj
And here's a sample output:
C:\Users\Tom>C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe /m /nr:false C:\Users\Tom\Sandbox\repository_trunk\MSBuildProcessTask\MSBuildPr
ocessTask\Test.proj
Microsoft (R) Build Engine Version 4.0.30319.1
[Microsoft .NET Framework, Version 4.0.30319.235]
Copyright (C) Microsoft Corporation 2007. All rights reserved.
Build started 16/08/2011 22:22:06.
1>Project "C:\Users\Tom\Sandbox\repository_trunk\MSBuildProcessTask\MSBuildProcessTask\Test.proj" on node 1 (default targets).
1>Project "C:\Users\Tom\Sandbox\repository_trunk\MSBuildProcessTask\MSBuildProcessTask\Test.proj" (1) is building "C:\Users\Tom\Sandbox\reposito
ry_trunk\MSBuildProcessTask\MSBuildProcessTask\Test.1.proj" (2) on node 1 (default targets).
2>Default:
Hello
1>Project "C:\Users\Tom\Sandbox\repository_trunk\MSBuildProcessTask\MSBuildProcessTask\Test.proj" (1) is building "C:\Users\Tom\Sandbox\reposito
ry_trunk\MSBuildProcessTask\MSBuildProcessTask\Test.2.proj" (3) on node 2 (default targets).
------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------
Microsoft SQL Server 2008 (SP1) - 10.0.2531.0 (X64)
Mar 29 2009 10:11:52
Copyright (c) 1988-2008 Microsoft Corporation
Express Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1)
(1 rows affected)
3>Default:
Hello
2>Done Building Project "C:\Users\Tom\Sandbox\repository_trunk\MSBuildProcessTask\MSBuildProcessTask\Test.1.proj" (default targets).
3>C:\Users\Tom\Sandbox\repository_trunk\MSBuildProcessTask\MSBuildProcessTask\Test.2.proj(6,3): error : Error. Exit code: 1
3>Done Building Project "C:\Users\Tom\Sandbox\repository_trunk\MSBuildProcessTask\MSBuildProcessTask\Test.2.proj" (default targets).
1>Done Building Project "C:\Users\Tom\Sandbox\repository_trunk\MSBuildProcessTask\MSBuildProcessTask\Test.proj" (default targets).
Build succeeded.
"C:\Users\Tom\Sandbox\repository_trunk\MSBuildProcessTask\MSBuildProcessTask\Test.proj" (default target) (1) ->
"C:\Users\Tom\Sandbox\repository_trunk\MSBuildProcessTask\MSBuildProcessTask\Test.2.proj" (default target) (3) ->
(Default target) ->
C:\Users\Tom\Sandbox\repository_trunk\MSBuildProcessTask\MSBuildProcessTask\Test.2.proj(6,3): error : Error. Exit code: 1
0 Warning(s)
1 Error(s)
Time Elapsed 00:00:00.23
C:\Users\Tom>
As you can see we only get output from one of the SQLCMD commands. The problem is that the new process doesn't always seem to run, and doesn't produce any error message (only ExitCode 1).