禁止搜索全局程序集缓存(GAC)

6
我正在尝试使用FSharp PowerPack来使用ArgParser库,但在我的机器上遇到了一些严重的问题,似乎加载了错误版本的FSharp.Core.dll从GAC,这导致ArgParser的加载失败。理想情况下,我会解决这个问题(因为它在我的同事的电脑上运行得很好),但我已经尝试了各种卸载和重新安装系统中的FSharp二进制文件,但都没有效果。
由于GAC的存在,我不喜欢无法将“已知”的正确DLLs放入可执行目录中,如果有任何方法可以禁用在GAC中搜索,我将非常高兴这样做。
我知道这个解决方案可能有点糟糕,但现在我只需要让它加载并工作,我会尝试任何方法。
编辑:以下是项目的加载输出。
'PowerPackTest.exe' (Managed (v4.0.30319)): Loaded 'C:\WINNT\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'PowerPackTest.exe' (Managed (v4.0.30319)): Loaded 'C:\Projects\PowerPackTest\PowerPackTest\bin\Debug\PowerPackTest.exe', Symbols loaded.
'PowerPackTest.exe' (Managed (v4.0.30319)): Loaded 'C:\WINNT\Microsoft.Net\assembly\GAC_MSIL\FSharp.Core\v4.0_4.0.0.0__b03f5f7f11d50a3a\FSharp.Core.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'PowerPackTest.exe' (Managed (v4.0.30319)): Loaded 'C:\WINNT\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0__b77a5c561934e089\System.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'PowerPackTest.exe' (Managed (v4.0.30319)): Loaded 'C:\WINNT\assembly\GAC_MSIL\FSharp.PowerPack\2.0.0.0__a19089b1c74d0809\FSharp.PowerPack.dll'
'PowerPackTest.exe' (Managed (v4.0.30319)): Loaded 'C:\WINNT\assembly\GAC_MSIL\FSharp.Core\2.0.0.0__b03f5f7f11d50a3a\FSharp.Core.dll'

正如您所看到的,它首先加载FSharp.Core v4,但在最后一秒加载v2。这在我的同事的机器上不会发生。


好的,那么你的应用程序是CLR4 - 你是如何加载FSharp.Core程序集的?我猜你是在运行时使用LoadWithPartialName吗? - x0n
不行:"open Microsoft.FSharp.Text" 我从来没有明确引用FSharp.Core。我从来没有必要这样做。我一直认为它是隐含的,就像System.Core一样。 - Adam Haile
啊,你正在使用 F# 解释器……我明白了。嗯。你是说你的同事们的机器上也安装了 GAC 中的 v2+v4? - x0n
不,没有使用FSI。它被编译成了exe文件。实际上,通过FSI运行的FSX脚本可以正常工作。是的,他们也安装了两个版本……据我所知,安装程序总是会同时安装两个版本。 - Adam Haile
3个回答

5
预编译的PowerPack二进制文件是针对CLR v2编译的,并且它们也引用了FSharp.Core v2。这可能是导致问题的原因。我不太明白为什么.NET 4版本的PowerPack没有提供下载(或在NuGet中!),但您可以通过两种方式解决此问题:
您可以设置程序集绑定重定向,但我不知道这是否适用于fsi.exe
或者,您可以下载F# PowerPack的源代码并编译自己的.NET 4版本。这很容易。

我以为 F# 需要 CLR v4??它能够在 CLR v2 上使用吗? - Adam Haile
2
我也不明白为什么没有PowerPack的4.0版本。有几次我需要用到它,最后只好自己构建(这相当简单)。 - Tomas Petricek
有关以4.0构建它的任何建议吗?它一直告诉我BigInteger未定义:( - Adam Haile
3
我想通了... System.Numerics 显然曾经是 FSharp.Core 的一部分,但现在已经是它自己的 DLL 了... 一旦我添加了它,BigInteger 就被找到并且成功构建。而且,现在我的项目使用 v4.0,它可以正常工作。谢谢! - Adam Haile
@Adam - 实际上正在发生的事情是 F# 被设计为可以与 CLR v2 或 CLR v4 一起使用。由于 v2 不支持 BigInteger,因此 FSharp.Core v2 包含了一个实现,而 v4 则依赖于 CLR v4 的 System.Numerics。 - Joel Mueller

0

我刚刚查看了一个 .net 4.0 项目,我正在使用 ArgParser,在引用 FSharp.Core 和 FSharp.Powerpack 的同时,还在 app.config 中设置了重定向:

<startup useLegacyV2RuntimeActivationPolicy="true">
   <supportedRuntime version="v4.0"/>
</startup>

0
GAC总是胜出 - 这是一项安全功能。如果您有不同版本的FSharp.Core,为什么不将其放入GAC中,并在app.config中使用重定向绑定来强制加载新版本,或者重新构建您的应用程序(可能不可行)以针对新版本进行编译呢?

GAC显示我有FSharp.Core的v2和v4版本。我已经尝试告诉项目使用特定版本,但无论我做什么,它似乎总是加载v2。 - Adam Haile
好的,我猜测v4是指CLR4。你可能需要重新编译你的应用程序以针对.NET 4。你不能将v4程序集加载到v2 CLR中。你可以通过在app.config文件中使用supportedRuntimes元素来强制你的应用程序使用CLR4而无需重新编译。然后,你需要在配置中添加重定向绑定以将v2重定向到v4。查一下吧。 - x0n
2
已经在这里了,以下是来自 App.Config 的条目: <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" /> - Adam Haile

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接