Visual Studio的Microsoft.VisualStudio.Web.Host.exe在构建期间对%DEVPATH%\*.dll
保持读锁定。
我正在使用Redgate .NET Reflector在我的开发盒上运行一个网站。 .NET Reflector要求将环境变量DEVPATH
设置为%ALLUSERSPROFILE%\Red Gate\.NET Reflector\DevPath\
,以便它可以创建引用程序集的PDB,而无需将它们放在bin目录中。当它创建PDB时,它会将反汇编的.dll复制到DEVPATH
,并且您运行的任何程序都会引用这些副本而不是bin目录中的文件。
那很好,除了在我的情况下,这些反汇编的dll使用反射并查看它们所在的同一目录,假设它是原始bin目录,对于其他程序集 - 我和#39写完了。
这是我的目录结构:
/inetpub/wwwroot/bin/Arena.Framework.dll <-- dll to be decompiled
/inetpub/wwwroot/bin/Arena.Custom.Common.dll <-- my custom dll
/ProgramData/Red Gate/.NET Reflector/DevPath/Arena.Framework.dll <-- copied by .NET Reflector in order to be decompiled; uses reflection to find types in ./Arena.Custom.*.dll
首先,我尝试使用从.../bin/Arena.Custom.Common.dll
到%DEVPATH%/Arena.Custom.Common.dll
的符号链接,但这完全阻止了构建。
接下来我尝试让.NET Reflector为我的自定义dll生成PDB,而不是让MSBuild这样做,以便它自动将我的dll复制到目录中。不幸的是,.NET Reflector太聪明了,因为它确实是一个项目dll,并且不会做它。
我的下一个解决方案是在我的Arena.Custom.Common.csproj
文件中添加几行:
<Target Name="AfterBuild">
<Copy SourceFiles="@(MainAssembly)" DestinationFolder="$(DEVPATH)" SkipUnchangedFiles="true" Retries="0" />
<Message Text="Copied @(MainAssembly) to $(DEVPATH)" />
</Target>
这会将输出dll复制到DevPath
。这是我第一次建造时,我认为我已经完成了。但是,下次我构建时,它失败了,因为 Microsoft.VisualStudio.Web.Host.exe (以下简称Host.exe)已加载它。我假设它可以覆盖bin
目录中的文件的原因是它实际上并没有加载它们,而是将它们复制到临时目录并在每次构建时加载它们。但是,DEVPATH
中的文件始终由VS的Host.exe加载。由于.NET Reflector只能反编译你自己不构建的dll,它永远不需要复制那些,因此永远不会遇到我所拥有的问题。
MSDN表示您可以在csproj属性窗口中禁用托管过程,我这样做了,但它仍然在运行。我不确定,但我猜测网站项目是否导致它运行,而网站的属性窗口没有&#34; Debug&#34;标签
是否有更好的解决方法,而不仅仅是在构建后将它们复制到DEVPATH
?
也许我应该直接将输出目录从.../bin
更改为DEVPATH
?这会将所有依赖dll复制到DEVPATH
,这不是理想的。
也许有一种方法可以告诉Host.exe在构建期间卸载文件,或者在构建完成之前终止进程?我尝试手动执行此操作,MSBuild.exe开始崩溃。
我考虑过保存%DEVPATH%
的临时副本,清除值,以某种方式重新启动Host.exe,构建,复制,将%DEVPATH%
设置回原始值,然后重新启动主机。 exe,但我觉得,如果Host.exe启用,VS依赖它在构建期间连续运行。
另一种解决方法是关闭VS,删除DEVPATH
中的文件,重新打开VS,并在每次需要更改DLL时重建。这是一个糟糕的选择,但它确实有效。
希望有更好的解决方案......
根据评论,我的问题是:
如何在构建时/之后将我编译的DLL的新版本复制到DEVPATH
?