2012-09-13 74 views
8

我寫了一個MSBuild項目文件,它嘗試建立並行我所有的VS2010解決方案的CONFIGS:的MSBuild:並行構建和.NET項目

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0"> 
    <ItemGroup> 
    <BuildFile Include="$(SourceRoot)MyProject.sln" /> 
    <Config Include="Debug"> 
     <Configuration>Debug</Configuration> 
    </Config> 
    <Config Include="Release"> 
     <Configuration>Release</Configuration> 
    </Config> 
    </ItemGroup> 

    <Target Name="BuildAll" Outputs="%(Config.Configuration)"> 
    <Message Text="Start building for configuration: %(Config.Configuration)" /> 
    <MSBuild Projects="@(BuildFile)" 
      Properties="Configuration=%(Config.Configuration)" 
      Targets="Build" /> 
    </Target> 
</Project> 

我推出的MSBuild有:

msbuild /m /p:BuildInParallel=true /t:BuildAll buildall.proj 

問題是我的解決方案有很多.Net項目,它們都有相同的輸出文件夾。這些項目也使用相同的外部組件。

因此,經常會同時生成兩個輸出可執行文件,並且它們的相關性會同時被複制。這導致類似的錯誤:

C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(3001,9): 
error MSB3021: 
Unable to copy file "xxx\NLog.dll" to "D:\src\Blackbird\shared\bin\debug\NLog.xml". The process 
cannot access the file 'xxx\NLog.dll because it is being used by another process. 

,我認爲是指:「2個不同的項目中使用NLOG並嘗試其裝配在輸出文件夾在同一時間複製」 ......

是否有辦法解決這個問題?我真的想避免修改解決方案中的所有項目。看看任務源代碼「C:\ Windows \ Microsoft.NET \ Framework \ v4.0.30319 \ Microsoft.Common.targets(3001,9)」,我看到有可能使msbuild重試副本:

<Copy 
    SourceFiles="@(ReferenceCopyLocalPaths)" 
    DestinationFiles="@(ReferenceCopyLocalPaths->'$(OutDir)%(DestinationSubDirectory)%(Filename)%(Extension)')" 
    SkipUnchangedFiles="$(SkipCopyUnchangedFiles)" 
    OverwriteReadOnlyFiles="$(OverwriteReadOnlyFiles)" 
    Retries="$(CopyRetryCount)" 
    RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)" 
    UseHardlinksIfPossible="$(CreateHardLinksForCopyLocalIfPossible)" 
    Condition="'$(UseCommonOutputDirectory)' != 'true'" 
    > 

我已經嘗試設置變量CopyRetryCount,CopyRetryDelayMilliseconds,......我希望,如果複製失敗,幾毫秒後完成的另一個副本會成功。但我一直無法設置這些參數。我怎樣才能改變它們?

有沒有另一種解決方案?

+0

您是否將NLog作爲您的產品的一部分構建,還是僅僅檢入源代碼管理?如果你正在構建它,是否有可能你的一些項目引用二進制位置而不是項目? –

回答

3

我已經找到了解決辦法

<MSBuild Projects="@(BuildFile)" 
    Properties="Configuration=%(Config.Configuration);Retries=10;RetryDelayMilliseconds=50" 
    Targets="Build" /> 

它工作正常,但現在它重試之前產生一個警告副本

C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(3001,9): 
warning MSB3026: Could not copy 
"D:\src\xxx\System.Data.SQLite.pdb" to "..\Debug\System.Data.SQLite.pdb". 
Beginning retry 1 in 50ms. The process cannot access the file 
'..\Debug\System.Data.SQLite.pdb' because it is being used by another process. 

在我的最後一次測試,它生成此警告的36倍!有沒有辦法抑制警告MSB0326?

0

一般來說,構建過程中運行的任何東西都不得在其輸入上獲得排它鎖 - 只有共享讀鎖。看起來你的構建過程中的東西(可能是NLog,不管這是什麼)違反了這一點 - 它對輸入"xxx\NLog.dll"進行獨佔鎖定,所以當另一個msbuild節點試圖複製相同的輸入時,它會失敗。

對於您的特定症狀,重試是一個合理的解決方法 - 儘管不保證總是成功。

0

我有同樣的問題。我需要爲我的防病毒添加適當的例外,以避免由MsBuild生成的死鎖DLL。

相關問題