win7下得到操作系統版本錯誤( GetVersionEx)
有一段得到操作系統版本的代碼,用的是 GetVersionEx 方法,在當前機器的硬盤上運行,得到的操作系統版本是win7。奇怪的是,在U盤上運行,得到的操作系統版本是XP。
直接說原因:
不知道什么時候,系統在注冊表中設置了U盤exe的XP兼容項(在兼容性助手彈出時,選擇重新啟動或者重新安裝時,系統會在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\AppCompatFlags\Layers下記錄該程序的路徑。同時寫上特定的字符串值,比如WINXPSP2、VISTASETUP RUNASADMIN)。之后在該程序的運行之前,系統會讀取該記錄值以決定是否要彈兼容性助手。
解決辦法:
手動修改或者刪除此注冊表項。
偶認為它不應該影響到API的正確執行才對,事實證明它的確影響到了GetVersionEx 的執行結果了。
http://hi.baidu.com/anowsober/blog/item/0c2c428b470073d8fc1f1065.html
以上內容為轉載。
我遇到的情況是,我在win7 64位上編譯出來的32位程序調用了GetVersionEx,程序在f:\bin目錄下執行返回的操作系統是5.1(xp sp3),放到別的盤,或者還在f盤別的目錄執行可以得到正確的操作系統版本6.1(win7)。根據上邊的解釋,刪除了注冊表,正常了。

以上轉自:http://hi.baidu.com/445920201/item/8de62930e9f01e21b2c0c50a我遇到的情況和上面相同,在win7系統中D盤的某一目錄通過GetVersionEx獲取的系統版本是VISTA,其他任何磁盤和文件獲取的系統版本都是正確的,搜索注冊表后,刪除注冊表中的選項后,再次獲取就正確了。通過GetVersionEx獲取系統版本,MSDN中解釋:
GetVersionEx Function
Retrieves information about the current operating system.
1 BOOL WINAPI GetVersionEx(
2 __in_out LPOSVERSIONINFO lpVersionInfo
3 );
Parameters
- lpVersionInfo
-
An OSVERSIONINFO or OSVERSIONINFOEX structure that receives the operating system information.
Before calling the GetVersionEx function, set the dwOSVersionInfoSize member of this structure as appropriate.
Return Value
If the function succeeds, the return value is a nonzero value.
If the function fails, the return value is zero. To get extended error information, call GetLastError. The function fails if you specify an invalid value for the dwOSVersionInfoSize member of the OSVERSIONINFO or OSVERSIONINFOEX structure.
Remarks
Identifying the current operating system is usually not the best way to determine whether a particular operating system feature is present. This is because the operating system may have had new features added in a redistributable DLL. Rather than using GetVersionEx to determine the operating system platform or version number, test for the presence of the feature itself. For more information, see Operating System Version.
The GetSystemMetrics function provides additional information about the current operating system.
Product |
Setting |
Windows XP Media Center Edition |
SM_MEDIACENTER |
Windows XP Starter Edition |
SM_STARTER |
Windows XP Tablet PC Edition |
SM_TABLETPC |
Windows Server 2003 R2 |
SM_SERVERR2 |
To check for specific operating systems or operating system features, use the IsOS function. The GetProductInfo function retrieves the product type.
To retrieve information for the operating system on a remote computer, use the NetWkstaGetInfo function, the Win32_OperatingSystem WMI class, or the OperatingSystem property of the IADsComputer interface.
To compare the current system version to a required version, use the VerifyVersionInfo function instead of using GetVersionEx to perform the comparison yourself.
Example Code [C++]
When using the GetVersionEx function to determine whether your application is running on a particular version of the operating system, check for version numbers that are greater than or equal to the desired version numbers. This ensures that the test succeeds for later versions of the operating system. For example, if your application requires Windows XP or later, use the following test.
1 #include <windows.h>
2 #include <stdio.h>
3
4 void main()
5 {
6 OSVERSIONINFO osvi;
7 BOOL bIsWindowsXPorLater;
8
9 ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
10 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
11
12 GetVersionEx(&osvi);
13
14 bIsWindowsXPorLater =
15 ( (osvi.dwMajorVersion > 5) ||
16 ( (osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion >= 1) ));
17
18 if(bIsWindowsXPorLater)
19 printf("The system meets the requirements.\n");
20 else printf("The system does not meet the requirements.\n");
21 }
Example Code
For an example that identifies the current operating system, see Getting the System Version.
The following example uses the GetVersionEx, GetSystemMetrics, and GetNativeSystemInfo functions to determine the version information of the currently running operating system. The code outputs the information to the console.
Relying on version information is not the best way to test for a feature. Instead, refer to the documentation for the feature of interest. For more information on common techniques for feature detection, see Operating System Version.
If you must require a particular operating system, be sure to use it as a minimum supported version, rather than design the test for the one operating system. This way, your detection code will continue to work on future versions of Windows.
1 #include <windows.h>
2 #include <tchar.h>
3 #include <stdio.h>
4
5 #define BUFSIZE 80
6
7 typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO);
8
9 int __cdecl _tmain()
10 {
11 OSVERSIONINFOEX osvi;
12 SYSTEM_INFO si;
13 PGNSI pGNSI;
14 BOOL bOsVersionInfoEx;
15
16 ZeroMemory(&si, sizeof(SYSTEM_INFO));
17 ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
18
19 // Try calling GetVersionEx using the OSVERSIONINFOEX structure.
20 // If that fails, try using the OSVERSIONINFO structure.
21
22 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
23
24 if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) )
25 {
26 osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
27 if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) )
28 return FALSE;
29 }
30
31 // Call GetNativeSystemInfo if supported
32 // or GetSystemInfo otherwise.
33
34 pGNSI = (PGNSI) GetProcAddress(
35 GetModuleHandle(TEXT("kernel32.dll")),
36 "GetNativeSystemInfo");
37 if(NULL != pGNSI)
38 pGNSI(&si);
39 else GetSystemInfo(&si);
40
41 switch (osvi.dwPlatformId)
42 {
43 // Test for the Windows NT product family.
44
45 case VER_PLATFORM_WIN32_NT:
46
47 // Test for the specific product.
48
49 if ( osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0 )
50 {
51 if( osvi.wProductType == VER_NT_WORKSTATION )
52 printf ("Windows Vista ");
53 else printf ("Windows Server \"Longhorn\" " );
54 }
55
56 if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2 )
57 {
58 if( GetSystemMetrics(SM_SERVERR2) )
59 printf( "Microsoft Windows Server 2003 \"R2\" ");
60 else if( osvi.wProductType == VER_NT_WORKSTATION &&
61 si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)
62 {
63 printf( "Microsoft Windows XP Professional x64 Edition ");
64 }
65 else printf ("Microsoft Windows Server 2003, ");
66 }
67
68 if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1 )
69 printf ("Microsoft Windows XP ");
70
71 if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 )
72 printf ("Microsoft Windows 2000 ");
73
74 if ( osvi.dwMajorVersion <= 4 )
75 printf ("Microsoft Windows NT ");
76
77 // Test for specific product on Windows NT 4.0 SP6 and later.
78 if( bOsVersionInfoEx )
79 {
80 // Test for the workstation type.
81 if ( osvi.wProductType == VER_NT_WORKSTATION &&
82 si.wProcessorArchitecture!=PROCESSOR_ARCHITECTURE_AMD64)
83 {
84 if( osvi.dwMajorVersion == 4 )
85 printf ( "Workstation 4.0 " );
86 else if( osvi.wSuiteMask & VER_SUITE_PERSONAL )
87 printf ( "Home Edition " );
88 else printf ( "Professional " );
89 }
90
91 // Test for the server type.
92 else if ( osvi.wProductType == VER_NT_SERVER ||
93 osvi.wProductType == VER_NT_DOMAIN_CONTROLLER )
94 {
95 if(osvi.dwMajorVersion==5 && osvi.dwMinorVersion==2)
96 {
97 if ( si.wProcessorArchitecture ==
98 PROCESSOR_ARCHITECTURE_IA64 )
99 {
100 if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
101 printf ( "Datacenter Edition "
102 "for Itanium-based Systems" );
103 else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
104 printf ( "Enterprise Edition "
105 "for Itanium-based Systems" );
106 }
107
108 else if ( si.wProcessorArchitecture ==
109 PROCESSOR_ARCHITECTURE_AMD64 )
110 {
111 if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
112 printf ( "Datacenter x64 Edition " );
113 else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
114 printf ( "Enterprise x64 Edition " );
115 else printf( "Standard x64 Edition " );
116 }
117
118 else
119 {
120 if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
121 printf ( "Datacenter Edition " );
122 else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
123 printf ( "Enterprise Edition " );
124 else if ( osvi.wSuiteMask & VER_SUITE_BLADE )
125 printf ( "Web Edition " );
126 else printf ( "Standard Edition " );
127 }
128 }
129 else if(osvi.dwMajorVersion==5 && osvi.dwMinorVersion==0)
130 {
131 if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
132 printf ( "Datacenter Server " );
133 else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
134 printf ( "Advanced Server " );
135 else printf ( "Server " );
136 }
137 else // Windows NT 4.0
138 {
139 if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
140 printf ("Server 4.0, Enterprise Edition " );
141 else printf ( "Server 4.0 " );
142 }
143 }
144 }
145 // Test for specific product on Windows NT 4.0 SP5 and earlier
146 else
147 {
148 HKEY hKey;
149 TCHAR szProductType[BUFSIZE];
150 DWORD dwBufLen=BUFSIZE*sizeof(TCHAR);
151 LONG lRet;
152
153 lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
154 TEXT("SYSTEM\\CurrentControlSet\\Control\\"
155 "ProductOptions"), 0, KEY_QUERY_VALUE, &hKey );
156 if( lRet != ERROR_SUCCESS )
157 return FALSE;
158
159 lRet = RegQueryValueEx( hKey, TEXT("ProductType"),
160 NULL, NULL, (LPBYTE) szProductType, &dwBufLen);
161 RegCloseKey( hKey );
162
163 if( (lRet != ERROR_SUCCESS) ||
164 (dwBufLen > BUFSIZE*sizeof(TCHAR)) )
165 return FALSE;
166
167 if ( lstrcmpi( TEXT("WINNT"), szProductType) == 0 )
168 printf( "Workstation " );
169 if ( lstrcmpi( TEXT("LANMANNT"), szProductType) == 0 )
170 printf( "Server " );
171 if ( lstrcmpi( TEXT("SERVERNT"), szProductType) == 0 )
172 printf( "Advanced Server " );
173 printf( "%d.%d ", osvi.dwMajorVersion, osvi.dwMinorVersion );
174 }
175
176 // Display service pack (if any) and build number.
177
178 if( osvi.dwMajorVersion == 4 &&
179 lstrcmpi( osvi.szCSDVersion, TEXT("Service Pack 6") ) == 0 )
180 {
181 HKEY hKey;
182 LONG lRet;
183
184 // Test for SP6 versus SP6a.
185 lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
186 TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\"
187 "Hotfix\\Q246009"), 0, KEY_QUERY_VALUE, &hKey );
188 if( lRet == ERROR_SUCCESS )
189 printf( "Service Pack 6a (Build %d)\n",
190 osvi.dwBuildNumber & 0xFFFF );
191 else // Windows NT 4.0 prior to SP6a
192 {
193 _tprintf( TEXT("%s (Build %d)\n"),
194 osvi.szCSDVersion,
195 osvi.dwBuildNumber & 0xFFFF);
196 }
197
198 RegCloseKey( hKey );
199 }
200 else // not Windows NT 4.0
201 {
202 _tprintf( TEXT("%s (Build %d)\n"),
203 osvi.szCSDVersion,
204 osvi.dwBuildNumber & 0xFFFF);
205 }
206
207 break;
208
209 // Test for the Windows Me/98/95.
210 case VER_PLATFORM_WIN32_WINDOWS:
211
212 if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0)
213 {
214 printf ("Microsoft Windows 95 ");
215 if (osvi.szCSDVersion[1]=='C' || osvi.szCSDVersion[1]=='B')
216 printf("OSR2 " );
217 }
218
219 if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10)
220 {
221 printf ("Microsoft Windows 98 ");
222 if ( osvi.szCSDVersion[1]=='A' || osvi.szCSDVersion[1]=='B')
223 printf("SE " );
224 }
225
226 if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90)
227 {
228 printf ("Microsoft Windows Millennium Edition\n");
229 }
230 break;
231
232 case VER_PLATFORM_WIN32s:
233
234 printf ("Microsoft Win32s\n");
235 break;
236 }
237 return TRUE;
238 }
Requirements
Client |
Requires Windows Vista, Windows XP, Windows 2000 Professional, Windows NT Workstation 3.5 and later, Windows Me, Windows 98, or Windows 95. |
Server |
Requires Windows Server 2008, Windows Server 2003, Windows 2000 Server, or Windows NT Server 3.5 and later. |
Header |
Declared in Winbase.h; include Windows.h. |
Library |
Use Kernel32.lib. |
DLL |
Requires Kernel32.dll. |
Unicode |
Implemented as GetVersionExW (Unicode) and GetVersionExA (ANSI). |