jul*_*gon 10 .net msbuild t4 build tfsbuild
我在尝试确定为什么MSBuild阻止访问我刚刚创建的新T4模板中使用的dll时遇到了很多麻烦.
这个问题很难解释(甚至可以问,标题很明显).
我创建了一个T4模板来生成ac#类,它是我们拥有的其他N个类的包装器.这是我提出的在同一端点上公开多个WCF服务的解决方案.
模板代码本身使用包含各种扩展方法的程序集(Mobiltec.Framework.dll)来简化模板代码.起初,我刚刚将一个.tt文件添加到项目中并继续使用它:每当.tt改变时,它都会按预期更新生成的文件.
由于这个模板读取其他程序集并基于它们生成一个类,我想确保它在每个构建中转换输出,以防止开发人员忘记更新输出和类似的东西.
经过几天的搜索,我终于找到了一个相当不错的解决方案,模板正在每个版本"几乎"完美地转换.问题在于,每当我构建项目并转换模板时,它都会锁定对前面提到的dll的访问,从而阻止我之后删除或更新文件.我必须关闭Visual Studio才能释放该文件.
现在,这对本地开发人员机器来说不是一个大问题,但它在构建服务器上的构建失败,因为那里的输出都在一个文件夹中:
这是文本模板系统中的错误还是我可能会犯一些导致文件被锁定的错误?
更新
我会尝试更好地解释一下如何设置所有内容,以便你们可以更好地理解这个问题.
有一个.tt模板文件,每个Web应用程序一个(总共有4个).此模板负责自动为所有WCF服务合同生成包装类.合同本身在另一个程序集中分开(对于四个组件中的每一个也是一个),以便它们可以与客户端共享,而不会携带所有其他依赖项.
我必须实现一组方法来使用反射,每个程序集中的签名,成员和类型进行打印,以生成可以编译为有效类的文本.我在一个通用程序集上实现了这些方法.
然后,每个tt文件引用此公共程序集以及服务契约程序集,以生成此包装类.例如,模板有一堆这样的行:
<#@ assembly name="Mobiltec.M3.EG.Services.dll" #>
<#@ assembly name="Mobiltec.M3.Common.dll" #>
Run Code Online (Sandbox Code Playgroud)
由于我们需要在每个构建中转换这些模板,因此我已经更改了项目文件以启用它并按照此建议安装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
Run Code Online (Sandbox Code Playgroud)
要么:
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
Run Code Online (Sandbox Code Playgroud)
此外,当我尝试通过Visual Studio删除bin/obj文件夹时,我收到此错误:

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

基本上,这一切都归结为MSBuild在Web应用程序项目的bin文件夹中锁定文件(.tt中所有显式引用的文件).每当重建项目时,引用的dll都会再次复制到项目自己的输出文件夹中,这会失败,因为Windows无法覆盖"正在使用"的文件.
释放锁的唯一方法是完全关闭Visual Studio并重新打开它.我试图手动杀死机器上的所有MSBuild进程,或关闭并重新打开解决方案,但没有任何作用.即使像Unlocker这样的工具也无法删除文件上的锁(它甚至都没有检测到它).
构建服务器上的初始问题是由同样的问题引起的,但现在已经"解决",因为我重命名了其中一个dll.两个不同的项目(Mobiltec.Framework.Desktop和Mobiltec.Framework.WindowsMobile)具有相同的输出dll名称(Mobiltec.Framework.dll),第二个尝试覆盖构建上的全局输出文件夹中的第一个,在.tt文件发生转换后(锁定原始dll)整个过程失败了.
有点相关,谷歌把我带到这里是一个非常相似的问题。调试t4模板时,引发异常将导致T4VSHostProcess.exe锁定模板中所有引用的DLL。重新启动Visual Studio可以解决此问题,但我只能使用sysinternals进程浏览器并手动终止该T4VSHostProcess.exe进程,以避免重新启动Visual Studio。
| 归档时间: |
|
| 查看次数: |
1705 次 |
| 最近记录: |