Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何强制编译为目标.NET Framework 4的应用程序在.NET Framework 4.6.1下运行?_.net_Clr - Fatal编程技术网

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

如何强制编译为目标.NET Framework 4的应用程序在.NET Framework 4.6.1下运行?,.net,clr,.net,Clr,我做了大量的研究,没有找到任何合适的答案。下面是一个场景 我有一个编译为目标.NETFramework4的应用程序。在运行时,我希望该应用程序在.NETFramework 4.6.1中实际执行。到目前为止,我找到了两种选择 在.NET Framework 4.6.1下重新编译应用程序 使用version=“v4.0”sku=“.NETFramework,version=v4.6.1”将configuration/startup/supportedRuntime元素添加到app.config 选项

我做了大量的研究,没有找到任何合适的答案。下面是一个场景

我有一个编译为目标.NETFramework4的应用程序。在运行时,我希望该应用程序在.NETFramework 4.6.1中实际执行。到目前为止,我找到了两种选择

  • 在.NET Framework 4.6.1下重新编译应用程序
  • 使用version=“v4.0”sku=“.NETFramework,version=v4.6.1”将configuration/startup/supportedRuntime元素添加到app.config
  • 选项1不可取,因为它需要重新发布软件

    选项2没有达到我预期的效果。它似乎会检查是否安装了CLR 4.0(不是framework 4.0),如果未安装,则会提示下载相应的SKU进行安装。安装后,应用程序仍在.NET Framework 4.0下执行

    作为一个测试,以及发布这个问题的原因,我创建了一个简单的控制台应用程序

    Console.WriteLine(System.Net.ServicePointManager.SecurityProtocol);
    
    如果是根据.NETFramework4编译的,那么输出是

    Ssl3,Tls

    如果是根据.NETFramework 4.6.1编译的,则输出为

    Tls,Tls11,Tls12


    特定ServicePointManager.SecurityProtocol的确定与4 vs 4.6.1框架的一般问题无关,我恐怕没有明确的答案,因为它与一般情况无关(如果您愿意,所有情况可能都是特定的)

    对于具体答案,如下所述:

    从.NETFramework 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>
    
    
    ...
    ...
    ...
    
    我是。。。询问强制针对framework 4.0编译的应用程序使用framework 4.6.1运行的一般情况

    嗯,您已经使用app.config文件条目执行了。它使用户能够在没有先安装4.6.1的情况下运行程序。他所要做的就是点击“是”按钮。这并不是经常使用,当用户负责用Windows Update更新他的机器时,4.6.1应该始终出现在机器上。如果他故意不这样做,“强迫”就不太可能被接受

    但这并不是你的问题的实质。您希望您的程序能够像安装在4.6.1上一样运行。那是一壶完全不同的鱼。请注意,2)不起作用,您不能那么容易地愚弄运行时。编译器在您的可执行文件中嵌入了一个,运行时使用该文件来确定其行为。查看ildasm.exe,双击清单查看。您的app.config条目不会覆盖它

    最大的问题是.NET4.5在运行时和框架程序集中都发生了重大变化,这与.NET4.5有很大的不同。重到足以保证将版本升级到5.0。但这总是给客户带来很多痛苦和痛苦,如果微软运行的是一个针对4.0的程序,它会拿出书中的每一个技巧,让4.5(及以上)表现得像4.0

    不仅仅是一个把戏。一种核心方法是存储在c:\Program Files(x86)\reference Assembly目录中的引用程序集。它们存储目标包文件。最初生成程序时,您使用了存储在C:\Program Files(x86)\Reference Assemblys\Microsoft\Framework.NETFramework\v4.0中的文件。如果您重新确定项目的目标,那么您将使用v4.6.1中存储的目标。他们非常不同。值得注意的是,你所说的是不同的,它获得了两个新的价值观。这是一个突破性的改变,一个.NET 4.0程序在看到SecurityProtocolType.Tls12时很容易发生心脏病发作,它完全不知道这意味着什么。使用错误的目标包文件构建程序可能会导致错误

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


    因此,不可能让编译为目标.NET4.0的程序像在更高版本上运行一样运行。您所了解的注册表项和appcontext开关仅与ServicePointManager.SecurityProtocol属性高度相关。它们的存在仅仅是因为您不是唯一希望这样做的客户,TLS版本非常重要。只需确保新的枚举值不会使程序出错。

    谢谢。这确实解决了我的示例中的问题,这也是我们将要使用的。我也对更大问题的答案感兴趣。您是否碰巧知道这是否可能,如果可能,如何实现?嗯,SecurityProtocolType的.NET 4.0版本没有您喜欢的枚举值。你的应用程序如何能够正确解释属性值是一个很难猜测的问题。但如果它能工作,那么它也能工作。它只有在安装>=4.5框架时才能工作。即使应用程序是针对4.0编译的,为什么不将目标更改为4.5.2+?你试图做的是一个黑客,可以在不稳定的方式打破。从4.0到4.5.2的变化并不是很感谢你的回答。这对于我提出的样本来说是非常有效的,它突出了我试图确定的东西。在这个问题上,我是在问关于一般cas的问题