2011-08-16 47 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任務具有您描述的行爲。 –