2011-08-16 44 views
3

我使用MSBuild任务的BuildInParallel属性并行地运行构建项目。根项目正在建设四个儿童项目。子项目正在使用自定义的MSBuild任务,该任务使用System.Diagnostics.Process启动新的进程。出于某种原因,当UseShellExecute为false时,派生进程无法正常运行。我不知道这是为什么,我也弄不清是什么错误 - 所发生的一切是Process.ExitCode是1,也不例外..MSBuild BuildInParallel,运行失败的自定义任务产卵过程

这里的自定义MSBuild任务:

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; 
    } 
} 

而这里的根MSBuild项目文件(Test.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"> 
     <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> 

而这里的孩子项目文件的例子( 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 &quot;SELECT @@VERSION&quot;" /> 
    </Target> 
</Project> 

我的命令行是:C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe /m /nr:false C:\Users\Tom\Sandbox\repository_trunk\MSBuildProcessTask\MSBuildProcessTask\Test.proj

下面是一个示例输出:

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> 

正如你所看到的,我们只能从SQLCMD命令之一获取输出。

+0

检查窗口事件日志 – sll

+0

没有任何事件日志.. –

+0

(1)不是行** UseShellExecute = false,**最后留下逗号逗号? (2)当UseShellExecute设置为false时,你可以尝试与RedirectStandardOutput设置为true一样吗? – Arun

回答

0

没有机会说出究竟导致问题的原因,您必须亲自调查或至少提供有关错误的更多详细信息。

试试运行MSBuild指定诊断详细级别,将倾倒在非常详细的输出,同时运行:

MsBuild.exe /v:diag 
+1

谢谢sllev,我很感激帮助。我花了大约两天的时间来调查自己,我完全陷入了困境。问题是,新进程似乎并不总是运行,并且不会产生任何错误消息(只有ExitCode 1)。/v:diag输出更多信息,但仍然没有错误信息或线索恐怕。 –

+0

@Tom:你有没有试过调试?如果你能够在MSBuildProcessTask的构造函数中设置断点,那么当VS菜单 - >调试 - >异常 - >启用所有异常,然后继续执行时,设置中断点会很好,因此在出现任何情况时异常你会看到它 – sll

+0

我试过调试。没有例外被抛出。该过程只是完成(没有从SQLCMD输出)并以ExitCode 1结束。当我调用Process.Start()时,有什么办法可以调试“引擎盖下”发生了什么? –

0

你有没有尝试给每个目标唯一的名称(不是“默认”)?

我认为,当你包含一个项目时,msbuild将包含的项目的目标扩展到当前项目中。当您添加与现有名称相同名称的另一个目标时,现有名称将被覆盖。

您可以使用here中所述的/ preprocess开关查看扩展项目的外观。

+1

感谢您的建议,@Alex。不幸的是,使用不同的目标名称并没有什么不同 - 问题仍然存在。请注意,我没有使用[Import元素](http://msdn.microsoft.com/en-us/library/92x05xfs.aspx);我正在使用[MSBuild任务](http://msdn.microsoft.com/en-us/library/z7f65y0d.aspx)构建子项目。我不认为MSBuild任务具有您描述的行为。 –