首页 文章

如何强制编译为.NET Framework 4的应用程序在.NET Framework 4.6.1下运行?

提问于
浏览
8

我做了大量的研究,没有找到任何合适的答案 . 这是场景 .

我有一个编译为目标.NET Framework 4的应用程序 . 在运行时,我希望该应用程序实际在.NET Framework 4.6.1中执行 . 到目前为止我找到了两个选项 .

  • 在.NET Framework 4.6.1下重新编译应用程序

  • 使用version = "v4.0" sku = ".NETFramework,Version=v4.6.1"将配置/ startup / supportedRuntime元素添加到app.config

选项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

2 回答

  • 11

    我...询问强制针对框架4.0编译的应用程序使用框架4.6.1运行的一般情况

    好吧,你已经使用了app.config文件条目 . 它授权this feature,用户可以't get the program running without installing 4.6.1 first. All he has to do is click the Yes button. Not that this gets exercised very often, 4.6.1 should always be present on the machine when the user is responsible about keeping his machine updated with Windows Update. If he intentionally doesn' t然后"forcing"不太可能被很好地接收 .

    但这实际上并不是你的问题所在 . 您希望您的程序__如何在4.6.1上安装 behave . 这是一个非常不同的鱼 . 请注意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是不同的,它获得了两个新的 Value 观 . 这是一个 breaking 更改,.NET 4.0程序在看到SecurityProtocolType.Tls12时容易遭受心脏病发作,它不知道它可能意味着什么 . 使用错误的定位包文件构建程序可能会导致deeply mystifying exceptions .

    和其他技巧 . 根据[TargetFrameworkAttribute],有选择地打开后.NET 4.0版本中的错误修复,对错误的向后兼容性对于确保程序不会观察到更改的运行时行为非常重要 . CLR充满了appcompat开关的边缘 . 我可以指向CoreCLR中的源代码文件但是看起来完全太可怕了:)

    所以不,将编译为目标.NET 4.0的程序表现得像在更高版本上运行一样是不可能的 . 您了解的注册表项和appcontext开关非常特定于ServicePointManager.SecurityProtocol属性 . 它们只是因为您不是唯一想要这样做的客户,TLS版本非常重要 . 只需确保新的枚举值不会使程序失效 .

  • 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>
    

相关问题