如何强制.NET使用GAC中的程序集的本地副本


70

我有一个.NET程序集(出于无法控制的原因)必须位于GAC中。但是,另一个程序使用相同的程序集,该程序具有相同程序集的较早版本的自己的副本。它必须使用自己的副本,而不要使用GAC中的任何副本。在这种情况下,适当的版本控制可能比它值得的麻烦得多,出于我不愿讨论的原因。我的问题是:是否仍然要告诉.NET:只需在此目录中的此目录中使用THIS DLL,请忽略在GAC或其他任何地方找到的内容

Answers:


46

确保GAC程序集和本地程序集具有不同的版本号(至少可以通过在AssemblyInfo中通配您的AssemblyVersion来让您的内部版本号自动递增,这不是一个坏主意:[assembly:AssemblyVersion(“ 1.0.0。*” )])。然后,使用应用程序的配置重定向程序集绑定:

就您而言,您将不需要assemblyBinding配置的“ appliesTo”属性。您只需要以下内容:

<runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
        <dependentAssembly>
            <assemblyIdentity name="YourAssembly" publicKeyToken="AAAAAAAAAAAA" culture="neutral"/>
            <bindingRedirect oldVersion="0.0.0.0-5.2.1.0" newVersion="5.0.8.1"/>
        </dependentAssembly>
    </assemblyBinding>
</runtime>

3
您是否可以通过重新编译应用程序以使用新版本的dll来避免使用此绑定重定向,还是始终需要进行一些配置更改?

将版本号的修订部分设置为*不会使其自动递增。在MSDN文档AssemblyVersionAttribute表明,它应该是随机的,但在实践中的Visual Studio使用的秒数,因为午夜除以2
M.达德利

因此,您要说的是即使没有任何更改,每个程序集也会在每个构建版本上重新版本化,这样我们才能打破对GAC的依赖性?程序集绑定重定向有什么用?我唯一想到的是,它可以用在prod上,因此,如果您的项目在GAC中引用5.0.8.3453而不是5.0.8.1,只是因为您在不进行更改的开发人员上对其进行了版本化,重定向到5.0.8.1。是对的吗?笨拙,但我看不到其他解决方法。
谢尔盖·阿科波夫

1
我很迷惑。这篇文章说了它的可能 aip.im/2013/04/…–
Niloofar

31

如果它们具有相同的版本号,答案是不可以。如果您尝试加载与GAC的程序集具有相同的完整程序集名称(名称,版本,键)的程序集,则CLR每次都会选择GAC的程序集。


1
我不知道谁对此表示反对,但是我经历了@JaredPar所说的同样的事情,这让我发疯。它是从GAC加载的。我有两个具有相同全名的程序集,我想加载经过稍微修改的程序集。皮塔饼
Csaba Toth

你尝试过这个吗?aip.im/2013/04/...
Niloofar

您可以使用类似DNSPY的方式修改dll,以便它具有不同的签名和版本。有点骇人听闻,但可以使用。
轧辊

@rolls如何使用dnspy更改程序集版本?我尝试更改版本,但是在编译后,它仅使用初始版本。顺便说一句:我通过右键单击属性,然后选择详细信息选项卡来检查版本。
Ozkan

您是否使用了保存模块?还要检查那里的所有选项。绝对有可能做到,就像我在成功之前所做的那样。
轧辊

10

您可以设置DEVPATH以强制加载程序集,请参见链接文本

这不能回答您的问题,因为它仅用于开发用途,甚至不建议使用,因为它不反映生产用途。但是我想我还是会分享,因为很高兴知道。


2

您是否尝试过Assembly.LoadFromFile()?这是手动操作,但是应在需要之前将程序集加载到内存中。然后,.NET将使用内存中的那个而不是寻找它。

另一种方法是,如果本地程序集是未签名的,则可以通过这种方式进行区分。


4
好主意,但是不行,它不起作用-LoadFile()加载正确的程序集,但是当使用引用的程序集时,仍然会从GAC中加载它。:(
EMP

2
有没有管理的方式来组装加载GAC'd的本地副本
JaredPar

使用dnspy修改dll的签名和版本,然后可以强制加载自定义的被入侵的dll。
轧辊

2

我有一个类似的问题。我通过使用ildasm和更改了目标dll的publicKeyToken,ilasm以生成一个新的dll。然后,我在项目参考中对其进行了更新,以指向新的dll。我采取的步骤在这里

这对我有用。


1

绑定重定向不起作用的原因之一是因为Oracle.ManagedDataAccess提供程序对dll的搜索顺序与非托管提供程序不同。非托管提供程序从应用程序目录中启动,然后在注册表中查找dllpath,然后在machine.config中查找dll路径,然后在web.config中查找dll路径。根据Oracle文档,托管提供者的搜索顺序如下:

托管驱动程序将使用以下搜索顺序引用这些程序集:

  1. 全局程序集缓存
  2. Web应用程序的bin目录或Windows应用程序的EXE目录
  3. x86或x64子目录,取决于应用程序在32位还是64位.NET Framework中运行。如果应用程序是使用AnyCPU构建的,则只要程序集可用,ODP.NET就会使用正确的DLL位。如果您的应用程序是AnyCPU,Oracle建议使用此方法查找相关程序集。

https://docs.oracle.com/zh_CN/database/oracle/oracle-database/12.2/odpnt/installODPmd.html#GUID-0E834EC7-21DF-4913-B712-2B0A07FD58FD

因此,解决此问题的方法是注销GAC程序集,或者如果无法卸载,则将简单的Oracle.ManagedDataAccess版本与GAC中的版本放到bin和web.config中。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.