10

VS2010 ソリューションのすべての構成を並行してビルドしようとする MSBuild プロジェクト ファイルを作成しました。

<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 プロジェクトがあることです。これらのプロジェクトも同じ外部アセンブリを使用します。

そのため、2 つの出力実行可能ファイルが同時に生成され、それらの依存関係が同時にコピーされることがよくあります。これにより、次のようなエラーが発生します。

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 を設定しようとしました... コピーが失敗した場合、数ミリ秒後に行われた別のコピーが成功することを期待していました。しかし、これらのパラメーターを設定できませんでした。どうすれば変更できますか?

別の解決策はありますか?

4

3 に答える 3

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を抑制する方法はありますか?

于 2012-09-14T00:08:43.170 に答える
0

私も同じ問題を抱えていました。MsBuild によって生成された DLL のサキャンを回避するために、アンチウイルスに適切な例外を追加する必要がありました。

于 2014-08-01T19:14:47.810 に答える