2016-06-17 94 views
7

我做了大量的研究,没有找到任何合适的答案。这是场景。如何强制编译的目标.NET Framework 4在.NET框架4.6.1下运行?

我有一个应用程序被编译为面向.NET Framework 4.在运行时我希望该应用程序在.NET Framework 4.6.1中实际执行。到目前为止我发现了两个选择。

  1. 重新编译应用程序下.NET框架4.6.1
  2. 添加的配置/启动/ supportedRuntime元件与版本的app.config = “4.0版” SKU =”。NETFramework,版本= v4.6.1 “

选项1不可取,因为它需要重新发布软件。

选项2不会做我期望的。它似乎检查是否安装了CLR 4.0(不是框架4.0),如果不提示下载相应的SKU进行安装。安装后,应用程序仍然在.NET框架4.0

执行作为测试,而这个问题是张贴的原因,我创建了一个小型控制台应用程序,它只是做到这一点

Console.WriteLine(System.Net.ServicePointManager.SecurityProtocol); 

如果编译针对.NET框架4,则输出是

SSL3,TLS

如果正在针对.NET编译Framewo RK 4.6.1则输出是

TLS,Tls11,Tls12

+2

http://stackoverflow.com/a/28502562/17034 –

+1

谢谢Hans。这确实解决了我的示例中的问题,并且是我们要使用的。我也对更大的问题的答案感兴趣。你有机会知道这是否可能,如果是的话,如何? –

+1

Hmya,SecurityProtocolType的.NET 4.0版本没有你喜欢的枚举值。你的应用程序如何正确解释属性值是一个非常困难的猜测。但如果它起作用,那么它就可以工作 –

回答

8

我...询问有关强制对框架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版本相当重要。只要确保新的枚举值不会影响您的程序。

+0

标记为答案,因为它似乎实际上不可能做我在问什么。你的解释包含很多细节和参考。谢谢汉斯。 –

+0

@GregBogumil你要做的就是强迫最终用户破解 - 你不想升级你的编译目标(为什么?),但是想强制一个新的运行时使用4.0中不存在的TLS值。真正的解决办法是改变你的目标 –

3

具体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+,那么你的确可以改变你的程序的行为W/O重新编译,在文章中详细介绍,只是添加此行到您的.config文件:

<configuration> 
    ... 
    <runtime> 
    ... 
    <AppContextSwitchOverrides value="Switch.System.Net.DontEnableSchUseStrongCrypto=false" /> 
    </runtime> 
    ... 
</configuration> 
+1

谢谢你的回答。我提出的这个例子强调了我想要确定的东西,这是非常有效的。在这个问题中,我正在询问关于强制使用框架4.6编译的应用程序的一般情况。我比CLR和框架之间的差异更加精通,并且明白强制使用不同的CLR运行是可以实现的。似乎基于这个问题的答案很好,可能是因为没有重新编译应用程序到目标框架4.6.1就无法完成。 –

+1

特别感谢您对运行时配置的更改。根据大量研究,我迄今为止的最佳答案是改变注册表。在有时需要管理人员的客户端机器上。 –

相关问题