답변
이런 식으로해야합니다. 레지스트리에서 값을 가져옵니다.
.NET 1-4의 경우 :
Framework가장 높은 설치된 버전이고 SP해당 버전의 서비스 팩입니다.
RegistryKey installed_versions = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP");
string[] version_names = installed_versions.GetSubKeyNames();
//version names start with 'v', eg, 'v3.5' which needs to be trimmed off before conversion
double Framework = Convert.ToDouble(version_names[version_names.Length - 1].Remove(0, 1), CultureInfo.InvariantCulture);
int SP = Convert.ToInt32(installed_versions.OpenSubKey(version_names[version_names.Length - 1]).GetValue("SP", 0));
.NET 4.5+의 경우 ( 공식 문서에서 ) :
using System;
using Microsoft.Win32;
...
private static void Get45or451FromRegistry()
{
    using (RegistryKey ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey("SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4\\Full\\")) {
        int releaseKey = Convert.ToInt32(ndpKey.GetValue("Release"));
        if (true) {
            Console.WriteLine("Version: " + CheckFor45DotVersion(releaseKey));
        }
    }
}
...
// Checking the version using >= will enable forward compatibility,  
// however you should always compile your code on newer versions of 
// the framework to ensure your app works the same. 
private static string CheckFor45DotVersion(int releaseKey)
{
    if (releaseKey >= 461808) {
        return "4.7.2 or later";
    }
    if (releaseKey >= 461308) {
        return "4.7.1 or later";
    }
    if (releaseKey >= 460798) {
        return "4.7 or later";
    }
    if (releaseKey >= 394802) {
        return "4.6.2 or later";
    }
    if (releaseKey >= 394254) {
        return "4.6.1 or later";
    }
    if (releaseKey >= 393295) {
        return "4.6 or later";
    }
    if (releaseKey >= 393273) {
        return "4.6 RC or later";
    }
    if ((releaseKey >= 379893)) {
        return "4.5.2 or later";
    }
    if ((releaseKey >= 378675)) {
        return "4.5.1 or later";
    }
    if ((releaseKey >= 378389)) {
        return "4.5 or later";
    }
    // This line 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";
}
답변
확실하지 아무도 다음과 같은 제안하지 왜 마이크로 소프트의 공식 조언 바로 여기 .
이것이 그들이 권장하는 코드입니다. 물론 추악하지만 작동합니다.
.NET 1-4의 경우
private static void GetVersionFromRegistry()
{
     // Opens the registry key for the .NET Framework entry. 
        using (RegistryKey ndpKey =
            RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, "").
            OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\"))
        {
            // As an alternative, if you know the computers you will query are running .NET Framework 4.5  
            // or later, you can use: 
            // using (RegistryKey ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine,  
            // RegistryView.Registry32).OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\"))
        foreach (string versionKeyName in ndpKey.GetSubKeyNames())
        {
            if (versionKeyName.StartsWith("v"))
            {
                RegistryKey versionKey = ndpKey.OpenSubKey(versionKeyName);
                string name = (string)versionKey.GetValue("Version", "");
                string sp = versionKey.GetValue("SP", "").ToString();
                string install = versionKey.GetValue("Install", "").ToString();
                if (install == "") //no install info, must be later.
                    Console.WriteLine(versionKeyName + "  " + name);
                else
                {
                    if (sp != "" && install == "1")
                    {
                        Console.WriteLine(versionKeyName + "  " + name + "  SP" + sp);
                    }
                }
                if (name != "")
                {
                    continue;
                }
                foreach (string subKeyName in versionKey.GetSubKeyNames())
                {
                    RegistryKey subKey = versionKey.OpenSubKey(subKeyName);
                    name = (string)subKey.GetValue("Version", "");
                    if (name != "")
                        sp = subKey.GetValue("SP", "").ToString();
                    install = subKey.GetValue("Install", "").ToString();
                    if (install == "") //no install info, must be later.
                        Console.WriteLine(versionKeyName + "  " + name);
                    else
                    {
                        if (sp != "" && install == "1")
                        {
                            Console.WriteLine("  " + subKeyName + "  " + name + "  SP" + sp);
                        }
                        else if (install == "1")
                        {
                            Console.WriteLine("  " + subKeyName + "  " + name);
                        }
                    }
                }
            }
        }
    }
}
.NET 4.5 이상
// Checking the version using >= will enable forward compatibility, 
// however you should always compile your code on newer versions of
// the framework to ensure your app works the same.
private static string CheckFor45DotVersion(int releaseKey)
{
   if (releaseKey >= 393295) {
      return "4.6 or later";
   }
   if ((releaseKey >= 379893)) {
        return "4.5.2 or later";
    }
    if ((releaseKey >= 378675)) {
        return "4.5.1 or later";
    }
    if ((releaseKey >= 378389)) {
        return "4.5 or later";
    }
    // This line 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";
}
private static void Get45or451FromRegistry()
{
    using (RegistryKey ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey("SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4\\Full\\")) {
        if (ndpKey != null && ndpKey.GetValue("Release") != null) {
            Console.WriteLine("Version: " + CheckFor45DotVersion((int) ndpKey.GetValue("Release")));
        }
      else {
         Console.WriteLine("Version 4.5 or later is not detected.");
      }
    }
}
답변
레지스트리에 대한 액세스 권한이 필요하지 않은 대체 방법은 특정 프레임 워크 업데이트에 도입 된 클래스의 존재를 확인하는 것입니다.
private static bool Is46Installed()
{
    // API changes in 4.6: https://github.com/Microsoft/dotnet/blob/master/releases/net46/dotnet46-api-changes.md
    return Type.GetType("System.AppContext, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", false) != null;
}
private static bool Is461Installed()
{
    // API changes in 4.6.1: https://github.com/Microsoft/dotnet/blob/master/releases/net461/dotnet461-api-changes.md
    return Type.GetType("System.Data.SqlClient.SqlColumnEncryptionCngProvider, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", false) != null;
}
private static bool Is462Installed()
{
    // API changes in 4.6.2: https://github.com/Microsoft/dotnet/blob/master/releases/net462/dotnet462-api-changes.md
    return Type.GetType("System.Security.Cryptography.AesCng, System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", false) != null;
}
private static bool Is47Installed()
{
    // API changes in 4.7: https://github.com/Microsoft/dotnet/blob/master/releases/net47/dotnet47-api-changes.md
    return Type.GetType("System.Web.Caching.CacheInsertOptions, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", false) != null;
}
답변
Environment.Version()다른 질문에 대한 정답을 제공하고 있습니다. 동일한 버전의 CLR이 .NET 2.0, 3 및 3.5에서 사용됩니다. 각 후속 릴리스에 추가 된 라이브러리에 대해 GAC 를 확인할 수 있다고 가정합니다 .
답변
예전에는 쉬웠지만 Microsoft는 큰 변화를 주기로 결정했습니다. 버전 4.5 이전 에는 .NET의 각 버전이 아래의 자체 디렉터리 C:\Windows\Microsoft.NET\Framework(하위 디렉터리 v1.0.3705, v1.1.4322, v2.0.50727, v3.0, v3.5및 v4.0.30319)에 상주했습니다 .
버전 4.5 이후 로 변경되었습니다. 각 버전의 .NET (예 : 4.5.x, 4.6.x, 4.7.x, 4.8.x, …)이 동일한 하위 디렉토리에 설치되어 v4.0.30319있으므로 더 이상 사용할 수 없습니다. 조사하여 설치된 .NET 버전을 확인하십시오.Microsoft.NET\Framework .
.NET 버전을 확인하기 위해 Microsoft 는 확인중인 .NET 버전에 따라 두 가지 다른 샘플 스크립트를 제공 했지만 이에 대해 두 가지 다른 C # 스크립트를 사용하는 것을 좋아하지 않습니다. 그래서 저는 그것들을 하나로 결합하려고 시도했습니다. 여기 GetDotNetVersion.cs제가 만든 스크립트 가 있습니다 (그리고 4.7.1 프레임 워크 용으로 업데이트했습니다).
using System;
using Microsoft.Win32;
public class GetDotNetVersion
{
    public static void Main(string[] args)
    {
        Console.WriteLine((args != null && args.Length > 0)
                          ? "Command line arguments: " + string.Join(",", args)
                          : "");
        string maxDotNetVersion = GetVersionFromRegistry();
        if (String.Compare(maxDotNetVersion, "4.5") >= 0)
        {
            string v45Plus = GetDotNetVersion.Get45PlusFromRegistry();
            if (v45Plus != "") maxDotNetVersion = v45Plus;
        }
        Console.WriteLine("*** Maximum .NET version number found is: " + maxDotNetVersion + "***");
    }
    private static string Get45PlusFromRegistry()
    {
        String dotNetVersion = "";
        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)
            {
                dotNetVersion = CheckFor45PlusVersion((int)ndpKey.GetValue("Release"));
                Console.WriteLine(".NET Framework Version: " + dotNetVersion);
            }
            else
            {
                Console.WriteLine(".NET Framework Version 4.5 or later is not detected.");
            }
        }
        return dotNetVersion;
    }
    // Checking the version using >= will enable forward compatibility.
    private static string CheckFor45PlusVersion(int releaseKey)
    {
        if (releaseKey >= 528040) return "4.8 or later";
        if (releaseKey >= 461808) return "4.7.2";
        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";
    }
    private static string GetVersionFromRegistry()
    {
        String maxDotNetVersion = "";
        // Opens the registry key for the .NET Framework entry.
        using (RegistryKey ndpKey = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, "")
                                        .OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\"))
        {
            // As an alternative, if you know the computers you will query are running .NET Framework 4.5 
            // or later, you can use:
            // using (RegistryKey ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, 
            // RegistryView.Registry32).OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\"))
            foreach (string versionKeyName in ndpKey.GetSubKeyNames())
            {
                if (versionKeyName.StartsWith("v"))
                {
                    RegistryKey versionKey = ndpKey.OpenSubKey(versionKeyName);
                    string name = (string)versionKey.GetValue("Version", "");
                    string sp = versionKey.GetValue("SP", "").ToString();
                    string install = versionKey.GetValue("Install", "").ToString();
                    if (install == "") //no install info, must be later.
                    {
                        Console.WriteLine(versionKeyName + "  " + name);
                        if (String.Compare(maxDotNetVersion, name) < 0) maxDotNetVersion = name;
                    }
                    else
                    {
                        if (sp != "" && install == "1")
                        {
                            Console.WriteLine(versionKeyName + "  " + name + "  SP" + sp);
                            if (String.Compare(maxDotNetVersion, name) < 0) maxDotNetVersion = name;
                        }
                    }
                    if (name != "")
                    {
                        continue;
                    }
                    foreach (string subKeyName in versionKey.GetSubKeyNames())
                    {
                        RegistryKey subKey = versionKey.OpenSubKey(subKeyName);
                        name = (string)subKey.GetValue("Version", "");
                        if (name != "")
                        {
                            sp = subKey.GetValue("SP", "").ToString();
                        }
                        install = subKey.GetValue("Install", "").ToString();
                        if (install == "")
                        {
                            //no install info, must be later.
                            Console.WriteLine(versionKeyName + "  " + name);
                            if (String.Compare(maxDotNetVersion, name) < 0) maxDotNetVersion = name;
                        }
                        else
                        {
                            if (sp != "" && install == "1")
                            {
                                Console.WriteLine("  " + subKeyName + "  " + name + "  SP" + sp);
                                if (String.Compare(maxDotNetVersion, name) < 0) maxDotNetVersion = name;
                            }
                            else if (install == "1")
                            {
                                Console.WriteLine("  " + subKeyName + "  " + name);
                                if (String.Compare(maxDotNetVersion, name) < 0) maxDotNetVersion = name;
                            } // if
                        } // if
                    } // for
                } // if
            } // foreach
        } // using
        return maxDotNetVersion;
    }
} // class
내 컴퓨터에서 다음을 출력합니다.
v2.0.50727 2.0.50727.4927 SP2
v3.0 3.0.30729.4926 SP2
v3.5 3.5.30729.4926 SP1
v4
클라이언트 4.7.03056
전체 4.7.03056
v4.0
클라이언트 4.0.0.0
.NET Framework 버전 : 4.7.2 이상
*** * 발견 된 최대 .NET 버전 번호 : 4.7.2 이상 ****
시간이 지남에 따라 유지 관리해야하는 유일한 것은 4.7.1 이상의 .NET 버전이 나오면 빌드 번호입니다. 기능을 수정하면 쉽게 수행 할 수 있습니다. CheckFor45PlusVersion . 새 버전의 릴리스 키를 알고 있어야합니다. 추가 할 수 있습니다. 예를 들면 :
if (releaseKey >= 461308) return "4.7.1 or later";
이 릴리스 키 는 여전히 최신 버전이며 Windows 10의 Fall Creators 업데이트에 유효합니다. 다른 (이전) Windows 버전을 계속 실행중인 경우 Microsoft 의이 설명서에 따라 다른 버전 이 있습니다.
다른 모든 Windows OS 버전 461310에 설치된 .NET Framework 4.7.1
따라서 필요한 경우 추가해야합니다.
if (releaseKey >= 461310) return "4.7.1 or later";
함수의 맨 위로 CheckFor45PlusVersion. 마찬가지로 최신 버전에서도 작동합니다. 예를 들어 최근에 4.8에 대한 검사를 추가했습니다. 일반적으로 빌드 번호를 찾을 수 있습니다. 으로 Microsoft에서 .
참고 : PowerShell이 아니라 Visual Studio를 설치할 필요가 없습니다 . 여기서csc.exe 설명한 스크립트를 컴파일하고 실행하는 데 사용할 수 있습니다.
업데이트 : 질문은 .NET Framework에 관한 것입니다. 완전성을 위해 .NET Core 버전 을 쿼리하는 방법도 언급하고 싶습니다 . 위와 비교하면 간단합니다. 명령 셸을 열고 다음을 입력합니다.
dotnet --infoEnter
그리고 .NET Core 버전 번호, Windows 버전 및 각 관련 런타임 DLL의 버전도 나열됩니다. 샘플 출력 :
.NET Core SDK (global.json 반영) :
버전 : 2.1.300
커밋 : adab45bf0c런타임 환경 :
OS 이름 : Windows
OS 버전 : 10.0.15063
OS 플랫폼 : Windows
RID : win10-x64
기본 경로 : C : \ Program Files \ dotnet \ sdk \ 2.1.300호스트 (지원에 유용) :
버전 : 2.1.0
커밋 : caa7b7e2ba.NET Core SDK 설치 :
1.1.9 [C : \ Program Files \ dotnet \ sdk]
2.1.102 [C : \ Program Files \ dotnet \ sdk]
…
2.1.300 [C : \ Program Files \ dotnet \ sdk].NET Core 런타임 설치 :
Microsoft.AspNetCore.All 2.1.0 [C : \ Program
Files \ dotnet \ shared \ Microsoft .AspNetCore.All]
…
Microsoft.NETCore.App 2.1.0 [C : \ Program Files \ dotnet \ shared \ Microsoft.NETCore.App]추가 .NET Core 런타임 또는 SDK를 설치하려면 :
https://aka.ms/dotnet-download
참고 그
- 
모든 추가 정보없이 버전 번호 만 필요한 경우을 사용할 수 있습니다
dotnet --version. - 
A의 64 비트 Windows PC , 설치할 수 의 x86 버전 나란히 과 의 x64 .NET 코어 버전. 이 경우 환경 변수에서 첫 번째 버전 만 가져옵니다
PATH. 최신 상태로 유지하고 각 버전을 알고 싶은 경우 특히 중요합니다. 두 버전을 모두 쿼리하려면 다음을 사용하십시오. 
C : \ Program Files \ dotnet \ dotnet.exe-버전
3.0.100-preview6-012264
C : \ Program Files (x86) \ dotnet \ dotnet.exe –version
버전 3.0.100-preview6-012264
위의 예에서 둘 다 동일하지만 두 인스턴스를 모두 업데이트하는 것을 잊은 경우 다른 결과를 얻을 수 있습니다! 참고 Program Files을위한 64 비트 버전과 Program Files (x86)는 IS 32 비트 버전.
업데이트 : 빌드 번호를 일련의 if 문 (Microsoft가 제안한대로) 대신 목록에 유지하려는 경우 CheckFor45PlusVersion대신 이 코드를 사용할 수 있습니다 .
private static string CheckFor45PlusVersion(int releaseKey)
{
    var release = new Dictionary<int, string>()
    {
            { 378389, "4.5" },
            { 378675, "4.5.1" }, { 379893, "4.5.2" },
            { 393295, "4.6" },
            { 394254, "4.6.1" }, { 394802, "4.6.2" },
            { 460798, "4.7" },
            { 461308, "4.7.1" }, { 461808, "4.7.2" },
            { 528040, "4.8 or later" }
    };
    int result = -1;
    foreach(var k in release.OrderBy(k=>k.Key))
    {
        if (k.Key <= releaseKey) result = k.Key; else break;
    };
    return (result > 0) ? release[result] : "No 4.5 or later version detected";
}
답변
AFAIK 프레임 워크에는이를 수행 할 수있는 기본 제공 방법이 없습니다. 이 게시물 에서 Windows 레지스트리 값을 읽어 프레임 워크 버전 결정에 대한 제안을 확인할 수 있습니다.
답변
이 클래스를 사용하면 응용 프로그램이 적절한 .NET 버전을 찾을 수없는 경우 충돌 및 굽기 대신 우아한 알림 메시지를 표시 할 수 있습니다. 기본 코드에서 다음과 같이하면됩니다.
[STAThread]
static void Main(string[] args)
{
    if (!DotNetUtils.IsCompatible())
        return;
   . . .
}
기본적으로 4.5.2가 필요하지만 원하는 클래스로 조정할 수 있습니다 (MessageBox를 Console로 자유롭게 대체 할 수 있음).
4.8 업데이트 :
public class DotNetUtils
{
    public enum DotNetRelease
    {
        NOTFOUND,
        NET45,
        NET451,
        NET452,
        NET46,
        NET461,
        NET462,
        NET47,
        NET471,
        NET472,
        NET48,
    }
    public static bool IsCompatible(DotNetRelease req = DotNetRelease.NET452)
    {
        DotNetRelease r = GetRelease();
        if (r < req)
        {
            MessageBox.Show(String.Format("This this application requires {0} or greater.", req.ToString()));
            return false;
        }
        return true;
    }
    public static DotNetRelease GetRelease(int release = default(int))
    {
        int r = release != default(int) ? release : GetVersion();
        if (r >= 528040) return DotNetRelease.NET48;
        if (r >= 461808) return DotNetRelease.NET472;
        if (r >= 461308) return DotNetRelease.NET471;
        if (r >= 460798) return DotNetRelease.NET47;
        if (r >= 394802) return DotNetRelease.NET462;
        if (r >= 394254) return DotNetRelease.NET461;
        if (r >= 393295) return DotNetRelease.NET46;
        if (r >= 379893) return DotNetRelease.NET452;
        if (r >= 378675) return DotNetRelease.NET451;
        if (r >= 378389) return DotNetRelease.NET45;
        return DotNetRelease.NOTFOUND;
    }
    public static int GetVersion()
    {
        int release = 0;
        using (RegistryKey key = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32)
                                            .OpenSubKey("SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4\\Full\\"))
        {
            release = Convert.ToInt32(key.GetValue("Release"));
        }
        return release;
    }
}
나중에 새 버전을 추가 할 때 쉽게 확장 할 수 있습니다. 나는 4.5 이전에 아무것도 신경 쓰지 않았지만 아이디어를 얻었습니다.
