Показать полную графическую версию : [решено] Некорректная работа GetVersionEx()
RedScorpio
30-05-2016, 10:50
Добрый день
Некорректно работает функция GetVersionEx() под Windows 10: возвращается версия OS 6.2 (Windows 8), хотя в соответствии с https://msdn.microsoft.com/en-us/library/windows/desktop/ms724833%28v=vs.85%29.aspx должно возвращаться 10.0.
Почему так происходит?
Фрагмент кода:
memset(&osvi, 0x00, sizeof(OSVERSIONINFOEX));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
GetVersionEx((LPOSVERSIONINFOA) &osvi);
sprintf(_cLogStr, "Windows version\t= %d.%d", (int)osvi.dwMajorVersion, (int)osvi.dwMinorVersion);
_WriteLogString(_cLogStr, -1, 1, 0, 1);
Там есть примечание, касающееся Windows 8.1 и Windows 10
* For applications that have been manifested for Windows 8.1 or Windows 10. Applications not manifested for Windows 8.1 or Windows 10 will return the Windows 8 OS version value (6.2). To manifest your applications for Windows 8.1 or Windows 10, refer to Targeting your application for Windows.
Посмотрите - https://msdn.microsoft.com/en-us/library/windows/desktop/dn481241(v=vs.85).aspx
<!-- Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
<!-- Windows 8.1 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
RedScorpio
03-06-2016, 10:08
Там есть примечание, касающееся Windows 8.1 и Windows 10 »
Да, действительно, не обратил внимание на примечание. Если сделать таргетирование в манифесте, версия ОС определяется корректно.
Но
Не всегда используется манифест и не всегда нужно таргетирование. Поэтому встает вопрос: как определить, что версия ОС может быть и другой, нежели возвращает GetVersionEx() (т.е. если мы получили Windows 8 - не факт, может быть и Windows 10). А в идеале - получить версию ОС без таргетирования.
Поэтому встает вопрос »Не вопрос, все уже придумано до нас!
https://msdn.microsoft.com/en-us/library/ms725492(v=vs.85).aspx
https://msdn.microsoft.com/en-us/library/dn424972(v=vs.85).aspx
Кроме того, всегда можно использовать WMI (без импорта скрипта, используя IBindCtx и IMoniker интерфейсов), в С++ не смотрел, а в Delphi применяю - 100% определение на любой версии.
RedScorpio
06-06-2016, 10:34
https://msdn.microsoft.com/en-us/library/ms725492%28v=vs.85%29.aspx»
Это не поможет:
If the application has no manifest, VerifyVersionInfo behaves as if the operation system version is Windows 8 (6.2).
If the application has a manifest that contains the GUID that corresponds to Windows 8.1, VerifyVersionInfo behaves as if the operation system version is Windows 8.1 (6.3).
If the application has a manifest that contains the GUID that corresponds to Windows 10, VerifyVersionInfo behaves as if the operation system version is Windows 10 (10.0).
Т.е. работа будет аналогична GetVersionEx()
https://msdn.microsoft.com/en-us/library/dn424972%28v=vs.85%29.aspx»
А вот это для верификации, скорее всего, подойдет.
PS. всегда можно использовать WMI (без импорта скрипта, используя IBindCtx и IMoniker интерфейсов) »
Не мой вариант - я не программист, просто иногда пишу "легенькие и простенькие" утилиты на C. Вот в одной и "выплыл" такой вопрос. В любом случае, спасибо за подсказки.
greg zakharov
06-06-2016, 21:53
Не всегда используется манифест и не всегда нужно таргетирование.Тогда определяйте версию системы через рантайм либрари.
#include <windows.h>
#include <stdio.h>
VOID (__stdcall *RtlGetNtVersionNumbers)(
LPDWORD Major,
LPDWORD Minor,
LPDWORD Other
);
int main(void) {
DWORD major = 0, minor = 0, other = 0;
if (!(RtlGetNtVersionNumbers = (PVOID)GetProcAddress(
GetModuleHandle("ntdll.dll"), "RtlGetNtVersionNumbers"
))) return -1;
RtlGetNtVersionNumbers(&major, &minor, &other);
printf("%lu.%lu\n", major, minor);
return 0;
}
RedScorpio
07-06-2016, 13:59
Спасибо, это
RtlGetNtVersionNumbers »
отличный метод для проверки "а не включен ли Compatibility mode"
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.