답변
이런 식으로해야합니다. 레지스트리에서 값을 가져옵니다.
.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 --info
Enter
그리고 .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 이전에 아무것도 신경 쓰지 않았지만 아이디어를 얻었습니다.