有没有办法强制我的 asp.net 应用程序从本地 bin 目录加载程序集,因为 GAC 中有另一个同名的旧版本程序集?
我不能删除 GAC 版本,因为其他应用程序正在使用它,而将新版本添加到 GAC 时遇到一些困难。
DEVOVERRIDE
环境变量设置为包含你的程序集的路径,这将在GAC之前进行探测。 - AbelDEVPATH
环境变量 并在 machine.config
中启用 开发模式 来绑定到任何程序集,完全覆盖 GAC。我认为这是实现您想要的最简单的方法,但不应在生产环境中使用。bindingRedirect
方法。machine.config
:<configuration>
<runtime>
<developmentMode developerInstallation="true"/>
</runtime>
</configuration>
DEVPATH
环境变量设置为非签名程序集的位置。这将强制Fusion的DEVOVERRIDE模式启动,并在探测GAC之前搜索DEVPATH
(及其子目录)。
MSDN上关于DEVPATH
和DEVOVERRIDE
的FAQ将回答大多数有关使用此功能的问题。DEVPATH
。LOG: Found assembly in DEVOVERRIDE path D:\testassemblies\Test.DLL
注意:如果您希望Visual Studio从DEVPATH
位置加载程序集,您应该将注册表键设置为此位置,即设置(检查.NET版本键以匹配您的.NET版本):
[HKEY_CURRENT_USER\
SOFTWARE\
Microsoft\
.NETFramework\
v2.0.50727\AssemblyFoldersEx\
DEVPATH]@="C:\SharedAssemblies"
DEVPATH
的操作指南。我认为它与我上面提到的信息相符,只是它说(合理地)你必须确保DEVPATH可读/写。它还建议在应用程序级别上使用developerInstallation="true"
,这是个好消息(我还没有测试过)。 - AbelDEVPATH
的匹配只是按名称进行的,所以如果有相同的程序集,它应该能够找到。但是很可能 vstest.console.exe
使用了自己的程序集加载器,从而导致了不同的行为。您可以通过在构建和生产中使用不同的版本号来避免这种情况,以便 GAC 版本永远不会被找到,但是当然,这不是您想要的解决方案。我不使用 VSTEST 环境,我使用另一个环境,在那里我也发现了与默认 .NET 行为不同的程序集加载行为。 - Abel <runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="DllName"
publicKeyToken="0123456789abc"
culture="neutral" />
<!-- Assembly versions can be redirected in app,
publisher policy, or machine configuration files. -->
<bindingRedirect oldVersion="2.0.0.0-2.5.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
如果我在GAC中有一个程序集,其版本可以从2.0.0.0到2.5.0.0,所有的调用都将被重定向到新版本(3.0.0.0)
在程序集部分,我添加了该程序集:
<add assembly="DllName, Version=3.0.0.0, Culture=neutral, PublicKeyToken=0123456789abc" />
就这样了。
要将一个版本重定向到另一个版本,请使用<bindingRedirect>元素。oldVersion属性可以指定单个版本或版本范围。例如,<bindingRedirect oldVersion="1.1.0.0-1.2.0.0" newVersion="2.0.0.0"/>表示运行时应该使用版本2.0.0.0而不是1.1.0.0和1.2.0.0之间的程序集版本。
s
根据这篇答案中关于程序集加载顺序的摘录笔记: 如何防止.NET应用从GAC加载/引用程序集?
我猜测,在要求库作为程序集加载之前,调用本地DLL文件上的LoadLibrary,可能会将其在搜索顺序中向上移动。
遗憾的是,我不确定如何让您的LoadLibrary调用在框架开始加载引用的程序集之前运行。
因此,这只是一个想法,而不是完整的答案。
你可以使用 codebase 路径来代替使用 bindingRedirect。我有一个使用 MySQL.Data.dll 的工作示例。
<dependentAssembly>
<assemblyIdentity name="MySql.Data" publicKeyToken="c5687fc88969c44d" culture="neutral" />
<codebase version="5.2.5.0" href="/bin/MySQL.Data.dll" />
</dependentAssembly>
这可以在 Web 应用程序的 Web.config 中完成。