Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   [решено] Некорректная работа GetVersionEx() (http://forum.oszone.net/showthread.php?t=315374)

RedScorpio 30-05-2016 10:50 2638698

Некорректная работа GetVersionEx()
 
Добрый день

Некорректно работает функция GetVersionEx() под Windows 10: возвращается версия OS 6.2 (Windows 8), хотя в соответствии с https://msdn.microsoft.com/en-us/lib...=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);


opel431 01-06-2016 22:29 2639519

Там есть примечание, касающееся 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/lib...(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 2639830

Цитата:

Цитата opel431
Там есть примечание, касающееся Windows 8.1 и Windows 10 »

Да, действительно, не обратил внимание на примечание. Если сделать таргетирование в манифесте, версия ОС определяется корректно.
Но
Не всегда используется манифест и не всегда нужно таргетирование. Поэтому встает вопрос: как определить, что версия ОС может быть и другой, нежели возвращает GetVersionEx() (т.е. если мы получили Windows 8 - не факт, может быть и Windows 10). А в идеале - получить версию ОС без таргетирования.

opel431 03-06-2016 23:29 2640088

Цитата:

Цитата RedScorpio
Поэтому встает вопрос »

Не вопрос, все уже придумано до нас!
https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx
https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx

Кроме того, всегда можно использовать WMI (без импорта скрипта, используя IBindCtx и IMoniker интерфейсов), в С++ не смотрел, а в Delphi применяю - 100% определение на любой версии.

RedScorpio 06-06-2016 10:34 2640671

Цитата:

Цитата opel431
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()
Цитата:

Цитата opel431
https://msdn.microsoft.com/en-us/library/dn424972%28v=vs.85%29.aspx»

А вот это для верификации, скорее всего, подойдет.

PS.
Цитата:

Цитата opel431
всегда можно использовать WMI (без импорта скрипта, используя IBindCtx и IMoniker интерфейсов) »

Не мой вариант - я не программист, просто иногда пишу "легенькие и простенькие" утилиты на C. Вот в одной и "выплыл" такой вопрос. В любом случае, спасибо за подсказки.

greg zakharov 06-06-2016 21:53 2640919

Цитата:

Цитата RedScorpio
Не всегда используется манифест и не всегда нужно таргетирование.

Тогда определяйте версию системы через рантайм либрари.
Код:

#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 2641063

Спасибо, это
Цитата:

Цитата greg zakharov
RtlGetNtVersionNumbers »

отличный метод для проверки "а не включен ли Compatibility mode"


Время: 22:14.

Время: 22:14.
© OSzone.net 2001-