构建时生成的T4模板上使用的MSBuild锁定dll

我在尝试确定为什么MSBuild阻止访问在我刚刚创建的新T4模板中使用的dll时遇到了很多麻烦。

这个问题很难解释(甚至可以问,正如标题所显示的那样)。

我创建了一个T4模板来生成ac#类,它是我们拥有的其他N个类的包装器。 这是我提出的通过同一端点公开多个WCF服务的解决方案。

模板代码本身使用包含各种扩展方法的程序集(Mobiltec.Framework.dll)来简化模板代码。 起初,我只是将一个.tt文件添加到项目中,并随它一起执行:每当.tt更改时都会更新生成的文件,如预期的那样。

由于该模板读取其他程序集并基于它们生成类,因此我想确保它在每个构建中都转换输出,以防开发人员忘记更新输出等。

经过几天的搜索之后,我终于找到了一个相当不错的解决方案,并且每个版本的“模板几乎”完美地进行了转换。 问题是,无论何时我构建项目并转换模板时,它都会锁定对上述dll的访问,从而阻止我在事后删除或更新文件。 我必须关闭Visual Studio才能释放文件。

现在,这对本地开发人员机器来说不是一个大问题,但是它无法在构建服务器上进行构建,因为它们的输出都在一个文件夹中:

  • 构建过程开始编译我们的主解决方案
  • 包含T4模板的项目被编译,并生成类
  • 另一个项目被编译并尝试更改输出文件夹中的dll,尝试10次后失败
  • 这是文本模板系统中的错误还是我可能犯了一些错误导致文件被锁定?

    更新

    我会试着更好地解释一下如何设置一切,以便你们可以更好地理解问题。

    有一个.tt模板文件,每个web应用程序都有一个(共有4个)。 该模板负责为我们的所有WCF服务合约自动生成包装类。 合约本身在另一个程序集中分开(对于四个组件中的每一个也是一个),以便它们可以与客户端共享,而不必承载所有其他依赖项。

    我不得不实施一系列方法来使用反射,每个程序集中的签名,成员和类型进行打印,以生成可编译为有效类的文本。 我在普通装配上实现了这些方法。

    然后每个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:TFS05M3DesenvolvimentoFeature-ODataM3SProjetosManutencaoMobiltec.M3.CommonMobiltec.M3.Common.DesktopbinMobiltec.M3.Common.dll" to "binMobiltec.M3.Common.dll". Exceeded retry count of 10. Failed.  Mobiltec.M3.EG
    Error   396 Unable to copy file "D:TFS05M3DesenvolvimentoFeature-ODataM3SProjetosManutencaoMobiltec.M3.CommonMobiltec.M3.Common.DesktopbinMobiltec.M3.Common.dll" to "binMobiltec.M3.Common.dll". The process cannot access the file 'binMobiltec.M3.Common.dll' because it is being used by another process.    Mobiltec.M3.EG
    Error   407 Could not copy "D:TFS05M3DesenvolvimentoFeature-ODataM3SProjetosManutencaoMobiltec.M3.EGMobiltec.M3.EG.ServicesbinDebugMobiltec.M3.EG.Services.dll" to "binMobiltec.M3.EG.Services.dll". Exceeded retry count of 10. Failed. Mobiltec.M3.EG
    Error   408 Unable to copy file "D:TFS05M3DesenvolvimentoFeature-ODataM3SProjetosManutencaoMobiltec.M3.EGMobiltec.M3.EG.ServicesbinDebugMobiltec.M3.EG.Services.dll" to "binMobiltec.M3.EG.Services.dll". The process cannot access the file 'binMobiltec.M3.EG.Services.dll' because it is being used by another process.  Mobiltec.M3.EG
    

    此外,当我尝试通过Visual Studio删除bin / obj文件夹时,出现此错误:

    如果我手动尝试删除bin文件夹中的文件,在Windows资源管理器中,出现此错误:

    Windows资源管理器删除错误

    基本上,这一切都归结为MSBuild锁定Web应用程序项目的bin文件夹中的文件(.tt中的所有明确引用的文件)。 无论何时重建项目,引用的dll都会再次被复制到项目自己的输出文件夹中,并且这会失败,因为windows无法覆盖正在使用的文件。

    唯一释放锁的是完全关闭Visual Studio并重新打开它。 我尝试手动杀死机器上的所有MSBuild进程,或关闭并重新打开解决方案,但没有任何效果。 即使像Unlocker这样的工具也无法删除文件上的锁定(它甚至没有检测到它)。

    构建服务器上的最初问题是由同一个问题引起的,但现在“解决”了,因为我重命名了其中一个dll。 两个不同的项目( Mobiltec.Framework.DesktopMobiltec.Framework.WindowsMobile )具有相同的输出dll名称( Mobiltec.Framework.dll ),第二个项目试图覆盖构建的全局输出文件夹中的第一个项目转换发生在.tt文件(锁定原始dll)失败整个过程。


    略有相关,谷歌带给我一个非常类似的问题。 调试t4模板时,抛出异常时会导致T4VSHostProcess.exe锁定模板中所有引用的DLL。 重新启动Visual Studio修复了这个问题,但是我只能使用sysinternals进程资源管理器并手动T4VSHostProcess.exe进程以避免重新启动Visual Studio。


    你使用多核心构建? 可以默认启用使用msbuild和/ nr:false。 这是可以强制msbuild锁定文件的功能之一。


    如果我正确理解你,这个问题可能已经在VS2010sp1中解决了。 另一方面,您可能会遇到找到DLL的问题。

    链接地址: http://www.djcxy.com/p/16471.html

    上一篇: MSBuild locking dll used on T4 template generated on build

    下一篇: How to tell if a byte array is gzipped