我做了大量研究,没有找到合适的答案。这是场景。
我有一个编译为目标.NET Framework 4的应用程序。在运行时,我希望该应用程序实际在.NET Framework 4.6.1中执行。到目前为止我找到了两个选项。
选项1是不可取的,因为它需要重新发布软件。
选项2没有达到我的预期。它似乎检查是否安装了CLR 4.0(不是框架4.0),如果没有提示下载适当的SKU来安装它。安装后,应用程序仍在.NET Framework 4.0下执行
作为测试,以及发布此问题的原因,我创建了一个小型控制台应用程序,只需执行此操作
Console.WriteLine(System.Net.ServicePointManager.SecurityProtocol);
如果是针对.NET Framework 4编译的,则输出为
Ssl3,Tls
如果是针对.NET Framework 4.6.1编译的,则输出为
Tls,Tls11,Tls12
答案 0 :(得分:11)
我...询问强制针对框架4.0编译的应用程序使用框架4.6.1运行的一般情况
好吧,您已经使用了app.config文件条目。它授权this feature,用户无法在不安装4.6.1的情况下运行程序。他所要做的就是单击是按钮。并非这种情况经常被运用,当用户负责使用Windows Update更新机器时,应始终在机器上存在4.6.1。如果他故意没有那么强迫"不太可能被接受。
但实际上这不是你的问题所在。您希望程序表现,就像它安装在4.6.1上一样。这是一个非常不同的鱼。请注意2)不起作用,你不能轻易地愚弄运行时。编译器在您的可执行文件中嵌入了TargetFrameworkAttribute attribute,是运行时用来确定其行为的 。看看ildasm.exe,双击清单查看它。您的app.config条目不会覆盖它。
最大的问题是,.NET 4.5与运行时和框架程序集中的重大重大变更完全不同。足够重,可以保证版本高达5.0。但这总会给客户带来很多痛苦和痛苦,如果它运行一个针对4.0的程序,那么微软就会把书中的每一个技巧都拉到4.5(及以上)就像4.0一样。
不只是一招。一种核心方法是存储在c:\ Program Files(x86)\ Reference Assemblies目录中的引用程序集。他们存储目标包文件。最初构建程序时,您使用了存储在C:\ Program Files(x86)\ Reference Assemblies \ Microsoft \ Framework.NETFramework \ v4.0中的存储库。如果您重新定位项目,那么您将使用v4.6.1中存储的项目。他们是非常不同的。值得注意的是,你所谈论的SecurityProtocolType enum是不同的,它获得了两个新的价值观。这是一个破解更改,.NET 4.0程序在看到SecurityProtocolType.Tls12时容易遭受心脏病发作,它不知道它可能意味着什么。使用错误的定位包文件构建程序可能会导致deeply mystifying exceptions。
和其他技巧。根据[TargetFrameworkAttribute],有选择地打开后.NET 4.0版本中的错误修复,对错误的向后兼容性对于确保程序不会观察到已更改的运行时行为非常重要。 CLR充满了appcompat开关的边缘。我可以指向CoreCLR中的源代码文件,但看起来完全太可怕了:)
所以不,将编译为目标.NET 4.0的程序表现得像在较高版本上运行一样是不可能的。您了解的注册表项和appcontext开关是高度特定于ServicePointManager.SecurityProtocol属性。它们只是因为您不是唯一想要这样做的客户,TLS版本非常重要。只需确保新的枚举值不会使您的程序失效。
答案 1 :(得分:4)
具体的ServicePointManager.SecurityProtocol确定与4 vs 4.6.1框架的一般问题完全无关,我担心这些问题没有明确的答案,因为它与之无关。一般情况(如果你愿意的话,所有情况都可能是具体的。)
具体答案如下所述:Mitigation: TLS Protocols
从.NET Framework 4.6开始, System.Net.ServicePointManager和System.Net.Security.SslStream 允许类使用以下三种协议之一: Tls1.0,Tls1.1或Tls 1.2。 SSL3.0协议和RC4密码不是 支撑。
如果安装了4.6+,那么您确实可以更改程序的行为而无需重新编译它,如文章中所述,只需将此行添加到.config文件中:
<configuration>
...
<runtime>
...
<AppContextSwitchOverrides value="Switch.System.Net.DontEnableSchUseStrongCrypto=false" />
</runtime>
...
</configuration>