10

MSBuild が、作成したばかりの新しい T4 テンプレート内で使用される dll へのアクセスをブロックしている理由を特定しようとして、多くの問題を抱えています。

この問題は、説明するのがちょっと難しいです (そして、タイトルから明らかなように、尋ねても構いません)。

T4 テンプレートを作成して、他の N 個のクラスのラッパーである ac# クラスを生成しました。これは、同じエンドポイントで複数の WCF サービスを公開するために思いついたソリューションです。

テンプレート コード自体は、テンプレート コードを簡略化するためのさまざまな拡張メソッドを含むアセンブリ (Mobiltec.Framework.dll) を使用します。最初は、プロジェクトに .tt ファイルを追加して、それを使用しました。予想どおり、.tt が変更されるたびに、生成されたファイルが更新されました。

このテンプレートは他のアセンブリを読み取り、それらに基づいてクラスを生成するため、開発者が出力の更新などを忘れないように、すべてのビルドで出力が変換されるようにしたいと考えました。

数日間の検索の後、最終的にかなりまともな解決策にたどり着き、テンプレートは各ビルドで「ほぼ」完全に変換されました。問題は、プロジェクトをビルドしてテンプレートが変換されるたびに、前述の dll へのアクセスがロックされ、後でファイルを削除または更新できなくなることです。ファイルを解放するには、Visual Studio を閉じる必要があります。

現在、これはローカルの開発者マシンでは大きな問題ではありませんが、ビルド サーバーでのビルドは失敗します。これは、出力がすべて 1 つのフォルダーにあるためです。

  1. ビルド プロセスがマスター ソリューションのコンパイルを開始します
  2. T4 テンプレートを含むプロジェクトがコンパイルされ、クラスが生成されます
  3. 別のプロジェクトがコンパイルされ、出力フォルダー内の dll を変更しようとすると、10 回試行した後にビルドに失敗します

これはテキスト テンプレート システムのバグですか、それとも何かミスを犯してファイルがロックされている可能性がありますか?

アップデート

ここですべてがどのようにセットアップされているかをもう少し詳しく説明して、問題をよりよく理解できるようにします。

Web アプリケーションごとに 1 つずつ、.tt テンプレート ファイルがあります (全部で 4 つあります)。このテンプレートは、すべての WCF サービス コントラクトのラッパー クラスを自動的に生成する役割を果たします。コントラクト自体は、他のすべての依存関係を持たずにクライアントと共有できるように、別のアセンブリ (4 つのコンポーネントごとに 1 つ) に分離されています。

有効なクラスとしてコンパイルできるテキストを生成するために、リフレクション、署名、メンバー、および各アセンブリの型を使用して、印刷するための一連のメソッドを実装する必要がありました。これらのメソッドを共通アセンブリに実装しました。

次に、各 tt ファイルは、この共通アセンブリをサービス コントラクト アセンブリと共に参照して、このラッパー クラスを生成します。テンプレートには、たとえば次のような行がたくさんあります。

<#@ assembly name="Mobiltec.M3.EG.Services.dll" #>
<#@ assembly name="Mobiltec.M3.Common.dll" #>

ビルドごとにこれらのテンプレートを変換する必要があるため、プロジェクト ファイルを変更してこれを有効にし、このアドバイスに従って Visual Studio SDK と Visualization and Modeling SDK をインストールしました。

現在、アセンブリまたはその依存関係のコードに変更を加えるたびに、次のようなメッセージが表示されます。

Error   1516    Compiling transformation: Metadata file 'Mobiltec.M3.EG.Services.dll' could not be found. Line=0, Column=0  Mobiltec.M3.EG
Error   1517    Compiling transformation: Metadata file 'Mobiltec.M3.Common.dll' could not be found. Line=0, Column=0   Mobiltec.M3.EG

または:

Error   395 Could not copy "D:\TFS05\M3\Desenvolvimento\Feature-ODataM3S\ProjetosManutencao\Mobiltec.M3.Common\Mobiltec.M3.Common.Desktop\bin\Mobiltec.M3.Common.dll" to "bin\Mobiltec.M3.Common.dll". Exceeded retry count of 10. Failed.  Mobiltec.M3.EG
Error   396 Unable to copy file "D:\TFS05\M3\Desenvolvimento\Feature-ODataM3S\ProjetosManutencao\Mobiltec.M3.Common\Mobiltec.M3.Common.Desktop\bin\Mobiltec.M3.Common.dll" to "bin\Mobiltec.M3.Common.dll". The process cannot access the file 'bin\Mobiltec.M3.Common.dll' because it is being used by another process.    Mobiltec.M3.EG
Error   407 Could not copy "D:\TFS05\M3\Desenvolvimento\Feature-ODataM3S\ProjetosManutencao\Mobiltec.M3.EG\Mobiltec.M3.EG.Services\bin\Debug\Mobiltec.M3.EG.Services.dll" to "bin\Mobiltec.M3.EG.Services.dll". Exceeded retry count of 10. Failed. Mobiltec.M3.EG
Error   408 Unable to copy file "D:\TFS05\M3\Desenvolvimento\Feature-ODataM3S\ProjetosManutencao\Mobiltec.M3.EG\Mobiltec.M3.EG.Services\bin\Debug\Mobiltec.M3.EG.Services.dll" to "bin\Mobiltec.M3.EG.Services.dll". The process cannot access the file 'bin\Mobiltec.M3.EG.Services.dll' because it is being used by another process.  Mobiltec.M3.EG

また、Visual Studio で bin/obj フォルダーを削除しようとすると、次のエラーが発生します。

Visual Studio の削除エラー

bin フォルダーのファイルを手動で削除しようとすると、Windows エクスプローラーで次のエラーが表示されます。

Windows エクスプローラーの削除エラー

基本的に、Web アプリケーション プロジェクトの bin フォルダー内のファイル (.tt で明示的に参照されているファイルのすべて) をロックする MSBuild にすべてが要約されます。プロジェクトが再構築されるたびに、参照された dll がプロジェクト自体の出力フォルダーに再度コピーされますが、Windows は「使用中」のファイルを上書きできないため、これは失敗します。

ロックを解放する唯一の方法は、Visual Studio を完全に閉じてから再度開くことです。マシン上のすべての MSBuild プロセスを手動で強制終了するか、ソリューションを閉じて再度開いてみましたが、何も機能しません。Unlocker のようなツールでさえ、ファイルのロックを解除することはできません (ロックを検出することさえできません)。

ビルド サーバーの最初の問題はまったく同じ問題が原因でしたが、DLL の 1 つを名前変更したため、現在は「解決」されています。2 つの異なるプロジェクト (Mobiltec.Framework.DesktopおよびMobiltec.Framework.WindowsMobile) は同じ出力 dll 名 ( Mobiltec.Framework.dll) を持ち、2 番目のプロジェクトは、.tt ファイルの変換が行われた後 (元の dll をロック)、ビルドのグローバル出力フォルダーで最初のプロジェクトを上書きしようとしていました。プロセス全体の失敗。

4

3 に答える 3

7

少し関連して、グーグルは非常によく似た問題のために私をここに連れてきました。例外がスローされたときに t4 テンプレートをデバッグすると、テンプレートでT4VSHostProcess.exe参照されているすべての DLL がロックされます。Visual Studio を再起動すると問題は解決しましたが、sysinternals プロセス エクスプローラーを使用して手動でプロセスを強制終了し、Visual Studio のT4VSHostProcess.exe再起動を回避することができました。

于 2016-02-22T15:55:27.787 に答える
0

私があなたを正しく理解していれば、この問題は VS2010sp1 で修正されている可能性があります。一方で、DLL の検索で問題が発生する場合があります。

于 2015-12-02T13:31:22.577 に答える
0

マルチコアビルドを使用していますか? デフォルトで有効になっている可能性があります /nr:false で msbuild を使用します。これは、msbuild に強制的にファイルをロックさせることができる機能の 1 つです。

于 2013-11-12T18:52:25.990 に答える