【问题标题】:Determining .net framework version in a running application在正在运行的应用程序中确定 .net 框架版本
【发布时间】:2018-12-13 09:03:42
【问题描述】:

(已编辑) 为什么即使我更改了项目的目标版本,AssemblyName.Version 仍会报告相同的版本?如何确定框架的实际执行版本?

这总是返回 4.0.0.0

foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
        {
            var aName = assembly.GetName();
            Console.WriteLine($"{aName.Name} {aName.Version}" );
        }

【问题讨论】:

    标签: .net windows frameworks version .net-assembly


    【解决方案1】:

    微软官方检测.NET Framework运行时版本的例子如下,

    https://docs.microsoft.com/en-us/dotnet/framework/migration-guide/how-to-determine-which-versions-are-installed#net_d

    using System;
    using Microsoft.Win32;
    
    public class GetDotNetVersion
    {
       public static void Main()
       {
          GetDotNetVersion.Get45PlusFromRegistry();
       }
    
       private static void Get45PlusFromRegistry()
       {
          const string subkey = @"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full\";
    
        using (RegistryKey ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey(subkey))
          {
            if (ndpKey != null && ndpKey.GetValue("Release") != null) {
                Console.WriteLine(".NET Framework Version: " + CheckFor45PlusVersion((int) ndpKey.GetValue("Release")));
            }
             else {
                Console.WriteLine(".NET Framework Version 4.5 or later is not detected.");
             } 
        }
       }
    
       // Checking the version using >= will enable forward compatibility.
       private static string CheckFor45PlusVersion(int releaseKey)
       {
          if (releaseKey >= 461808)
             return "4.7.2 or later";
          if (releaseKey >= 461308)
             return "4.7.1";
          if (releaseKey >= 460798)
             return "4.7";
          if (releaseKey >= 394802)
             return "4.6.2";
          if (releaseKey >= 394254)
             return "4.6.1";      
          if (releaseKey >= 393295)
             return "4.6";      
          if (releaseKey >= 379893)
             return "4.5.2";      
          if (releaseKey >= 378675)
             return "4.5.1";      
          if (releaseKey >= 378389)
           return "4.5";      
        // This code should never execute. A non-null release key should mean
        // that 4.5 or later is installed.
        return "No 4.5 or later version detected";
       }
    }   
    // This example displays output like the following:
    //       .NET Framework Version: 4.6.1
    

    更新: 事实证明,真正的问题与 .NET Framework 类使用的默认 SSL/TLS 协议集有关,如果您的程序集在编译时针对某个框架版本进行编译,则会触发不同的运行时行为。

    AppContext 开关是 <AppContextSwitchOverrides value="Switch.System.Net.DontEnableSchUseStrongCrypto=true"/>,如 KB3069494 中所述,

    https://support.microsoft.com/en-us/help/3069494/cannot-connect-to-a-server-by-using-the-servicepointmanager-or-sslstre

    您还可以查看最佳实践文章以获取更多提示,

    https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls?view=netframework-4.7.2

    【讨论】:

    • 这不能回答我要问的问题。这回答了“安装了哪些版本?”的问题。我在问“当前应用程序使用哪个版本?请注意我发布的第一句话中的斜体字。
    • @ElroyFlynn 您的应用程序只能使用已安装的 .NET Framework 版本(仅仅是因为 .NET Framework 4.x 使用就地升级)。这就是所谓的运行时版本。如果您要求其他版本号,请再次编辑您的问题。
    • 那么当我针对不同的框架版本并在同一台机器上运行它时,我的应用程序(其他部分)如何产生不同的结果?如前所述,我将目标从 4.5 更改为 4.6 并获得不同的行为。
    • 嗯,这是你真正的问题。 Microsoft 设计了兼容性层来假装您的应用程序在较旧的 .NET Framework 版本上运行,如果您查看 docs.microsoft.com/en-us/dotnet/framework/whats-new/… 之类的文档(“兼容性开关”部分),这是众所周知的。根据您观察到的行为差异,有一些方法可以相应地解决它们。
    • 好的,我发现我最初的问题没有得到充分的了解。我会接受你的回答。如果您可以对其进行编辑以开始说“许多 .net 版本是就地升级,程序集继续报告原始版本值。要确定实际版本,请阅读注册表,如显示在下面的代码中。“(正确吗?)关于我的真正问题,当需要 tls 1.2 时,WebRequest 失败,而当目标 fw
    【解决方案2】:

    试试这个:

    private static string GetExecutingAssemblyTargetFramework()
        {
            string result = string.Empty;
            System.Reflection.Assembly asm = System.Reflection.Assembly.GetExecutingAssembly();
            System.Runtime.Versioning.TargetFrameworkAttribute targetFrameworkAttribute = asm.GetCustomAttributes(
                typeof(System.Runtime.Versioning.TargetFrameworkAttribute), false).FirstOrDefault()
                as System.Runtime.Versioning.TargetFrameworkAttribute;
            if (targetFrameworkAttribute != null)
                result = targetFrameworkAttribute.FrameworkDisplayName;
            return result;
        }
    

    您也可以使用原始问题中的相同循环:

            foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
            {
                Console.WriteLine(GetAssemblyTargetFramework(assembly));
            }
    
       private static string GetAssemblyTargetFramework(System.Reflection.Assembly asm)
        {
            string result = string.Empty;
            System.Runtime.Versioning.TargetFrameworkAttribute targetFrameworkAttribute = asm.GetCustomAttributes(
                typeof(System.Runtime.Versioning.TargetFrameworkAttribute), false).FirstOrDefault()
                as System.Runtime.Versioning.TargetFrameworkAttribute;
            if (targetFrameworkAttribute != null)
                result = targetFrameworkAttribute.FrameworkDisplayName;
            return result;
        }
    

    【讨论】:

    • OP 不是在寻找 TargetFramework,而是在寻找当前正在执行的框架版本。目标框架指示程序集是针对哪个框架构建的,而不是当前正在执行程序集的框架。
    猜你喜欢
    • 2021-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-06
    相关资源
    最近更新 更多