T4 referenced assembly blocks build

2019-04-29 09:52发布

In Visual Studio 2010 I have the following project layout:

  • Solution
    • project A
      • class C
      • class D
    • project B
      • T4 template

The T4 template contains a assembly reference like this:

<#@ assembly name="$(SolutionDir)\A\bin\Debug\A.dll" #>

The template instantiates an instance of class C. When I run the T4 template the processor loads the project A's dll and correctly creates the output. The error arises when I want to change something in project A, say modify either class C or D.

Unable to copy file "obj\Debug\A.dll" to "bin\Debug\A.dll". The process cannot access the file 'bin\Debug\A.dll' because it is being used by another process.

The only way I found to get rid of this error is to restart Visual Studio. Is there any other way to force the unloading of the A.dll assembly from VS?

2条回答
相关推荐>>
2楼-- · 2019-04-29 10:13

m0sa This issue has been fixed in Visual Studio 2010 SP1.

If you're not able to use that, there is a VolatileAssembly directive add-on in the T4 Toolbox project on CodeBox (http://t4toolbox.codeplex.com/)

查看更多
劳资没心,怎么记你
3楼-- · 2019-04-29 10:17

Im using VS2010 SP1 and was still getting blocked during build after first build when running a custom T4 template during the POST-BUILD events which accessed instances of classes of the same project.

How I got it to work was to use Reflection to access classes from the Project dll.

I still got the blocking issue when loading the dll directly from the file.

NOTE: The trick was to load the .dll into memory as a byte array and then load the assembly from the raw byte array. DONT load from the file using the Assembly.LoadFrom

This code is from my T4 template file and is accessing a static class "Information" and calling a static Method "Version" to return a string value.

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);
查看更多
登录 后发表回答