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

发布于 2024-07-09 10:22:04 字数 237 浏览 8 评论 0原文

我有一个 .NET 程序集(由于我无法控制的原因)必须位于 GAC 中。 但是,同一程序集被另一个程序使用,该程序拥有同一程序集旧版本的自己的副本。 它必须使用自己的副本,而不是 GAC 中的任何内容。 在这种情况下,正确的版本控制可能比它的价值更麻烦,原因我不会详细讨论。 我的问题是:有没有办法告诉.NET:只需使用此 DLL,就在这个目录中 - 忽略您在 GAC 或其他任何地方找到的任何内容

I have a .NET assembly that (for reasons outside my control) must be in the GAC. However, the same assembly is used by another program, which has a its own copy of an older version of the same assembly. It must use its own copy and not whatever is in the GAC. Proper versioning is probably more hassle than it's worth in this case, for reasons I won't go into. My questions is: is there anyway to tell .NET: just use THIS DLL, right here in this directory - ignore whatever you find in the GAC or anywhere else.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

不弃不离 2024-07-16 10:22:05

绑定重定向不起作用的原因之一是 Oracle.ManagedDataAccess 提供程序对 dll 的搜索顺序与非托管提供程序不同。 非托管提供程序在应用程序目录中启动,然后查找注册表中的 dll 路径,然后查找 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/en/database/oracle/oracle-database/12.2/odpnt/installODPmd.html#GUID-0E834EC7-21DF-4913-B712-2B0A07FD58FD

那么解决的方法这个问题是取消注册 GAC 程序集,或者如果无法卸载,只需将不同版本的 Oracle.ManagedDataAccess 放入 bin 和 web.config 中而不是 GAC 中的版本。

One reason the binding redirect doesn't work is because the Oracle.ManagedDataAccess provider has a different search order for dlls than the unmanaged provider. The unmanaged provider starts in the application directory, then looks in the dllpath in the registry, then the dll path in machine.config, then dll path in web.config. According to the Oracle documentation, the search order for managed provider works like this:

Managed Driver will reference these assemblies by using the following search order:

  1. Global Assembly Cache
  2. The web application's bin directory or Windows application's EXE directory
  3. The x86 or x64 subdirectory based on whether the application runs in 32-bit or 64-bit .NET Framework. If the application is built using AnyCPU, then ODP.NET will use the correct DLL bitness as long as the assembly is available. Oracle recommends using this method of finding dependent assemblies if your application is AnyCPU.

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

So the way to resolve this problem is to unregister the GAC assembly OR simply put a different version of Oracle.ManagedDataAccess in your bin and web.config than what's in GAC, if you can't uninstall it.

无所的.畏惧 2024-07-16 10:22:05

我更改了 GAC 中程序集的名称,将“_”作为第一个字符。

I change the name of the assembly in the GAC, put an "_" as the first character.

魔法少女 2024-07-16 10:22:04

确保 GAC 程序集和本地程序集具有不同的版本号(至少让您的内部版本号通过在 AssemblyInfo 中使用通配符来自动递增 AssemblyVersion 是个好主意:[程序集: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>

Make sure the GAC Assembly and local Assembly have different version numbers (not a bad idea to let your build number, at least, auto-increment by wild-carding your AssemblyVersion in AssemblyInfo: [assembly: AssemblyVersion("1.0.0.*")] ). Then, redirect your assembly binding using your app's config:

In your case, you won't need the "appliesTo" attribute of the assemblyBinding config. You just need something like:

<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>
我喜欢麦丽素 2024-07-16 10:22:04

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

If they have the same version number the answer is you can't. If you attempt to load an assembly that has the same full assembly name (name, version, key) as a GAC'd assembly the CLR will pick the GAC'd assembly every single time.

友欢 2024-07-16 10:22:04

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

此没有回答您的问题,因为它仅适用于开发用途,即使如此,也并不真正推荐,因为它不反映生产用途。 不过我想无论如何我都会分享它,因为知道这一点很高兴。

You can set the DEVPATH to force load an assembly, see link text

This doesn't answer your question since it only meant for development use and even then not really recommended as it doesn't mirror production usage. However I thought I'll share it anyway since it's good to know.

↘紸啶 2024-07-16 10:22:04

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

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

Have you tried Assembly.LoadFromFile()? This is a manual thing to do, but should load your assembly into memory before it is needed. .NET will then use the one in memory instead of hunting for it.

Another way would be if the local assembly was unsigned, you could differentiate it that way.

Rob

烛影斜 2024-07-16 10:22:04

我有类似的问题。 我通过使用 ildasm 和 ilasm 生成新的 dll 来更改目标 dll 的 publicKeyToken。 然后我在项目引用中更新了它以指向新的 dll。 我采取的步骤是

这对我有用。

I had a similar issue. I changed the publicKeyToken of the target dll by using ildasm and ilasm to generate a new dll. I then updated it in the project reference to point to the new dll. The steps I took are here.

This worked for me.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文