67

TFS 2012ビルドを使用していますが、エラーが発生します

パスへのアクセスが拒否されました

構築中のソリューションには約15のプロジェクトが含まれており、そのうちのいくつかはCastle.Components.Validator.2.5.0アセンブリを使用しています。

TFSビルドアクセス拒否エラーについて説明している他の投稿を見たことがありますが、それらは通常、ビルドを同時に実行することを指します。この場合、一度に実行されるビルドは1つだけです。また、サーバーを再起動したり、ビルドがしばらく実行されなかったりすると、エラーが発生します。

ビルドが実行されて失敗すると、次のビルドが成功し、その後、ビルドがしばらく実行されないか、サーバーが再起動されるまで、それぞれが再び成功します。これを回避することはできますが、手動での頭痛の種です。

エラーは次のとおりです。

C:\ WINDOWS \ Microsoft.NET \ Framework64 \ v4.0.30319 \ Microsoft.Common.targets(3513):ファイル "D:\ Builds \ 12 \ Foo \ Check-In Build \ Sources \ packages\Castle.Componentsをコピーできません.Validator.2.5.0 \ lib \ NET40 \ Castle.Components.Validator.dll "から"D:\ Builds \ 12 \ Foo \ Check-In Build \ Binaries\Castle.Components.Validator.dll"へ。

パス'D:\ Builds \ 12 \ Foo \ Check-In Build \ Binaries\Castle.Components.Validator.dll'へのアクセスが拒否されました。

ログファイルを見ると、ビルドがファイルを2回コピーしようとしていることがわかります。最初のものはファイルをロックしているため、2番目のものは失敗し、ビルドは失敗します。何が起こっているかを示すログファイルのスニペットを次に示します。

2> _CopyFilesMarkedCopyLocal:「D:\ Builds \ 12 \ Foo \ Check-InBuild \ Sources \ packages \ Castle.Components.Validator.2.5.0 \ lib \ NET40\Castle.Components.Validator.dll」から「 D:\ Builds \ 12 \ Foo \ Check-In Build \ Binaries\Castle.Components.Validator.dll"。

5> _CopyFilesMarkedCopyLocal:「D:\ Builds \ 12 \ Foo \ Check-InBuild \ Sources \ packages \ Castle.Components.Validator.2.5.0 \ lib \ NET40\Castle.Components.Validator.dll」から「 D:\ Builds \ 12 \ Foo \ Check-In Build \ Binaries\Castle.Components.Validator.dll"。

2> _CopyFilesMarkedCopyLocal:「D:\ Builds \ 12 \ Foo \ Check-InBuild \ Sources \ packages \ MvcContrib.Mvc3.FluentHtml-ci.3.0.96.0 \ lib \ MvcContrib.FluentHtml.dll」から「D: \ Builds \ 12 \ Foo \ Check-In Build \ Binaries\MvcContrib.FluentHtml.dll"。「D:\ Builds \ 12 \ Foo \ Check-InBuild \ Sources \ packages \ RhinoMocks.3.6 \ lib \ Rhino.Mocks.dll」から「D:\ Builds \ 12 \ Foo \Check-InBuild\」にファイルをコピーしていますBinaries\Rhino.Mocks.dll」。

これを修正する方法についての助けをいただければ幸いです。

4

16 に答える 16

51

他の人が述べたように、これは、共通の宛先ディレクトリでマルチスレッド ビルドを実行し、ファイル コピー タスクが別のプロジェクトで実行されているコピー タスクと同時に競合する場合に発生します。

通常、これは「別のプロセスによって使用されるファイル」例外 (ファイル コピー タスクによって処理および再試行される) になりますが、ファイル操作によって「アクセスが拒否されました」例外が発生する場合があります。(理由はまだわかりません)

「重複を解決する」べきだと提案する人もいますが、すべてのプロジェクトが log4net のようなライブラリを直接参照する必要がある場合には、それが実行可能であるとは思えません。

明らかに、この問題を回避する 1 つの方法は、msbuild を/p:BuildInParallel=falseor/m:1または/maxcpucount:1(または引数全体を省略して) 明示的に実行し、シングル スレッド モードを強制することです。

ただし、TFS 2013では、既定のビルド テンプレートは常に自動的に/m(すべてのコアを使用して) msbuild に渡されます。これにより、手動で渡すことができるシングル スレッド設定がサイレント モードで上書きされます。 (私自身の実験と診断ログの調査によって決定されました)

私が試みた別の回避策は、手動で/p:AllowedReferenceRelatedFileExtensions=nonemsbuild に渡すことでした。これにより、すべての pdb および xml ファイルが参照ライブラリからコピーされなくなります。(しばらくの間、この問題が発生するのは xml ファイルだけでした。)しかし、その後も log4net.dll で問題が発生し続けました。

私が使用した最終的な回避策は、のソース コードを逆コンパイルすることで発見したものでしたMicrosoft.Build.Tasks.Copy

if (hrForException == -2147024891)
{
    if (!Copy.alwaysRetryCopy)
        throw;
    else
        this.LogDiagnostic("Retrying on ERROR_ACCESS_DENIED because MSBUILDALWAYSRETRY = 1", new object[0]);
}

エラー -2147024891 (0x80070005 アクセスが拒否されました) が発生した場合、コピー タスクは特別な変数をチェックして、再試行する必要があるかどうかを確認します。その値は、環境変数を介して設定されます。

Copy.alwaysRetryCopy = Environment.GetEnvironmentVariable("MSBUILDALWAYSRETRY") != null;

環境変数 MSBUILDALWAYSRETRY = 1 を設定 (およびビルド サーバーを再起動) すると、問題は解消されました。また、ビルドログの警告として定期的に「ERROR_ACCESS_DENIED で再試行しています...」が表示されるようになり、設定が有効になっていることが証明されました (ビルドが偶然に成功しただけではありません)。

(この環境変数は十分に文書化されていないことに注意してください。適切に使用してください。)

更新:どうやら、TFS 2015 は(レガシー/XAML ビルド定義であっても) /m:1with をオーバーライドしなくなりました。これにより、再び有効な修正が行われるはずです。/m/m:1

于 2014-04-14T20:20:54.687 に答える
41

同じファイルをコピーしている 2 つのプロジェクトがあるようです。タイミングによっては、同時に発生して失敗することもあります。ソース プロジェクトを見つけるには、ノード ID をさかのぼる必要があります。詳細と追跡可能なコードについては、http://blogs.msdn.com/b/buckh/archive/2012/01/21/a-tool-to-find-duplicate-copies-in-a-build.aspxを参照してください。あなたのためにそれをダウン。

于 2012-10-16T00:30:26.510 に答える
13

Buck Hodges と Nimblejoe が正しく述べているように、これは主に TFS がデフォルトで複数の MSBuild プロセスを実行してプロジェクトをビルドするためです。

Process -> 3. Advanced -> MSBuild Argumentsのビルド定義で、MSBuild 引数/p:BuildInParallel=falseを追加してオーバーライドできます。

于 2013-10-02T12:56:35.133 に答える
11

これは、ビルド エージェントのフォルダーが開いている場合にも発生する可能性があります。

于 2014-03-24T18:11:56.240 に答える
8

私も同じ問題を抱えていました。パスへのアクセスが拒否されたため、コピーできないというエラー メッセージが表示されました。私の場合、すべての dll ファイルと xml ファイルなどは D:\TFS\Example\Bin\Debug フォルダーに配置されます。

Bin フォルダーを右クリックして [プロパティ] をクリックすると、[属性] の下で [読み取り専用] チェック ボックスがオンになっていることがわかりました。

[読み取り専用] チェック ボックスのチェックを外し、[適用] をクリックして、表示される新しいポップアップで [OK] をクリックしました。

Visual Studio に戻り、エラー メッセージが表示されるソリューションをビルドしました。

出来上がり..今回はエラーなしで正常にビルドされました。

これが完璧かどうかはわかりませんが、問題を解決するためにこれを行いました。

于 2014-12-30T18:10:02.827 に答える
0

考えられる原因の 1 つは、クラス ライブラリのbinまたはobjフォルダーが TFS にチェックインされている場合です。その場合は、TFS からプロジェクトの bin または obj フォルダーを削除すると、この問題が解決されます。

于 2013-01-15T08:28:10.730 に答える
0

私にとっては、ビルド エージェントが管理者の PowerShell で開始されなかったことが原因でした。

于 2018-07-19T08:33:33.297 に答える
-1

多くの人がすでに述べているように、これはプロジェクトを並行して構築するときに発生します。プロジェクト A と B の両方がサード パーティのライブラリ C (ローカルにコピー) を参照している場合、それらが同時にビルドされると、この問題が発生します。

本当の問題は、TFS Build 2012 以下が、ソリューションのビルド時にソリューションの出力全体が 1 つのフォルダーにコピーされるように構成されていることです。それが、並列ビルドの苦労の原点です。

TFS 2013 以降、ビルド定義の「出力場所」を「PerProject」に設定することで、これを簡単に解決できます。これにより、ビルド サービスはローカルの msbuild 実行のように動作し、出力場所に関する設定が対応するプロジェクト ファイルから読み込まれます。したがって、出力は各プロジェクトの bin フォルダーに書き込まれます。

TFS 2012 および以下の記事 (+リンクされた記事) では、TFS 2013 と同じ結果を得るのに役立ちます。

http://blog.stangroome.com/2012/05/10/override-the-tfs-team-build-outdir-property-net-4-5/

于 2014-10-17T05:03:04.780 に答える
-2

I resolved a very similar issue by closing all open instances of Visual Studio, re-opening the solution and building it again.

于 2014-11-06T03:14:32.473 に答える