关于c#:有没有简单的方法来检查.NET Framework版本?

Is there an easy way to check the .NET Framework version?

问题是我需要知道它是否是3.5sp 1版本。Environment.Version()只返回2.0.50727.3053

我找到了这个解决方案,但我认为它需要的时间比它的价值多得多,所以我正在寻找一个更简单的解决方案。有可能吗?


像这样的事情应该可以做到。只需从注册表中获取值

对于.NET 1-4:

Framework是最高安装版本,SP是该版本的服务包。

1
2
3
4
5
6
7
RegistryKey installed_versions = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft
ET Framework Setup
DP"
);
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+(来自官方文档):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
using System;
using Microsoft.Win32;


...


private static void Get45or451FromRegistry()
{
    using (RegistryKey ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey("SOFTWARE\\Microsoft\
ET Framework Setup\
DP\\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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
private static void GetVersionFromRegistry()
{
     // Opens the registry key for the .NET Framework entry.
        using (RegistryKey ndpKey =
            RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine,"").
            OpenSubKey(@"SOFTWARE\Microsoft
ET Framework Setup
DP"
))
        {
            // 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
ET Framework Setup
DP"))
        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及更高版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// 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\
ET Framework Setup\
DP\\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.");
      }
    }
}


另一种不需要访问注册表权限的方法是检查特定框架更新中引入的类的存在性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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()给出了另一个问题的正确答案。在.NET 2.0、3和3.5中使用相同版本的clr。我想您可以检查GAC中是否有在每个后续版本中添加的库。


以前很容易,但微软决定做一个突破性的改变:在4.5版之前,每个版本的.NET都位于C:\Windows\Microsoft.NET\Framework下自己的目录中(子目录v1.0.3705, v1.1.4322, v2.0.50727, v3.0, v3.5v4.0.30319)。< BR>

从4.5版开始,这个版本已经改变了:每个.NET版本(即4.5.x、4.6.x、4.7.x)都安装在同一个子目录v4.0.30319中,因此您不再能够通过查看Microsoft.NET\Framework来检查已安装的.NET版本。

为了检查.NET版本,Microsoft提供了两个不同的示例脚本,具体取决于正在检查的.NET版本,但我不喜欢为此使用两个不同的C脚本。所以我尝试将它们组合成一个,这是我创建的脚本(并为4.7.1框架更新了它):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
using System;
using Microsoft.Win32;
public class GetDotNetVersion
{
    public static void Main()
    {
        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
ET Framework Setup
DP\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 >= 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";
    }

    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
ET Framework Setup
DP"
))
        {
            // 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
ET Framework Setup
DP"))
            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

在我的机器上,它输出:

0

随着时间的推移,唯一需要维护的是.NET版本大于4.7.1时的内部版本号——这可以通过修改函数CheckFor45PlusVersion轻松完成,您需要知道新版本的发布密钥,然后才能添加它。例如:

1
if (releaseKey >= 461308) return"4.7.1 or later";

此发布密钥仍然是最新版本,对Windows10的秋季创建者更新有效。如果您仍在运行其他(旧版)Windows版本,则根据Microsoft的此文档,还有另一个版本:

.NET Framework 4.7.1 installed on all other Windows OS versions 461310

所以,如果你也需要的话,你必须补充

2

到函数CheckFor45PlusVersion的顶部。同样,它也适用于较新版本。例如,我最近添加了4.7.2的检查。您通常可以在Microsoft上找到这些内部版本号。

注意:您不需要安装Visual Studio,甚至不需要安装PowerShell—您可以使用csc.exe来编译和运行上面的脚本,我在这里已经介绍过。

更新:问题是关于.NET框架,为了完整起见,我想介绍一下如何查询.NET核心的版本-与上面的相比,这很容易:打开命令shell并键入:

dotnet --info Enter

它还将列出.NET核心版本号、Windows版本以及每个相关运行时dll的版本。样品输出:

.NET Core SDK (reflecting any global.json):

  Version: 2.1.300

  Commit: adab45bf0c

Runtime Environment:

  OS Name: Windows

  OS Version: 10.0.15063

  OS Platform: Windows

  RID: win10-x64

  Base Path: C:\Program Files\dotnet\sdk\2.1.300\

Host (useful for support):

  Version: 2.1.0

  Commit: caa7b7e2ba

.NET Core SDKs installed:

  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 runtimes installed:

  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]

To install additional .NET Core runtimes or SDKs:

  https://aka.ms/dotnet-download


Afaik框架中没有内置方法允许您这样做。您可以查看本文,了解通过读取Windows注册表值来确定框架版本的建议。


如果找不到正确的.NET版本,这个类允许应用程序抛出一条优美的通知消息,而不是崩溃并烧掉。您需要做的就是在您的主代码中这样做:

1
2
3
4
5
6
7
[STAThread]
static void Main(string[] args)
{
    if (!DotNetUtils.IsCompatible())
        return;
   . . .
}

默认情况下,它需要4.5.2,但您可以根据自己的喜好对类进行调整(可以随意用控制台替换MessageBox):

更新4.8:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
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\
ET Framework Setup\
DP\\v4\\Full\"))
        {
            release = Convert.ToInt32(key.GetValue("
Release"));
        }
        return release;
    }
}

在以后添加新版本时可以轻松扩展。4点5分之前我什么都没做,但你知道。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
public class DA
{
    public static class VersionNetFramework
    {
        public static string GetVersion()
        {
            return Environment.Version.ToString();
        }
        public static string GetVersionDicription()
        {
            int Major = Environment.Version.Major;
            int Minor = Environment.Version.Minor;
            int Build = Environment.Version.Build;
            int Revision = Environment.Version.Revision;

            //http://dzaebel.net/NetVersionen.htm
            //http://stackoverflow.com/questions/12971881/how-to-reliably-detect-the-actual-net-4-5-version-installed

            //4.0.30319.42000 = .NET 4.6 on Windows 8.1 64 - bit
            if ((Major >=4) && (Minor >=0) && (Build >= 30319) && (Revision >= 42000))
                return @".NET 4.6 on Windows 8.1 64 - bit or later";
            //4.0.30319.34209 = .NET 4.5.2 on Windows 8.1 64 - bit
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 34209))
                return @".NET 4.5.2 on Windows 8.1 64 - bit or later";
            //4.0.30319.34209 = .NET 4.5.2 on Windows 7 SP1 64 - bit
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 34209))
                return @".NET 4.5.2 on Windows 7 SP1 64 - bit or later";
            //4.0.30319.34014 = .NET 4.5.1 on Windows 8.1 64 - bit
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 34014))
                return @".NET 4.5.1 on Windows 8.1 64 - bit or later";
            //4.0.30319.18444 = .NET 4.5.1 on Windows 7 SP1 64 - bit(with MS14 - 009 security update)
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 18444))
                return @".NET 4.5.1 on Windows 7 SP1 64 - bit(with MS14 - 009 security update) or later";
            //4.0.30319.18408 = .NET 4.5.1 on Windows 7 SP1 64 - bit
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 18408))
                return @".NET 4.5.1 on Windows 7 SP1 64 - bit or later";
            //4.0.30319.18063 = .NET 4.5 on Windows 7 SP1 64 - bit(with MS14 - 009 security update)
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 18063))
                return @".NET 4.5 on Windows 7 SP1 64 - bit(with MS14 - 009 security update) or later";
            //4.0.30319.18052 = .NET 4.5 on Windows 7 SP1 64 - bit
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 18052))
                return @".NET 4.5 on Windows 7 SP1 64 - bit or later";
            //4.0.30319.18010 = .NET 4.5 on Windows 8
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 18010))
                return @".NET 4.5 on Windows 8 or later";
            //4.0.30319.17929 = .NET 4.5 RTM
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 17929))
                return @".NET 4.5 RTM or later";
            //4.0.30319.17626 = .NET 4.5 RC
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 17626))
                return @".NET 4.5 RC or later";
            //4.0.30319.17020.NET 4.5 Preview, September 2011
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 17020))
                return @".NET 4.5 Preview, September 2011 or later";
            //4.0.30319.2034 = .NET 4.0 on Windows XP SP3, 7, 7 SP1(with MS14 - 009 LDR security update)
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 2034))
                return @".NET 4.0 on Windows XP SP3, 7, 7 SP1(with MS14 - 009 LDR security update) or later";
            //4.0.30319.1026 = .NET 4.0 on Windows XP SP3, 7, 7 SP1(with MS14 - 057 GDR security update)
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 1026))
                return @".NET 4.0 on Windows XP SP3, 7, 7 SP1(with MS14 - 057 GDR security update) or later";
            //4.0.30319.1022 = .NET 4.0 on Windows XP SP3, 7, 7 SP1(with MS14 - 009 GDR security update)
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 1022))
                return @".NET 4.0 on Windows XP SP3, 7, 7 SP1(with MS14 - 009 GDR security update) or later";
            //4.0.30319.1008 = .NET 4.0 on Windows XP SP3, 7, 7 SP1(with MS13 - 052 GDR security update)
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 1008))
                return @".NET 4.0 on Windows XP SP3, 7, 7 SP1(with MS13 - 052 GDR security update) or later";
            //4.0.30319.544 = .NET 4.0 on Windows XP SP3, 7, 7 SP1(with MS12 - 035 LDR security update)
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 544))
                return @".NET 4.0 on Windows XP SP3, 7, 7 SP1(with MS12 - 035 LDR security update) or later";
            //4.0.30319.447   yes built by: RTMLDR, .NET 4.0 Platform Update 1, April 2011
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 447))
                return @"built by: RTMLDR, .NET 4.0 Platform Update 1, April 2011 or later";
            //4.0.30319.431   yes built by: RTMLDR, .NET 4.0 GDR Update, March 2011 / with VS 2010 SP1 / or.NET 4.0 Update
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 431))
                return @"built by: RTMLDR, .NET 4.0 GDR Update, March 2011 / with VS 2010 SP1 / or.NET 4.0 Update or later";
            //4.0.30319.296 = .NET 4.0 on Windows XP SP3, 7(with MS12 - 074 GDR security update)
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 296))
                return @".NET 4.0 on Windows XP SP3, 7(with MS12 - 074 GDR security update) or later";
            //4.0.30319.276 = .NET 4.0 on Windows XP SP3 (4.0.3 Runtime update)
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 276))
                return @".NET 4.0 on Windows XP SP3 (4.0.3 Runtime update) or later";
            //4.0.30319.269 = .NET 4.0 on Windows XP SP3, 7, 7 SP1(with MS12 - 035 GDR security update)
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 269))
                return @".NET 4.0 on Windows XP SP3, 7, 7 SP1(with MS12 - 035 GDR security update) or later";
            //4.0.30319.1 yes built by: RTMRel, .NET 4.0 RTM Release, April 2010
            if ((Major >= 4) && (Minor >= 0) && (Build >= 30319) && (Revision >= 1))
                return @"built by: RTMRel, .NET 4.0 RTM Release, April 2010 or later";

            //4.0.30128.1     built by: RC1Rel, .NET 4.0 Release Candidate, Feb 2010
            if ((Major >=4) && (Minor >=0) && (Build >= 30128) && (Revision >= 1))
                return @"built by: RC1Rel, .NET 4.0 Release Candidate, Feb 2010 or later";
            //4.0.21006.1     built by: B2Rel, .NET 4.0 Beta2, Oct 2009
            if ((Major >=4) && (Minor >=0) && (Build >= 21006) && (Revision >=1))
                return @"built by: B2Rel, .NET 4.0 Beta2, Oct 2009 or later";
            //4.0.20506.1     built by: Beta1, .NET 4.0 Beta1, May 2009
            if ((Major >=4) && (Minor >=0) && (Build >= 20506) && (Revision >=1))
                return @"built by: Beta1, .NET 4.0 Beta1, May 2009 or later";
            //4.0.11001.1     built by: CTP2 VPC, .NET 4.0 CTP, October 2008
            if ((Major >=4) && (Minor >=0) && (Build >= 11001) && (Revision >=1))
                return @"built by: CTP2 VPC, .NET 4.0 CTP, October 2008 or later";

            //3.5.30729.5420  yes built by: Win7SP1, .NET 3.5.1 Sicherheits - Update, 12 April 2011
            if ((Major >=3) && (Minor >=5) && (Build >= 30729) && (Revision >= 5420))
                return @"built by: Win7SP1, .NET 3.5.1 Sicherheits - Update, 12 April 2011 or later";
            //3.5.30729.5004  yes built by: NetFXw7 / Windows 7..Rel., Jan 2010 / +Data functions KB976127 .NET 3.5 SP1
            if ((Major >=3) && (Minor >=5) && (Build >= 30729) && (Revision >= 5004))
                return @"built by: NetFXw7 / Windows 7..Rel., Jan 2010 / +Data functions KB976127 .NET 3.5 SP1 or later";
            //3.5.30729.4466  yes built by: NetFXw7 / Windows XP..Rel. , Jan 2010 / +Data functions KB976127 .NET 3.5 SP1
            if ((Major >=3) && (Minor >=5) && (Build >= 30729) && (Revision >= 4466))
                return @"built by: NetFXw7 / Windows XP..Rel. , Jan 2010 / +Data functions KB976127 .NET 3.5 SP1 or later";
            //3.5.30729.4926  yes built by: NetFXw7 / Windows 7 Release, Oct 2009 / .NET 3.5 SP1 + Hotfixes
            if ((Major >=3) && (Minor >=5) && (Build >= 30729) && (Revision >= 4926))
                return @"built by: NetFXw7 / Windows 7 Release, Oct 2009 / .NET 3.5 SP1 + Hotfixes or later";
            //3.5.30729.4918      built by: NetFXw7 / Windows 7 Release Candidate, June 2009
            if ((Major >=3) && (Minor >=5) && (Build >= 30729) && (Revision >= 4918))
                return @"built by: NetFXw7 / Windows 7 Release Candidate, June 2009 or later";
            //3.5.30729.196   yes built by: QFE, .NET 3.5 Family Update Vista / W2008, Dec 2008
            if ((Major >= 3) && (Minor >= 5) && (Build >= 30729) && (Revision >=196))
                return @"built by: QFE, .NET 3.5 Family Update Vista / W2008, Dec 2008 or later";
            //3.5.30729.1 yes built by: SP, .NET 3.5 SP1, Aug 2008
            if ((Major >= 3) && (Minor >= 5) && (Build >= 30729) && (Revision >=1))
                return @"built by: SP, .NET 3.5 SP1, Aug 2008 or later";

            //3.5.30428.1         built by: SP1Beta1, .NET 3.5 SP1 BETA1, May 2008
            if ((Major >=3) && (Minor >=5) && (Build >= 30428) && (Revision >=1))
                return @"built by: SP1Beta1, .NET 3.5 SP1 BETA1, May 2008 or later";
            //3.5.21022.8 yes built by: RTM, Jan 2008
            if ((Major >=3) && (Minor >=5) && (Build >= 21022) && (Revision >= 8))
                return @"built by: RTM, Jan 2008 or later";
            //3.5.20706.1     built by: Beta2, Orcas Beta2, Oct 2007
            if ((Major >=3) && (Minor >=5) && (Build >= 20706) && (Revision >= 1))
                return @"built by: Beta2, Orcas Beta2, Oct 2007 or later";
            //3.5.20526.0     built by: MCritCTP, Orcas Beta1, Mar 2007
            if ((Major >=3) && (Minor >=5) && (Build >= 20526) && (Revision >=0))
                return @"built by: MCritCTP, Orcas Beta1, Mar 2007 or later";

            //3.0.6920.1500   yes built by: QFE, Family Update Vista / W2008, Dez 2008, KB958483
            if ((Major >=3) && (Minor >=0) && (Build >= 6920) && (Revision >= 1500))
                return @"built by: QFE, Family Update Vista / W2008, Dez 2008, KB958483 or later";
            //3.0.4506.4926   yes(NetFXw7.030729 - 4900) / Windows 7 Release, Oct 2009
            if ((Major >=3) && (Minor >=0) && (Build >= 4506) && (Revision >= 4926))
                return @"(NetFXw7.030729 - 4900) / Windows 7 Release, Oct 2009 or later";
            //3.0.4506.4918(NetFXw7.030729 - 4900) / Windows 7 Release Candidate, June 2009
            if ((Major >=3) && (Minor >=5) && (Build >= 4506) && (Revision >= 4918))
                return @"(NetFXw7.030729 - 4900) / Windows 7 Release Candidate, June 2009 or later";
            //3.0.4506.2152       3.0.4506.2152(SP.030729 - 0100) / .NET 4.0 Beta1 / May 2009
            if ((Major >= 3) && (Minor >= 5) && (Build >= 4506) && (Revision >= 2152))
                return @"3.0.4506.2152(SP.030729 - 0100) / .NET 4.0 Beta1 / May 2009 or later";
            //3.0.4506.2123   yes(NetFX.030618 - 0000).NET 3.0 SP2, Aug 2008
            if ((Major >= 3) && (Minor >= 5) && (Build >= 4506) && (Revision >= 2123))
                return @"s(NetFX.030618 - 0000).NET 3.0 SP2, Aug 2008 or later";
            //3.0.4506.2062(SP1Beta1.030428 - 0100), .NET 3.0 SP1 BETA1, May 2008
            if ((Major >= 3) && (Minor >= 5) && (Build >= 4506) && (Revision >= 2062))
                return @"(SP1Beta1.030428 - 0100), .NET 3.0 SP1 BETA1, May 2008 or later";
            //3.0.4506.590(winfxredb2.004506 - 0590), Orcas Beta2, Oct 2007
            if ((Major >= 3) && (Minor >= 5) && (Build >= 4506) && (Revision >= 590))
                return @"(winfxredb2.004506 - 0590), Orcas Beta2, Oct 2007 or later";
            //3.0.4506.577(winfxred.004506 - 0577), Orcas Beta1, Mar 2007
            if ((Major >= 3) && (Minor >= 5) && (Build >= 4506) && (Revision >= 577))
                return @"(winfxred.004506 - 0577), Orcas Beta1, Mar 2007 or later";
            //3.0.4506.30 yes Release (.NET Framework 3.0) Nov 2006
            if ((Major >= 3) && (Minor >= 5) && (Build >= 4506) && (Revision >= 30))
                return @"Release (.NET Framework 3.0) Nov 2006 or later";
            //3.0.4506.25 yes(WAPRTM.004506 - 0026) Vista Ultimate, Jan 2007
            if ((Major >= 3) && (Minor >= 5) && (Build >= 4506) && (Revision >= 25))
                return @"(WAPRTM.004506 - 0026) Vista Ultimate, Jan 2007 or later";

            //2.0.50727.4927  yes(NetFXspW7.050727 - 4900) / Windows 7 Release, Oct 2009
            if ((Major >=2) && (Minor >=0) && (Build >= 50727) && (Revision >= 4927))
                return @"(NetFXspW7.050727 - 4900) / Windows 7 Release, Oct 2009 or later";
            //2.0.50727.4918(NetFXspW7.050727 - 4900) / Windows 7 Release Candidate, June 2009
            if ((Major >= 2) && (Minor >= 0) && (Build >= 50727) && (Revision >= 4918))
                return @"(NetFXspW7.050727 - 4900) / Windows 7 Release Candidate, June 2009 or later";
            //2.0.50727.4200  yes(NetFxQFE.050727 - 4200).NET 2.0 SP2, KB974470, Securityupdate, Oct 2009
            if ((Major >= 2) && (Minor >= 0) && (Build >= 50727) && (Revision >= 4200))
                return @"(NetFxQFE.050727 - 4200).NET 2.0 SP2, KB974470, Securityupdate, Oct 2009 or later";
            //2.0.50727.3603(GDR.050727 - 3600).NET 4.0 Beta 2, Oct 2009
            if ((Major >= 2) && (Minor >= 0) && (Build >= 50727) && (Revision >= 3603))
                return @"(GDR.050727 - 3600).NET 4.0 Beta 2, Oct 2009 or later";
            //2.0.50727.3082  yes(QFE.050727 - 3000), .NET 3.5 Family Update XP / W2003, Dez 2008, KB958481
            if ((Major >= 2) && (Minor >= 0) && (Build >= 50727) && (Revision >= 3082))
                return @"(QFE.050727 - 3000), .NET 3.5 Family Update XP / W2003, Dez 2008, KB958481 or later";
            //2.0.50727.3074  yes(QFE.050727 - 3000), .NET 3.5 Family Update Vista / W2008, Dez 2008, KB958481
            if ((Major >= 2) && (Minor >= 0) && (Build >= 50727) && (Revision >= 3074))
                return @"(QFE.050727 - 3000), .NET 3.5 Family Update Vista / W2008, Dez 2008, KB958481 or later";
            //2.0.50727.3053  yes(netfxsp.050727 - 3000), .NET 2.0 SP2, Aug 2008
            if ((Major >= 2) && (Minor >= 0) && (Build >= 50727) && (Revision >= 3053))
                return @"yes(netfxsp.050727 - 3000), .NET 2.0 SP2, Aug 2008 or later";
            //2.0.50727.3031(netfxsp.050727 - 3000), .NET 2.0 SP2 Beta 1, May 2008
            if ((Major >= 2) && (Minor >= 0) && (Build >= 50727) && (Revision >= 3031))
                return @"(netfxsp.050727 - 3000), .NET 2.0 SP2 Beta 1, May 2008 or later";
            //2.0.50727.1434  yes(REDBITS.050727 - 1400), Windows Server 2008 and Windows Vista SP1, Dez 2007
            if ((Major >= 2) && (Minor >= 0) && (Build >= 50727) && (Revision >= 1434))
                return @"(REDBITS.050727 - 1400), Windows Server 2008 and Windows Vista SP1, Dez 2007 or later";
            //2.0.50727.1433  yes(REDBITS.050727 - 1400), .NET 2.0 SP1 Release, Nov 2007, http://www.microsoft.com/downloads/details.aspx?FamilyID=79bc3b77-e02c-4ad3-aacf-a7633f706ba5
            if ((Major >= 2) && (Minor >= 0) && (Build >= 50727) && (Revision >= 1433))
                return @"(REDBITS.050727 - 1400), .NET 2.0 SP1 Release, Nov 2007 or later";
            //2.0.50727.1378(REDBITSB2.050727 - 1300), Orcas Beta2, Oct 2007
            if ((Major >= 2) && (Minor >= 0) && (Build >= 50727) && (Revision >= 1378))
                return @"(REDBITSB2.050727 - 1300), Orcas Beta2, Oct 2007 or later";
            //2.0.50727.1366(REDBITS.050727 - 1300), Orcas Beta1, Mar 2007
            if ((Major >= 2) && (Minor >= 0) && (Build >= 50727) && (Revision >= 1366))
                return @"(REDBITS.050727 - 1300), Orcas Beta1, Mar 2007 or later";
            //2.0.50727.867   yes(VS Express Edition 2005 SP1), Apr 2007, http://www.microsoft.com/downloads/details.aspx?FamilyId=7B0B0339-613A-46E6-AB4D-080D4D4A8C4E
            if ((Major >= 2) && (Minor >= 0) && (Build >= 50727) && (Revision >= 867))
                return @"(VS Express Edition 2005 SP1), Apr 2007 or later";
            //2.0.50727.832(Fix x86 VC++2005), Apr 2007, http://support.microsoft.com/kb/934586/en-us
            if ((Major >= 2) && (Minor >= 0) && (Build >= 50727) && (Revision >= 832))
                return @"(Fix x86 VC++2005), Apr 2007 or later";
            //2.0.50727.762   yes(VS TeamSuite SP1), http://www.microsoft.com/downloads/details.aspx?FamilyId=BB4A75AB-E2D4-4C96-B39D-37BAF6B5B1DC
            if ((Major >= 2) && (Minor >= 0) && (Build >= 50727) && (Revision >= 762))
                return @"(VS TeamSuite SP1) or later";
            //2.0.50727.312   yes(rtmLHS.050727 - 3100) Vista Ultimate, Jan 2007
            if ((Major >= 2) && (Minor >= 0) && (Build >= 50727) && (Revision >= 312))
                return @"(rtmLHS.050727 - 3100) Vista Ultimate, Jan 2007 or later";
            //2.0.50727.42    yes Release (.NET Framework 2.0) Oct 2005
            if ((Major >= 2) && (Minor >= 0) && (Build >= 50727) && (Revision >= 42))
                return @"Release (.NET Framework 2.0) Oct 2005 or later";
            //2.0.50727.26        Version 2.0(Visual Studio Team System 2005 Release Candidate) Oct 2005
            if ((Major >= 2) && (Minor >= 0) && (Build >= 50727) && (Revision >= 26))
                return @"Version 2.0(Visual Studio Team System 2005 Release Candidate) Oct 2005 or later";

            //2.0.50712       Version 2.0(Visual Studio Team System 2005(Drop3) CTP) July 2005
            if ((Major >=2) && (Minor >=0) && (Build >= 50712))
                return @"Version 2.0(Visual Studio Team System 2005(Drop3) CTP) July 2005 or later";
            //2.0.50215       Version 2.0(WinFX SDK for Indigo / Avalon 2005 CTP) July 2005
            if ((Major >=2) && (Minor >=0) && (Build >= 50215))
                return @"Version 2.0(WinFX SDK for Indigo / Avalon 2005 CTP) July 2005 or later";
            //2.0.50601.0     Version 2.0(Visual Studio.NET 2005 CTP) June 2005
            if ((Major >=2) && (Minor >=0) && (Build >= 50601) && (Revision >=0))
                return @"Version 2.0(Visual Studio.NET 2005 CTP) June 2005 or later";
            //2.0.50215.44        Version 2.0(Visual Studio.NET 2005 Beta 2, Visual Studio Express Beta 2) Apr 2005
            if ((Major >=2) && (Minor >=0) && (Build >= 50215) && (Revision >= 44))
                return @"Version 2.0(Visual Studio.NET 2005 Beta 2, Visual Studio Express Beta 2) Apr 2005 or later";
            //2.0.50110.28        Version 2.0(Visual Studio.NET 2005 CTP, Professional Edition) Feb 2005
            if ((Major >=2) && (Minor >=0) && (Build >= 50110) && (Revision >=28))
                return @"Version 2.0(Visual Studio.NET 2005 CTP, Professional Edition) Feb 2005 or later";
            //2.0.41115.19        Version 2.0(Visual Studio.NET 2005 Beta 1, Team System Refresh) Dec 2004
            if ((Major >=2 ) && (Minor >=0 ) && (Build >= 41115) && (Revision >= 19))
                return @"Version 2.0(Visual Studio.NET 2005 Beta 1, Team System Refresh) Dec 2004 or later";
            //2.0.40903.0         Version 2.0(Whidbey CTP, Visual Studio Express) Oct 2004
            if ((Major >=2) && (Minor >=0) && (Build >= 40903) && (Revision >=0))
                return @"Version 2.0(Whidbey CTP, Visual Studio Express) Oct 2004 or later";
            //2.0.40607.85        Version 2.0(Visual Studio.NET 2005 Beta 1, Team System Refresh) Aug 2004 *
            if ((Major >=2) && (Minor >=0) && (Build >= 40607) && (Revision >= 85))
                return @"Version 2.0(Visual Studio.NET 2005 Beta 1, Team System Refresh) Aug 2004 * or later";
            //2.0.40607.42        Version 2.0(SQL Server Yukon Beta 2) July 2004
            if ((Major >=2) && (Minor >=0) && (Build >= 40607) && (Revision >= 42))
                return @"Version 2.0(SQL Server Yukon Beta 2) July 2004 or later";
            //2.0.40607.16        Version 2.0(Visual Studio.NET 2005 Beta 1, TechEd Europe 2004) June 2004
            if ((Major >=2) && (Minor >=0) && (Build >= 40607) && (Revision >= 16))
                return @"Version 2.0(Visual Studio.NET 2005 Beta 1, TechEd Europe 2004) June 2004 or later";
            //2.0.40301.9         Version 2.0(Whidbey CTP, WinHEC 2004) March 2004 *
            if ((Major >=0) && (Minor >=0) && (Build >= 40301) && (Revision >=9))
                return @"Version 2.0(Whidbey CTP, WinHEC 2004) March 2004 * or later";

            //1.2.30703.27        Version 1.2(Whidbey Alpha, PDC 2004) Nov 2003 *
            if ((Major >=1) && (Minor >=2) && (Build >= 30703) && (Revision >= 27))
                return @"Version 1.2(Whidbey Alpha, PDC 2004) Nov 2003 * or later";
            //1.2.21213.1     Version 1.2(Whidbey pre - Alpha build) *
            if ((Major >=1) && (Minor >=2) && (Build >= 21213) && (Revision >=1))
                return @"Version 1.2(Whidbey pre - Alpha build) * or later";

            //1.1.4322.2443   yes Version 1.1 Servicepack 1, KB953297, Oct 2009
            if ((Major >=1) && (Minor >=1) && (Build >= 4322) && (Revision >=2443))
                return @"Version 1.1 Servicepack 1, KB953297, Oct 2009 or later";
            //1.1.4322.2407   yes Version 1.1 RTM
            if ((Major >=1) && (Minor >=1) && (Build >= 4322) && (Revision >= 2407))
                return @"Version 1.1 RTM or later";
            //1.1.4322.2407       Version 1.1 Orcas Beta2, Oct 2007
            if ((Major >=1) && (Minor >=1) && (Build >= 4322) && (Revision >= 2407))
                return @"Version 1.1 Orcas Beta2, Oct 2007 or later";
            //1.1.4322.2379       Version 1.1 Orcas Beta1, Mar 2007
            if ((Major >=1) && (Minor >=1) && (Build >= 4322) && (Revision >= 2379))
                return @"Version 1.1 Orcas Beta1, Mar 2007 or later";
            //1.1.4322.2032   yes Version 1.1 SP1 Aug 2004
            if ((Major >=1) && (Minor >=1) && (Build >= 4322) && (Revision >= 2032))
                return @"Version 1.1 SP1 Aug 2004 or later";
            //1.1.4322.573    yes Version 1.1 RTM(Visual Studio.NET 2003 / Windows Server 2003) Feb 2003 *
            if ((Major >=1) && (Minor >=1) && (Build >= 4322) && (Revision >= 573))
                return @"Version 1.1 RTM(Visual Studio.NET 2003 / Windows Server 2003) Feb 2003 * or later";
            //1.1.4322.510        Version 1.1 Final Beta Oct 2002 *
            if ((Major >=1) && (Minor >=1) && (Build >= 4322) && (Revision >= 510))
                return @"Version 1.1 Final Beta Oct 2002 * or later";

            //1.0.3705.6018   yes Version 1.0 SP3 Aug 2004
            if ((Major >=1) && (Minor >=0) && (Build >= 3705) && (Revision >= 6018))
                return @"Version 1.0 SP3 Aug 2004 or later";
            //1.0.3705.288    yes Version 1.0 SP2 Aug 2002 *
            if ((Major >=1) && (Minor >=0) && (Build >= 3705) && (Revision >= 288))
                return @"Version 1.0 SP2 Aug 2002 * or later";
            //1.0.3705.209    yes Version 1.0 SP1 Mar 2002 *
            if ((Major >=1) && (Minor >=0) && (Build >= 3705) && (Revision >=209))
                return @"Version 1.0 SP1 Mar 2002 * or later";
            //1.0.3705.0  yes Version 1.0 RTM(Visual Studio.NET 2002) Feb 2002 *
            if ((Major >=1) && (Minor >=0) && (Build >= 3705) && (Revision >=0))
                return @"Version 1.0 RTM(Visual Studio.NET 2002) Feb 2002 * or later";
            //1.0.3512.0      Version 1.0 Pre - release RC3(Visual Studio.NET 2002 RC3)
            if ((Major >=1) && (Minor >=0) && (Build >= 3512) && (Revision >=0))
                return @"Version 1.0 Pre - release RC3(Visual Studio.NET 2002 RC3) or later";
            //1.0.2914.16     Version 1.0 Public Beta 2 Jun 2001 *
            if ((Major >=1) && (Minor >=0) && (Build >= 2914) && (Revision >= 16))
                return @"Version 1.0 Public Beta 2 Jun 2001 * or later";
            //1.0.2204.21         Version 1.0 Public Beta 1 Nov 2000 *
            if ((Major >=1) && (Minor >=0) && (Build >= 2204) && (Revision >=21))
                return @"Version 1.0 Public Beta 1 Nov 2000 * or later";

            return @"Unknown .NET version";
        }
    }
}


谢谢你的这篇文章,它非常有用。为了检查Framework2.0,我不得不稍微调整一下,因为注册表项不能直接转换为double。代码如下:

2


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
public class DA {
  public static class VersionNetFramework {
    public static string Get45or451FromRegistry()
    {//https://msdn.microsoft.com/en-us/library/hh925568(v=vs.110).aspx
        using (RegistryKey ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey("SOFTWARE\\Microsoft\
ET Framework Setup\
DP\\v4\\Full\"))
        {
            int releaseKey = Convert.ToInt32(ndpKey.GetValue("
Release"));
            if (true)
            {
                return (@"
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)
    {//https://msdn.microsoft.com/en-us/library/hh925568(v=vs.110).aspx
        if (releaseKey >= 394271)
            return"
4.6.1 installed on all other Windows OS versions or later";
        if (releaseKey >= 394254)
            return"
4.6.1 installed on Windows 10 or later";
        if (releaseKey >= 393297)
            return"
4.6 installed on all other Windows OS versions or later";
        if (releaseKey >= 393295)
            return"
4.6 installed with Windows 10 or later";
        if (releaseKey >= 379893)
            return"
4.5.2 or later";
        if (releaseKey >= 378758)
            return"
4.5.1 installed on Windows 8, Windows 7 SP1, or Windows Vista SP2 or later";
        if (releaseKey >= 378675)
            return"
4.5.1 installed with Windows 8.1 or later";
        if (releaseKey >= 378389)
            return"
4.5 or later";

        return"
No 4.5 or later version detected";
    }
    public static string GetVersionFromRegistry()
    {//https://msdn.microsoft.com/en-us/library/hh925568(v=vs.110).aspx
        string res = @"
";
        // Opens the registry key for the .NET Framework entry.
        using (RegistryKey ndpKey =
            RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine,"
").
            OpenSubKey(@"
SOFTWARE\Microsoft
ET Framework Setup
DP"))
        {
            // 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
ET Framework Setup
DP"))
            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.
                        res += (versionKeyName +"
" + name) + Environment.NewLine;
                    else
                    {
                        if (sp !="
" && install =="1")
                        {
                            res += (versionKeyName +"
" + name +"  SP" + sp) + Environment.NewLine;
                        }

                    }
                    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.
                            res += (versionKeyName +"
" + name) + Environment.NewLine;
                        else
                        {
                            if (sp !="
" && install =="1")
                            {
                                res += ("
" + subKeyName +" " + name +"  SP" + sp) + Environment.NewLine;
                            }
                            else if (install =="
1")
                            {
                                res += ("
" + subKeyName +" " + name) + Environment.NewLine;
                            }
                        }
                    }
                }
            }
        }
        return res;
    }
    public static string GetUpdateHistory()
    {//https://msdn.microsoft.com/en-us/library/hh925567(v=vs.110).aspx
        string res=@"
";
        using (RegistryKey baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey(@"
SOFTWARE\Microsoft\Updates"))
        {
            foreach (string baseKeyName in baseKey.GetSubKeyNames())
            {
                if (baseKeyName.Contains("
.NET Framework") || baseKeyName.StartsWith("KB") || baseKeyName.Contains(".NETFramework"))
                {

                    using (RegistryKey updateKey = baseKey.OpenSubKey(baseKeyName))
                    {
                        string name = (string)updateKey.GetValue("
PackageName","");
                        res += baseKeyName +"
" + name + Environment.NewLine;
                        foreach (string kbKeyName in updateKey.GetSubKeyNames())
                        {
                            using (RegistryKey kbKey = updateKey.OpenSubKey(kbKeyName))
                            {
                                name = (string)kbKey.GetValue("
PackageName","");
                                res += ("
" + kbKeyName +" " + name) + Environment.NewLine;

                                if (kbKey.SubKeyCount > 0)
                                {
                                    foreach (string sbKeyName in kbKey.GetSubKeyNames())
                                    {
                                        using (RegistryKey sbSubKey = kbKey.OpenSubKey(sbKeyName))
                                        {
                                            name = (string)sbSubKey.GetValue("
PackageName","");
                                            if (name =="
")
                                                name = (string)sbSubKey.GetValue("
Description","");
                                            res += ("
  " + sbKeyName +" " + name) + Environment.NewLine;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        return res;
    }
}

使用类da.versionNetFramework

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
private void Form1_Shown(object sender, EventArgs e)
{
    //
    // Current OS Information
    //
    richTextBox1.Text = @"Current OS Information:";
    richTextBox1.AppendText(Environment.NewLine +
                           "Machine Name:" + Environment.MachineName);
    richTextBox1.AppendText(Environment.NewLine +
                           "Platform:" + Environment.OSVersion.Platform.ToString());
    richTextBox1.AppendText(Environment.NewLine +
                            Environment.OSVersion);
    //
    // .NET Framework Environment Information
    //
    richTextBox1.AppendText(Environment.NewLine + Environment.NewLine +
                                      ".NET Framework Environment Information:");
    richTextBox1.AppendText(Environment.NewLine +
                           "Environment.Version" + Environment.Version);
    richTextBox1.AppendText(Environment.NewLine +
                            DA.VersionNetFramework.GetVersionDicription());
    //
    // .NET Framework Information From Registry
    //
    richTextBox1.AppendText(Environment.NewLine + Environment.NewLine +
                                      ".NET Framework Information From Registry:");
    richTextBox1.AppendText(Environment.NewLine +
                            DA.VersionNetFramework.GetVersionFromRegistry());
    //
    // .NET Framework 4.5 or later Information From Registry
    //
    richTextBox1.AppendText(Environment.NewLine +
                                      ".NET Framework 4.5 or later Information From Registry:");
    richTextBox1.AppendText(Environment.NewLine +
                            DA.VersionNetFramework.Get45or451FromRegistry());
    //
    // Update History
    //
    richTextBox1.AppendText(Environment.NewLine + Environment.NewLine +
                           "Update History");
    richTextBox1.AppendText(Environment.NewLine +
                            DA.VersionNetFramework.GetUpdateHistory());
    //
    // Setting Cursor to first character of textbox
    //
    if (!richTextBox1.Text.Equals(""))
    {
        richTextBox1.SelectionStart = 1;
    }
}

结果:

当前操作系统信息:机台名称:D1平台:win32ntMicrosoft Windows NT 6.2.9200.0版

.NET Framework环境信息:环境.4.0.30319.42000版Windows 8.1 64位或更高版本上的.NET 4.6

来自注册表的.NET Framework信息:V2.0.50727 2.0.50727.4927 SP2版v3.0 3.0.30729.4926 SP2版v3.5 3.5.30729.4926 SP1版

V4客户4.6.000794.6万V4.0客户端4.0.0.0

来自注册表的.NET Framework 4.5或更高版本信息:版本:4.6与Windows 10或更高版本一起安装

更新历史Microsoft.NET Framework 4客户端配置文件KB24688KB246871V2KB2478063KB2533523KB25445KB260211KB260217扩展的Microsoft.NET Framework 4KB24688KB246871V2KB2478063KB2533523KB25445KB260211KB260217Microsoft.NET Framework 4多目标包KB2504637更新(KB2504637)


我试图把所有的答案组合成一个整体。

使用:

此时,NetFrameworkUtilities.GetVersion()将返回当前可用的.NET框架版本,如果不存在,则返回空值。

此示例适用于.NET Framework 3.5+版本。它不需要管理员权限。

我要注意的是,您可以使用以下运算符检查版本:

4

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
using System;
using System.Linq;
using Microsoft.Win32;

namespace Utilities
{
    public static class NetFrameworkUtilities
    {
        public static Version GetVersion() => GetVersionHigher4() ?? GetVersionLowerOr4();

        private static Version GetVersionLowerOr4()
        {
            using (var key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft
ET Framework Setup
DP"
))
            {
                var names = key?.GetSubKeyNames();

                //version names start with 'v', eg, 'v3.5' which needs to be trimmed off before conversion
                var text = names?.LastOrDefault()?.Remove(0, 1);
                if (string.IsNullOrEmpty(text))
                {
                    return null;
                }

                return text.Contains('.')
                    ? new Version(text)
                    : new Version(Convert.ToInt32(text), 0);
            }
        }

        private static Version GetVersionHigher4()
        {
            using (var key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft
ET Framework Setup
DP\v4\Full"
))
            {
                var value = key?.GetValue("Release");
                if (value == null)
                {
                    return null;
                }

                // 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.
                var releaseKey = Convert.ToInt32(value);
                if (releaseKey >= 461308) return new Version(4, 7, 1);
                if (releaseKey >= 460798) return new Version(4, 7);
                if (releaseKey >= 394747) return new Version(4, 6, 2);
                if (releaseKey >= 394254) return new Version(4, 6, 1);
                if (releaseKey >= 381029) return new Version(4, 6);
                if (releaseKey >= 379893) return new Version(4, 5, 2);
                if (releaseKey >= 378675) return new Version(4, 5, 1);
                if (releaseKey >= 378389) return new Version(4, 5);

                // This line should never execute. A non-null release key should mean
                // that 4.5 or later is installed.
                return new Version(4, 5);
            }
        }
    }
}


我已经更改了Matt的类,这样它就可以在任何项目中重用,而无需在控制台上打印所有的检查,并返回一个简单的字符串,其中安装了正确的max版本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Win32;

namespace MyNamespace
{
    public class DotNetVersion
    {
        protected bool printVerification;

        public DotNetVersion(){
            this.printVerification=false;
        }
        public DotNetVersion(bool printVerification){
            this.printVerification=printVerification;
        }


        public string getDotNetVersion(){
            string maxDotNetVersion = getVersionFromRegistry();
            if(String.Compare(maxDotNetVersion,"4.5") >= 0){
                string v45Plus = get45PlusFromRegistry();
                if(!string.IsNullOrWhiteSpace(v45Plus)) maxDotNetVersion = v45Plus;
            }
            log("*** Maximum .NET version number found is:" + maxDotNetVersion +"***");

            return maxDotNetVersion;
        }

        protected string get45PlusFromRegistry(){
            String dotNetVersion ="";
            const string subkey = @"SOFTWARE\Microsoft
ET Framework Setup
DP\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"));
                    log(".NET Framework Version:" + dotNetVersion);
                }else{
                    log(".NET Framework Version 4.5 or later is not detected.");
                }
            }
            return dotNetVersion;
        }

        // Checking the version using >= will enable forward compatibility.
        protected string checkFor45PlusVersion(int releaseKey){
            if(releaseKey >= 461308) return"4.7.1 or later";
            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.
            log("No 4.5 or later version detected");
            return"";
        }

        protected string getVersionFromRegistry(){
            String maxDotNetVersion ="";
            // Opens the registry key for the .NET Framework entry.
            using(RegistryKey ndpKey = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine,"")
                                            .OpenSubKey(@"SOFTWARE\Microsoft
ET Framework Setup
DP"
)){
                // 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
ET Framework Setup
DP"))
                string[] subKeyNnames = ndpKey.GetSubKeyNames();
                foreach(string versionKeyName in subKeyNnames){
                    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(string.IsNullOrWhiteSpace(install)){ //no install info, must be later.
                            log(versionKeyName +"
" + name);
                            if(String.Compare(maxDotNetVersion, name) < 0) maxDotNetVersion = name;
                        }else{
                            if(!string.IsNullOrWhiteSpace(sp) &&"
1".Equals(install)){
                                log(versionKeyName +"
" + name +"  SP" + sp);
                                if(String.Compare(maxDotNetVersion, name) < 0) maxDotNetVersion = name;
                            }

                        }
                        if(!string.IsNullOrWhiteSpace(name)){
                            continue;
                        }

                        string[] subKeyNames = versionKey.GetSubKeyNames();
                        foreach(string subKeyName in subKeyNames){
                            RegistryKey subKey = versionKey.OpenSubKey(subKeyName);
                            name =(string)subKey.GetValue("
Version","");
                            if(!string.IsNullOrWhiteSpace(name)){
                                sp = subKey.GetValue("
SP","").ToString();
                            }
                            install = subKey.GetValue("
Install","").ToString();
                            if(string.IsNullOrWhiteSpace(install)){
                                //no install info, must be later.
                                log(versionKeyName +"
" + name);
                                if(String.Compare(maxDotNetVersion, name) < 0) maxDotNetVersion = name;
                            }else{
                                if(!string.IsNullOrWhiteSpace(sp) &&"
1".Equals(install)){
                                    log("
" + subKeyName +" " + name +"  SP" + sp);
                                    if(String.Compare(maxDotNetVersion, name) < 0) maxDotNetVersion = name;
                                }
                                else if("
1".Equals(install)){
                                    log("
" + subKeyName +" " + name);
                                    if(String.Compare(maxDotNetVersion, name) < 0) maxDotNetVersion = name;
                                } // if
                            } // if
                        } // for
                    } // if
                } // foreach
            } // using
            return maxDotNetVersion;
        }

        protected void log(string message){
            if(printVerification) Console.WriteLine(message);
        }

    } // class
}


使用.NET 4.6.2更新。在同一注册表中检查释放值,与以前的响应相同:

1
2
3
4
5
6
7
8
9
10
11
12
RegistryKey registry_key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft
ET Framework Setup
DP\v4\Full"
);
if (registry_key == null)
    return false;
var val = registry_key.GetValue("Release", 0);
UInt32 Release = Convert.ToUInt32(val);

if (Release >= 394806) // 4.6.2 installed on all other Windows (different than Windows 10)
                return true;
if (Release >= 394802) // 4.6.2 installed on Windows 10 or later
                return true;


从4.5版起,Microsoft改变了在注册表中存储.NET框架指示器的方式。有关如何检索.NET框架和CLR版本的官方指南,请参见:https://msdn.microsoft.com/en-us/library/hh925568(v=vs.110).aspx

我包括他们代码的修改版本,以解决如何确定.NET Framework for 4.5及更高版本的悬赏问题:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
using System;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Win32;

namespace stackoverflowtesting
{
    class Program
    {
        static void Main(string[] args)
        {
            Dictionary<int, String> mappings = new Dictionary<int, string>();

            mappings[378389] ="4.5";
            mappings[378675] ="4.5.1 on Windows 8.1";
            mappings[378758] ="4.5.1 on Windows 8, Windows 7 SP1, and Vista";
            mappings[379893] ="4.5.2";
            mappings[393295] ="4.6 on Windows 10";
            mappings[393297] ="4.6 on Windows not 10";

            using (RegistryKey ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey("SOFTWARE\\Microsoft\
ET Framework Setup\
DP\\v4\\Full\"))
            {
                int releaseKey = Convert.ToInt32(ndpKey.GetValue("
Release"));
                if (true)
                {
                    Console.WriteLine("
Version:" + mappings[releaseKey]);
                }
            }
            int a = Console.Read();
        }
    }
}


如果您的计算机已连接到Internet,则转到smallestdotnet,下载并执行.NET检查器可能是最简单的方法。

如果您需要确定版本的实际方法,请查看GitHub上的源代码,特别是Constants.cs,它将帮助您查找.NET 4.5及更高版本,其中修订部分是Relvant部分:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
                           { int.MinValue,"4.5" },
                           { 378389,"4.5" },
                           { 378675,"4.5.1" },
                           { 378758,"4.5.1" },
                           { 379893,"4.5.2" },
                           { 381029,"4.6 Preview" },
                           { 393273,"4.6 RC1" },
                           { 393292,"4.6 RC2" },
                           { 393295,"4.6" },
                           { 393297,"4.6" },
                           { 394254,"4.6.1" },
                           { 394271,"4.6.1" },
                           { 394747,"4.6.2 Preview" },
                           { 394748,"4.6.2 Preview" },
                           { 394757,"4.6.2 Preview" },
                           { 394802,"4.6.2" },
                           { 394806,"4.6.2" },


有点大,但看起来像是微软最新的奇闻怪事:

4


试试这个:

1
2
3
4
string GetFrameWorkVersion()
    {
        return System.Runtime.InteropServices.RuntimeEnvironment.GetSystemVersion();
    }


这就是我找到的解决方案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private static string GetDotNetVersion()
{
  var v4 = (string)Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft
ET Framework Setup
DP\v4\Full"
, false)?.GetValue("Version");
  if(v4 != null)
    return v4;
  var v35 = (string)Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft
ET Framework Setup
DP\v3.5"
, false)?.GetValue("Version");
  if(v35 != null)
    return v35;
  var v3 = (string)Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft
ET Framework Setup
DP\v3.0"
, false)?.GetValue("Version");
  return v3 ??"< 3";
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
        public static class DotNetHelper
{
    public static Version InstalledVersion
    {
        get
        {
            string framework = null;

            try
            {
                using (var ndpKey =
            Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\
ET Framework Setup\
DP\\v4\\Full\"))
                {
                    if (ndpKey != null)
                    {
                        var releaseKey = ndpKey.GetValue("
Release");
                        if (releaseKey != null)
                        {
                            framework = CheckFor45PlusVersion(Convert.ToInt32(releaseKey));
                        }
                        else
                        {
                            string[] versionNames = null;
                            using (var installedVersions =
                                Registry.LocalMachine.OpenSubKey(@"
SOFTWARE\Microsoft
ET Framework Setup
DP"))
                            {
                                if (installedVersions != null) versionNames = installedVersions.GetSubKeyNames();
                            }


                            try
                            {
                                if (versionNames != null && versionNames.Length > 0)
                                {
                                    framework = versionNames[versionNames.Length - 1].Remove(0, 1);
                                }
                            }
                            catch (FormatException)
                            {

                            }
                        }
                    }
                }
            }
            catch (SecurityException)
            {
            }

            return framework != null ? new Version(framework) : null;
        }
    }

    private static string CheckFor45PlusVersion(int releaseKey)
    {
        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";
        // This code should never execute. A non-null release key should mean
        // that 4.5 or later is installed.
        return releaseKey >= 378389 ?"
4.5" : null;
    }
}