如何强制 .NET 使用 GAC 中程序集的本地副本
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/267693/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I force .NET to use a local copy of an assembly that's in the GAC
提问by EMP
I have a .NET assembly that (for reasons outside my control) mustbe 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.
我有一个 .NET 程序集(出于我无法控制的原因)必须在 GAC 中。但是,同一个程序集被另一个程序使用,该程序拥有同一个程序集的旧版本的副本。它必须使用自己的副本,而不是 GAC 中的任何内容。在这种情况下,正确的版本控制可能比它的价值更麻烦,原因我不会详细说明。我的问题是:无论如何要告诉 .NET:只需使用此 DLL,就在此目录中 - 忽略您在 GAC 或其他任何地方找到的任何内容。
回答by Corbin March
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:
确保 GAC 程序集和本地程序集具有不同的版本号(让您的内部版本号至少通过在 AssemblyInfo 中通配您的 AssemblyVersion 来自动递增是一个不错的主意:[assembly: AssemblyVersion("1.0.0.*" )] )。然后,使用应用程序的配置重定向程序集绑定:
- http://msdn.microsoft.com/en-us/library/2fc472t2(VS.80).aspx
- http://msdn.microsoft.com/en-us/library/433ysdt1(VS.80).aspx.
- http://msdn.microsoft.com/en-us/library/2fc472t2(VS.80).aspx
- http://msdn.microsoft.com/en-us/library/433ysdt1(VS.80).aspx。
In your case, you won't need the "appliesTo" attribute of the assemblyBinding config. You just need something like:
在您的情况下,您不需要 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>
回答by JaredPar
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.
如果它们具有相同的版本号,则答案是您不能。如果您尝试加载与 GAC 程序集具有相同完整程序集名称(名称、版本、密钥)的程序集,CLR 将每次都选择 GAC 程序集。
回答by Ying
You can set the DEVPATH to force load an assembly, see link text
您可以设置 DEVPATH 以强制加载程序集,请参阅链接文本
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.
这不能回答您的问题,因为它仅适用于开发用途,即使如此也不是真正推荐的,因为它不反映生产用途。但是,我想无论如何我都会分享它,因为很高兴知道。
回答by dasons
I had a similar issue. I changed the publicKeyToken of the target dll by using ildasmand ilasmto generate a new dll. I then updated it in the project reference to point to the new dll. The steps I took are here.
我有一个类似的问题。我通过使用ildasm和ilasm生成新的 dll更改了目标 dll 的 publicKeyToken 。然后我在项目引用中更新它以指向新的 dll。我采取的步骤在这里。
This worked for me.
这对我有用。
回答by Charles Owen
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:
绑定重定向不起作用的原因之一是 Oracle.ManagedDataAccess 提供程序对 dll 的搜索顺序与非托管提供程序不同。非托管提供程序在应用程序目录中启动,然后在注册表中的 dllpath 中查找,然后是 machine.config 中的 dll 路径,然后是 web.config 中的 dll 路径。根据 Oracle 文档,托管提供程序的搜索顺序如下所示:
Managed Driver will reference these assemblies by using the following search order:
托管驱动程序将使用以下搜索顺序引用这些程序集:
- Global Assembly Cache
- The web application's bin directory or Windows application's EXE directory
- 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.
- 全局程序集缓存
- Web 应用程序的 bin 目录或 Windows 应用程序的 EXE 目录
- x86 或 x64 子目录基于应用程序是在 32 位还是 64 位 .NET Framework 中运行。如果应用程序是使用 AnyCPU 构建的,那么只要程序集可用,ODP.NET 就会使用正确的 DLL 位数。如果您的应用程序是 AnyCPU,Oracle 建议使用此方法查找相关程序集。
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.
因此,解决此问题的方法是取消注册 GAC 程序集,或者在您的 bin 和 web.config 中放置与 GAC 中不同版本的 Oracle.ManagedDataAccess,如果您无法卸载它。
回答by Robert Wagner
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.
你试过 Assembly.LoadFromFile() 吗?这是一项手动操作,但应在需要之前将程序集加载到内存中。然后.NET 将使用内存中的那个而不是寻找它。
Another way would be if the local assembly was unsigned, you could differentiate it that way.
另一种方法是,如果本地程序集未签名,您可以通过这种方式区分它。
Rob
抢

