0%

VC++ 检测注册表

使用.NET平台所写的winform软件运行需要目标机器装有对应的Microsoft .NET Framework环境才能使用,如果未安装直接报错对使用者来说很不友好,得有一种方法来解决,最后采用了VC++编写了启动程序来对目标机器进行检测判断。
方法步骤这里从网上收集整理了下,用来判断本机 .NET 环境是否安装,如未安装则不运行 .NET 平台所写的程序。

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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
#include "stdio.h"
#include "windows.h"
#include "tchar.h"
#include "strsafe.h"
//#include "stdafx.h"
//#pragma comment (lib,"Advapi32.lib") //静态库编译下 需要 否则编译失败
//#pragma comment(lib, "Msimg32.lib") //静态库编译下 需要 否则编译失败
#pragma comment(lib, "AdvAPI32.lib") //静态库编译下 需要 否则编译失败
#pragma comment(lib, "User32.lib") //静态库编译下 需要 否则编译失败
#pragma comment(lib,"shell32.lib")

// 为避免机器编译时候出现:SDK中某些值没有被定义的情况,先定义他们。
#ifndef SM_TABLETPC
#define SM_TABLETPC 86
#endif

#ifndef SM_MEDIACENTER
#define SM_MEDIACENTER 87
#endif

// 用于检测注册表项的名称和值名称的常量
const TCHAR *g_szNetfx10RegKeyName = _T("Software\\\Microsoft\\\.NETFramework\\\Policy\\\v1.0");
const TCHAR *g_szNetfx10RegKeyValue = _T("3705");
const TCHAR *g_szNetfx10SPxMSIRegKeyName = _T("Software\\\Microsoft\\\Active Setup\\\Installed Components\\\{78705f0d - e8db - 4b2d - 8193 - 982bdda15ecd}");
const TCHAR *g_szNetfx10SPxOCMRegKeyName = _T("Software\\\Microsoft\\\Active Setup\\\Installed Components\\\{FDC11A6F - 17D1 - 48f9 - 9EA3 - 9051954BAA24}");
const TCHAR *g_szNetfx11RegKeyName = _T("Software\\\Microsoft\\\NET Framework Setup\\\NDP\\\v1.1.4322");
const TCHAR *g_szNetfx20RegKeyName = _T("Software\\\Microsoft\\\NET Framework Setup\\\NDP\\\v2.0.50727");
const TCHAR *g_szNetfx30RegKeyName = _T("Software\\\Microsoft\\\NET Framework Setup\\\NDP\\\v3.0\\\Setup");
const TCHAR *g_szNetfx30SpRegKeyName = _T("Software\\\Microsoft\\\NET Framework Setup\\\NDP\\\v3.0");
const TCHAR *g_szNetfx30RegValueName = _T("InstallSuccess");
const TCHAR *g_szNetfx35RegKeyName = _T("Software\\\Microsoft\\\NET Framework Setup\\\NDP\\\v3.5");
const TCHAR *g_szNetfx40RegKeyName = _T("SOFTWARE\\\Microsoft\\\NET Framework Setup\\\NDP\\\v4\\\Full");
const TCHAR *g_szNetfxStandardRegValueName = _T("Install");
const TCHAR *g_szNetfxStandardSPxRegValueName = _T("SP");
const TCHAR *g_szNetfxStandardVersionRegValueName = _T("Version");

// .NET Framework 3.0最终版本的版本信息
const int g_iNetfx30VersionMajor = 3;
const int g_iNetfx30VersionMinor = 0;
const int g_iNetfx30VersionBuild = 4506;
const int g_iNetfx30VersionRevision = 26;

// .NET Framework 3.5最终版本的版本信息
const int g_iNetfx35VersionMajor = 3;
const int g_iNetfx35VersionMinor = 5;
const int g_iNetfx35VersionBuild = 21022;
const int g_iNetfx35VersionRevision = 8;

// 函数原型声明
bool CheckNetfxBuildNumber(const TCHAR*, const TCHAR*, const int, const int, const int, const int);
int GetNetfx10SPLevel();
int GetNetfxSPLevel(const TCHAR*, const TCHAR*);
bool IsCurrentOSTabletMedCenter();
bool IsNetfx10Installed();
bool IsNetfx11Installed();
bool IsNetfx20Installed();
bool IsNetfx30Installed();
bool IsNetfx35Installed();
bool RegistryGetValue(HKEY, const TCHAR*, const TCHAR*, DWORD, LPBYTE, DWORD);

/******************************************************************
Function Name: 判断.NET Framework 1.0是否安装
Description: Uses the detection method recommended at
[url]http://msdn.microsoft.com/library/ms994349.aspx[/url]
to determine whether the .NET Framework 1.0 is
installed on the machine
Inputs: NONE
Results: .NET Framework 1.0已安装返回TRUE否则返回FALSE
******************************************************************/
bool IsNetfx10Installed()
{
TCHAR szRegValue[MAX_PATH];
return (RegistryGetValue(HKEY_LOCAL_MACHINE, g_szNetfx10RegKeyName, g_szNetfx10RegKeyValue, NULL, (LPBYTE)szRegValue, MAX_PATH));
}

/******************************************************************
Function Name: 判断.NET Framework 1.1是否安装
Description: Uses the detection method recommended at
[url]http://msdn.microsoft.com/library/ms994339.aspx[/url]
to determine whether the .NET Framework 1.1 is
installed on the machine
Inputs: NONE
Results: .NET Framework 1.1已安装返回TRUE否则返回FALSE
******************************************************************/
bool IsNetfx11Installed()
{
bool bRetValue = false;
DWORD dwRegValue = 0;

if (RegistryGetValue(HKEY_LOCAL_MACHINE, g_szNetfx11RegKeyName, g_szNetfxStandardRegValueName, NULL, (LPBYTE)&dwRegValue, sizeof(DWORD)))
{
if (1 == dwRegValue)
bRetValue = true;
}

return bRetValue;
}

/******************************************************************
Function Name: 判断.NET Framework 2.0是否安装
Description: Uses the detection method recommended at
[url]http://msdn.microsoft.com/library/aa480243.aspx[/url]
to determine whether the .NET Framework 2.0 is
installed on the machine
Inputs: NONE
Results: .NET Framework 2.0已安装返回TRUE否则返回FALSE
******************************************************************/
bool IsNetfx20Installed()
{
bool bRetValue = false;
DWORD dwRegValue = 0;

if (RegistryGetValue(HKEY_LOCAL_MACHINE, g_szNetfx20RegKeyName, g_szNetfxStandardRegValueName, NULL, (LPBYTE)&dwRegValue, sizeof(DWORD)))
{
if (1 == dwRegValue)
bRetValue = true;
}

return bRetValue;
}

/******************************************************************
Function Name: 判断.NET Framework 3.0是否安装
Description: Uses the detection method recommended at
[url]http://msdn.microsoft.com/library/aa964979.aspx[/url]
to determine whether the .NET Framework 3.0 is
installed on the machine
Inputs: NONE
Results: .NET Framework 3.0已安装返回TRUE否则返回FALSE
******************************************************************/
bool IsNetfx30Installed()
{
bool bRetValue = false;
DWORD dwRegValue = 0;

// 检查InstallSuccess注册表值存在,等于1
if (RegistryGetValue(HKEY_LOCAL_MACHINE, g_szNetfx30RegKeyName, g_szNetfx30RegValueName, NULL, (LPBYTE)&dwRegValue, sizeof(DWORD)))
{
if (1 == dwRegValue)
bRetValue = true;
}

//补充核查,检查版本列出的版本号在注册表中,是否已有预发布版的 .NET Framework 3.0 InstallSuccess值。
return (bRetValue && CheckNetfxBuildNumber(g_szNetfx30RegKeyName, g_szNetfxStandardVersionRegValueName, g_iNetfx30VersionMajor, g_iNetfx30VersionMinor, g_iNetfx30VersionBuild, g_iNetfx30VersionRevision));
}

/******************************************************************
Function Name: 判断.NET Framework 3.5是否安装
Description: Uses the detection method recommended at
[url]http://msdn.microsoft.com/library/cc160716.aspx[/url]
to determine whether the .NET Framework 3.5 is
installed on the machine
Inputs: NONE
Results: .NET Framework 3.5已安装返回TRUE否则返回FALSE
******************************************************************/
bool IsNetfx35Installed()
{
bool bRetValue = false;
DWORD dwRegValue = 0;

// 检查安装的注册表值存在,等于1
if (RegistryGetValue(HKEY_LOCAL_MACHINE, g_szNetfx35RegKeyName, g_szNetfxStandardRegValueName, NULL, (LPBYTE)&dwRegValue, sizeof(DWORD)))
{
if (1 == dwRegValue)
bRetValue = true;
}

// 补充核查,检查版本列出的版本号在注册表中,是否已有预发布版的 .NET Framework 3.5 InstallSuccess值。
return (bRetValue && CheckNetfxBuildNumber(g_szNetfx35RegKeyName, g_szNetfxStandardVersionRegValueName, g_iNetfx35VersionMajor, g_iNetfx35VersionMinor, g_iNetfx35VersionBuild, g_iNetfx35VersionRevision));
}

/******************************************************************
Function Name: 判断.NET Framework 4.0是否安装
Description: Uses the detection method recommended at
[url]http://msdn.microsoft.com/library/cc160716.aspx[/url]
to determine whether the .NET Framework 4.0 is
installed on the machine
Inputs: NONE
Results: .NET Framework 4.0已安装返回TRUE否则返回FALSE
******************************************************************/
bool IsNetfx40Installed()
{
bool bRetValue = false;
DWORD dwRegValue = 0;

// 检查安装的注册表值存在,等于1
if (RegistryGetValue(HKEY_LOCAL_MACHINE, g_szNetfx40RegKeyName, g_szNetfxStandardRegValueName, NULL, (LPBYTE)&dwRegValue, sizeof(DWORD)))
{
if (1 == dwRegValue)
bRetValue = true;
}

return bRetValue;
}

/******************************************************************
Function Name: 获取.NET Framework 1.0 SP 的版本
Description: Uses the detection method recommended at
[url]http://blogs.msdn.com/astebner/archive/2004/09/14/229802.aspx[/url]
to determine what service pack for the
.NET Framework 1.0 is installed on the machine
Inputs: NONE
Results: integer representing SP level for .NET Framework 1.0
******************************************************************/
int GetNetfx10SPLevel()
{
TCHAR szRegValue[MAX_PATH];
TCHAR *pszSPLevel = NULL;
int iRetValue = -1;
bool bRegistryRetVal = false;

//需要检测操作系统上注册表项SP的版本
if (IsCurrentOSTabletMedCenter())
bRegistryRetVal = RegistryGetValue(HKEY_LOCAL_MACHINE, g_szNetfx10SPxOCMRegKeyName, g_szNetfxStandardVersionRegValueName, NULL, (LPBYTE)szRegValue, MAX_PATH);
else
bRegistryRetVal = RegistryGetValue(HKEY_LOCAL_MACHINE, g_szNetfx10SPxMSIRegKeyName, g_szNetfxStandardVersionRegValueName, NULL, (LPBYTE)szRegValue, MAX_PATH);

if (bRegistryRetVal)
{
// 格式化SP版本号: #,#,#####,#
pszSPLevel = _tcsrchr(szRegValue, _T(', '));
if (NULL != pszSPLevel)
{
// 增量指针跳过逗号
pszSPLevel++;

// 转换值为整数
iRetValue = _tstoi(pszSPLevel);
}
}

return iRetValue;
}

/******************************************************************
Function Name: 获取.NET Framework SP 的版本
Description: 确定哪些已安装Service Pack的版本。 NET框架使用基于注册表检测方法的记载。 NET Framework的部署指南。
Inputs: pszNetfxRegKeyName – registry key name to use for detection
pszNetfxRegValueName – registry value to use for detection
Results: integer representing SP level for .NET Framework
******************************************************************/
int GetNetfxSPLevel(const TCHAR \*pszNetfxRegKeyName, const TCHAR \*pszNetfxRegValueName)
{
DWORD dwRegValue = 0;

if (RegistryGetValue(HKEY_LOCAL_MACHINE, pszNetfxRegKeyName, pszNetfxRegValueName, NULL, (LPBYTE)&dwRegValue, sizeof(DWORD)))
{
return (int)dwRegValue;
}

// 从注册表检索 .NET框架未安装或有某种错误的数据
return -1;
}

/******************************************************************
Function Name: 获取.NET Framework 编译版本
Description: 从注册表检索 .NET Framework 的版本号,验证这不是一个预发布版本号
Inputs: NONE
Results: true if the build number in the registry is greater
than or equal to the passed in version; false otherwise
******************************************************************/
bool CheckNetfxBuildNumber(const TCHAR \*pszNetfxRegKeyName, const TCHAR \*pszNetfxRegKeyValue, const int iRequestedVersionMajor, const int iRequestedVersionMinor, const int iRequestedVersionBuild, const int iRequestedVersionRevision)
{
TCHAR szRegValue[MAX_PATH];
TCHAR *pszToken = NULL;
TCHAR *pszNextToken = NULL;
int iVersionPartCounter = 0;
int iRegistryVersionMajor = 0;
int iRegistryVersionMinor = 0;
int iRegistryVersionBuild = 0;
int iRegistryVersionRevision = 0;
bool bRegistryRetVal = false;

// 尝试建立一些注册表值
bRegistryRetVal = RegistryGetValue(HKEY_LOCAL_MACHINE, pszNetfxRegKeyName, pszNetfxRegKeyValue, NULL, (LPBYTE)szRegValue, MAX_PATH);

if (bRegistryRetVal)
{
// 此注册表值应的格式#.#.#####.##.尝试解析4部分版本浏览
pszToken = _tcstok_s(szRegValue, _T("."), &pszNextToken);
while (NULL != pszToken)
{
iVersionPartCounter++;

switch (iVersionPartCounter)
{
case 1:
// 转换主要版本为整数

iRegistryVersionMajor = _tstoi(pszToken);
break;
case 2:
// 转换次要版本值为整数
iRegistryVersionMinor = _tstoi(pszToken);
break;
case 3:
// 转换编译版本值为整数
iRegistryVersionBuild = _tstoi(pszToken);
break;
case 4:
// 转换版本号值为整数
iRegistryVersionRevision = _tstoi(pszToken);
break;
default:
break;

}

// 获取其它部分的版本号
pszToken = _tcstok_s(NULL, _T("."), &pszNextToken);
}
}

// Compare the version number retrieved from the registry with
// the version number of the final release of the .NET Framework 3.0
//从注册表中检索最后发布的 .NET Framework 3.0 的版本号码,比较版本号码
if (iRegistryVersionMajor > iRequestedVersionMajor)
{
return true;
}
else if (iRegistryVersionMajor == iRequestedVersionMajor)
{
if (iRegistryVersionMinor > iRequestedVersionMinor)
{
return true;
}
else if (iRegistryVersionMinor == iRequestedVersionMinor)
{
if (iRegistryVersionBuild > iRequestedVersionBuild)
{
return true;
}
else if (iRegistryVersionBuild == iRequestedVersionBuild)
{
if (iRegistryVersionRevision >= iRequestedVersionRevision)
{
return true;
}
}
}
}

// If we get here, the version in the registry must be less than the
// version of the final release of the .NET Framework we are checking,
// so return false
return false;
}

bool IsCurrentOSTabletMedCenter()
{
// Use GetSystemMetrics to detect if we are on a Tablet PC or Media Center OS
return ((GetSystemMetrics(SM_TABLETPC) != 0) || (GetSystemMetrics(SM_MEDIACENTER) != 0));
}

/******************************************************************
Function Name: RegistryGetValue
Description: Get the value of a reg key
Inputs: HKEY hk – The hk of the key to retrieve
TCHAR *pszKey – Name of the key to retrieve
TCHAR *pszValue – The value that will be retrieved
DWORD dwType – The type of the value that will be retrieved
LPBYTE data – A buffer to save the retrieved data
DWORD dwSize – The size of the data retrieved
Results: true if successful, false otherwise
******************************************************************/
bool RegistryGetValue(HKEY hk, const TCHAR * pszKey, const TCHAR * pszValue, DWORD dwType, LPBYTE data, DWORD dwSize)
{
HKEY hkOpened;

// Try to open the key
if (RegOpenKeyEx(hk, pszKey, 0, KEY_READ, &hkOpened) != ERROR_SUCCESS)
{
return false;
}

// If the key was opened, try to retrieve the value
if (RegQueryValueEx(hkOpened, pszValue, 0, &dwType, (LPBYTE)data, &dwSize) != ERROR_SUCCESS)
{
RegCloseKey(hkOpened);
return false;
}

// Clean up
RegCloseKey(hkOpened);

return true;
}

int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
int iNetfx10SPLevel = -1;
int iNetfx11SPLevel = -1;
int iNetfx20SPLevel = -1;
int iNetfx30SPLevel = -1;
int iNetfx35SPLevel = -1;
int iNetfx40SPLevel = -1;
TCHAR szMessage[MAX_PATH];

// Determine whether or not the .NET Framework
// 1.0, 1.1, 2.0 or 3.0 are installed
bool bNetfx10Installed = IsNetfx10Installed();
bool bNetfx11Installed = IsNetfx11Installed();
bool bNetfx20Installed = IsNetfx20Installed();

// The .NET Framework 3.0 is an add-in that installs
// on top of the .NET Framework 2.0. For this version
// check, validate that both 2.0 and 3.0 are installed.
bool bNetfx30Installed = (IsNetfx20Installed() && IsNetfx30Installed());

// The .NET Framework 3.5 is an add-in that installs
// on top of the .NET Framework 2.0 and 3.0. For this version
// check, validate that 2.0, 3.0 and 3.5 are installed.
bool bNetfx35Installed = (IsNetfx20Installed() && IsNetfx30Installed() && IsNetfx35Installed());

// The .NET Framework 4.0 is an add-in that installs
bool bNetfx40Installed = IsNetfx40Installed();

/\* 只需要检测4.0是否安装 注释掉别的
// If .NET Framework 1.0 is installed, get the
// service pack level
if (bNetfx10Installed)
{
iNetfx10SPLevel = GetNetfx10SPLevel();

if (iNetfx10SPLevel > 0)
_stprintf_s(szMessage, MAX_PATH, _T(".NET Framework 1.0 service pack %i is installed."), iNetfx10SPLevel);
else
_stprintf_s(szMessage, MAX_PATH, _T(".NET Framework 1.0 is installed with no service packs."));

MessageBox(NULL, szMessage, _T(".NET Framework 1.0"), MB_OK | MB_ICONINFORMATION);
}
else
{
MessageBox(NULL, _T(".NET Framework 1.0 is not installed."), _T(".NET Framework 1.0"), MB_OK | MB_ICONINFORMATION);
}

// If .NET Framework 1.1 is installed, get the
// service pack level
if (bNetfx11Installed)
{
iNetfx11SPLevel = GetNetfxSPLevel(g_szNetfx11RegKeyName, g_szNetfxStandardSPxRegValueName);

if (iNetfx11SPLevel > 0)
_stprintf_s(szMessage, MAX_PATH, _T(".NET Framework 1.1 service pack %i is installed."), iNetfx11SPLevel);
else
_stprintf_s(szMessage, MAX_PATH, _T(".NET Framework 1.1 is installed with no service packs."));

MessageBox(NULL, szMessage, _T(".NET Framework 1.1"), MB_OK | MB_ICONINFORMATION);
}
else
{
MessageBox(NULL, _T(".NET Framework 1.1 is not installed."), _T(".NET Framework 1.1"), MB_OK | MB_ICONINFORMATION);
}

// If .NET Framework 2.0 is installed, get the
// service pack level
if (bNetfx20Installed)
{
iNetfx20SPLevel = GetNetfxSPLevel(g_szNetfx20RegKeyName, g_szNetfxStandardSPxRegValueName);

if (iNetfx20SPLevel > 0)
_stprintf_s(szMessage, MAX_PATH, _T(".NET Framework 2.0 service pack %i is installed."), iNetfx20SPLevel);
else
_stprintf_s(szMessage, MAX_PATH, _T(".NET Framework 2.0 is installed with no service packs."));

MessageBox(NULL, szMessage, _T(".NET Framework 2.0"), MB_OK | MB_ICONINFORMATION);
}
else
{
MessageBox(NULL, _T(".NET Framework 2.0 is not installed."), _T(".NET Framework 2.0"), MB_OK | MB_ICONINFORMATION);
}

// If .NET Framework 3.0 is installed, get the
// service pack level
if (bNetfx30Installed)
{
iNetfx30SPLevel = GetNetfxSPLevel(g_szNetfx30SpRegKeyName, g_szNetfxStandardSPxRegValueName);

if (iNetfx30SPLevel > 0)
_stprintf_s(szMessage, MAX_PATH, _T(".NET Framework 3.0 service pack %i is installed."), iNetfx30SPLevel);
else
_stprintf_s(szMessage, MAX_PATH, _T(".NET Framework 3.0 is installed with no service packs."));

MessageBox(NULL, szMessage, _T(".NET Framework 3.0"), MB_OK | MB_ICONINFORMATION);
}
else
{
MessageBox(NULL, _T(".NET Framework 3.0 is not installed."), _T(".NET Framework 3.0"), MB_OK | MB_ICONINFORMATION);
}

// If .NET Framework 3.5 is installed, get the
// service pack level
if (bNetfx35Installed)
{
iNetfx35SPLevel = GetNetfxSPLevel(g_szNetfx35RegKeyName, g_szNetfxStandardSPxRegValueName);

if (iNetfx35SPLevel > 0)
_stprintf_s(szMessage, MAX_PATH, _T(".NET Framework 3.5 service pack %i is installed."), iNetfx35SPLevel);
else
_stprintf_s(szMessage, MAX_PATH, _T(".NET Framework 3.5 is installed with no service packs."));

MessageBox(NULL, szMessage, _T(".NET Framework 3.5"), MB_OK | MB_ICONINFORMATION);
}
else
{
MessageBox(NULL, _T(".NET Framework 3.5 is not installed."), _T(".NET Framework 3.5"), MB_OK | MB_ICONINFORMATION);
}
*/
// If .NET Framework 4.0 is installed, get the
// service pack level
if (bNetfx40Installed)
{
iNetfx40SPLevel = GetNetfxSPLevel(g_szNetfx40RegKeyName, g_szNetfxStandardSPxRegValueName);

if (iNetfx40SPLevel > 0)
_stprintf_s(szMessage, MAX_PATH, _T(".NET Framework 4.0 service pack %i is installed."), iNetfx40SPLevel);
else
_stprintf_s(szMessage, MAX_PATH, _T(".NET Framework 4.0 is installed with no service packs."));

//MessageBox(NULL, szMessage, _T(".NET Framework 4.0"), MB_OK | MB_ICONINFORMATION);
//下面开始使用 ShellExecute 运行指定程序
if (ShellExecute(NULL, "open", "erpmgr.exe", NULL, NULL, SW_SHOWNORMAL) < (HANDLE)32) {
_stprintf_s(szMessage, MAX_PATH, _T("运行中发生错误,错误代码 %d"), 2);
MessageBox(NULL, szMessage, NULL, MB_OK);
}

}
else
{
MessageBox(NULL, _T(".NET 运行环境未安装或已经损坏,请先安装或修复后再次尝试。"), _T(".NET Framework 4.0"), MB_OK | MB_ICONINFORMATION);
}

return 0;
}

visual studio 中调试下看看
8720161025165736

觉得文章有用?请我喝杯咖啡~