T4参照アセンブリブロックビルド
-
10-10-2019 - |
質問
Visual Studio 2010では、次のプロジェクトレイアウトがあります。
- 解決
- プロジェクトa
- クラスc
- クラスd
- プロジェクトb
- T4テンプレート
- プロジェクトa
T4テンプレートには、次のようなアセンブリ参照が含まれています。
<#@ assembly name="$(SolutionDir)\A\bin\Debug\A.dll" #>
テンプレートはクラスCのインスタンスをインスタンスします。T4テンプレートを実行すると、プロセッサがプロジェクトAのDLLをロードし、出力を正しく作成します。プロジェクトAで何かを変更したいときにエラーが発生します。たとえば、クラスCまたはDのいずれかを変更します。
ファイル「obj debug a.dll」を「bin debug a.dll」にコピーできません。このプロセスは、別のプロセスで使用されているため、ファイル「bin debug a.dll」にアクセスできません。
このエラーを取り除くために見つけた唯一の方法は、Visual Studioを再開することです。 VSからのA.DLLアセンブリのアンロードを強制する他の方法はありますか?
解決
私はVS2010 SP1を使用しており、同じプロジェクトのクラスのインスタンスにアクセスしたビルド後のイベント中にカスタムT4テンプレートを実行するときに、最初のビルド後にビルド中にブロックされていました。
私がそれを機能させた方法は、リフレクションを使用してプロジェクトDLLからクラスにアクセスすることでした。
ファイルからDLLを直接ロードする際に、まだブロッキングの問題が発生しました。
ノート: :トリックは、.dllをバイト配列としてメモリにロードし、生のバイト配列からアセンブリをロードすることでした。 assembly.loadfromを使用してファイルからロードしないでください
このコードは私のT4テンプレートファイルからのもので、静的クラスの「情報」にアクセスし、静的メソッド「バージョン」を呼び出して文字列値を返しています。
string assemblyPath = Path.Combine(projectPath, @"bin\SampleProject.dll");
byte[] data;
using (var fs = File.OpenRead(assemblyPath))
{
data = new byte[fs.Length];
fs.Read(data, 0, Convert.ToInt32(fs.Length));
}
if (data == null || data.Length == 0)
{
throw new ApplicationException("Failed to load " + assemblyPath);
}
var asm = Assembly.Load(data);
appVersion = (string) asm.GetType("SampleProject.Information").GetField("Version").GetValue(null);
他のヒント
M0SAこの問題は、Visual Studio 2010 SP1で修正されています。
それを使用できない場合は、CodeBoxのT4 ToolboxプロジェクトにVolatileASSEMBLYディレクティブアドオンがあります(http://t4toolbox.codeplex.com/)