powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Определение версии OS, проблемы с Version Helper functions - вообще не работают
8 сообщений из 8, страница 1 из 1
Определение версии OS, проблемы с Version Helper functions - вообще не работают
    #38516430
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я всегда удовлетворялся определением версии ядра:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
  Dim osv As OSVERSIONINFO
  osv.dwOSVersionInfoSize = Len(osv)
  If GetVersionEx(osv) = 1 Then
    If osv.dwPlatformId = VER_PLATFORM_WIN32_NT Then
      MsgBox osv.dwMajorVersion & "." & osv.dwMinorVersion
    End If
  End If


Вчера взглянул на Windows 8.1 - там должно быть 6.3, но не все так просто:
GetVersionEx function
GetVersionExApplications not manifested for Windows 8.1 will return the Windows 8 OS version value (6.2).
Ладно, с этим справился:
Targeting your application for Windows 8.1
Код: xml
1.
2.
          <!-- Windows 8.1 -->
          <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>


Код: xml
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.
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <assemblyIdentity 
        version="1.0.0.0" 
        processorArchitecture="X86" 
        name="Test.Application" 
        type="win32" />
    <description>Test Application</description>
    <dependency>
        <dependentAssembly>
            <assemblyIdentity 
                type="win32" 
                name="Microsoft.Windows.Common-Controls" 
                version="6.0.0.0" 
                processorArchitecture="X86" 
                publicKeyToken="6595b64144ccf1df" 
                language="*" />
        </dependentAssembly>
    </dependency>
    <!-- Identify the application security requirements. -->
    <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
       <security>
          <requestedPrivileges>
             <requestedExecutionLevel
                level="asInvoker"
                uiAccess="false"/>
          </requestedPrivileges>
       </security>
    </trustInfo>
    <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
       <application>
          <!-- Windows 8.1 -->
          <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
          <!-- Windows Vista -->
          <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> 
          <!-- Windows 7 -->
          <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
          <!-- Windows 8 -->
          <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
       </application>
    </compatibility>
</assembly>



Но версия ядра не делает различий между
Windows 7 / Windows Server 2008 R2
Windows 8 / Windows Server 2012
и т.д.

Хотелось бы определять имя OS в текстовом виде:
Windows XP SP3
Windows Server 2008 R2
и т.д.


Есть вариант читать из реестра, например:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
Public Function WinVersionFromRegistry() As String
  Dim ProductName As String
  Dim CSDVersion As String
  
  ProductName = GetRegValue(HKEY_LOCAL_MACHINE, _
   "SOFTWARE\Microsoft\Windows NT\CurrentVersion", "ProductName", "", False)
  ProductName = Trim(Replace(ProductName, "Microsoft", ""))
   
  CSDVersion = GetRegValue(HKEY_LOCAL_MACHINE, _
   "SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CSDVersion", "", False)
  CSDVersion = Trim(Replace(CSDVersion, "Service Pack ", "SP"))
   
  If Len(ProductName) > 0 Then
    If Len(CSDVersion) > 0 Then
      WinVersionFromRegistry = ProductName & " " & CSDVersion
    Else
      WinVersionFromRegistry = ProductName & " " & CSDVersion
    End If
  End If
End Function



Но он не очень хорош:
Например для моей тестовой 8.1 выдает:
Windows 8.1 Enterprise Evaluation .
Т.е. может быть вставлен любой мусор типа Enterprise Evaluation что лишнее.

Я нашел более современный метод:
Version Helper functions
Version Helper functionsThe following functions can be used to determine the current OS version or identify whether it is a Windows or Windows Server release. These APIs supersede GetVersion and GetVersionEx.

Про их всех написано:
DLL: Kernel32.dll, ntdll.dll
Minimum supported client: Windows 2000 Professional [desktop apps only]
Minimum supported server: Windows 2000 Server [desktop apps only]
что вообще-то странно, потому что по логике откуда XP может знать про IsWindows8Point1OrGreater function

Я попробовал задекларировать (причем пробовал варианты как Lib "ntdll.dll" так и Lib "Kernel32.dll"):
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
'Version Helper functions
Public Declare Function IsWindows7OrGreater Lib "ntdll.dll" () As Boolean
Public Declare Function IsWindows7SP1OrGreater Lib "ntdll.dll" () As Boolean
Public Declare Function IsWindows8OrGreater Lib "ntdll.dll" () As Boolean
Public Declare Function IsWindows8Point1OrGreater Lib "ntdll.dll" () As Boolean
Public Declare Function IsWindowsServer Lib "ntdll.dll" () As Boolean
Public Declare Function IsWindowsVistaOrGreater Lib "ntdll.dll" () As Boolean
Public Declare Function IsWindowsVistaSP1OrGreater Lib "ntdll.dll" () As Boolean
Public Declare Function IsWindowsVistaSP2OrGreater Lib "ntdll.dll" () As Boolean
Public Declare Function IsWindowsXPOrGreater Lib "ntdll.dll" () As Boolean
Public Declare Function IsWindowsXPSP1OrGreater Lib "ntdll.dll" () As Boolean
Public Declare Function IsWindowsXPSP2OrGreater Lib "ntdll.dll" () As Boolean
Public Declare Function IsWindowsXPSP3OrGreater Lib "ntdll.dll" () As Boolean



Проблема: при любом вызове любой из них (будь то на XP или 8.1) получаем:
can't find DLL entry point IsWindows... in ntdll.dll (ну либо kernel32.dll)


Или msdn врет, или я чего-то не понимаю (не дочитал). Где собака зарыта?
Манифест, приведенный выше, прикручен, но конкретно с этими ф-циями так понимаю он вообще не причем.

Ну, или поставим вопрос по другому.
Как хотя б определить что система = СЕРВЕР (чтоб хотя б различать между 7 и 2008R2 для 6.1) - кроме способа чтения художественного описания из реестра как в коде выше.
...
Рейтинг: 0 / 0
Определение версии OS, проблемы с Version Helper functions - вообще не работают
    #38516474
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Все, разобрался.
Дмитрий77Я нашел более современный метод:
Version Helper functions
Version Helper functionsThe following functions can be used to determine the current OS version or identify whether it is a Windows or Windows Server release. These APIs supersede GetVersion and GetVersionEx.
Я думаю что это ни фига не "модные" функции, а наспех написанные макросы определенные в versionhelpers.h
Note These APIs are defined by versionhelpers.h, which is included in the Windows 8.1 software development kit (SDK).
По ходу они операционки (Win 8/ 8.1) теперь также пишут через одно место.

А для вычисления сервер/не сервер и SP делаем так:
Код: vbnet
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.
'os product type values
Public Const VER_NT_WORKSTATION As Long = &H1 '!!! НЕ СЕРВЕР
Public Const VER_NT_DOMAIN_CONTROLLER As Long = &H2
Public Const VER_NT_SERVER As Long = &H3

Public Type OSVERSIONINFOEX
  dwOSVersionInfoSize As Long
  dwMajorVersion      As Long
  dwMinorVersion      As Long
  dwBuildNumber       As Long
  dwPlatformId        As Long
  szCSDVersion        As String * 128
  wServicePackMajor   As Integer
  wServicePackMinor   As Integer
  wSuiteMask          As Integer
  wProductType        As Byte
  wReserved           As Byte
End Type

Public Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" _
 (lpVersionInformation As Any) As Long

Private Sub Command1_Click()
  Dim osv As OSVERSIONINFOEX
  osv.dwOSVersionInfoSize = Len(osv)
  If GetVersionEx(osv) = 1 Then
    If osv.dwPlatformId = VER_PLATFORM_WIN32_NT Then
      MsgBox osv.dwMajorVersion & "." & osv.dwMinorVersion & _
       IIf(osv.wProductType <> VER_NT_WORKSTATION, " Server", "") & _
       IIf(osv.wServicePackMajor <> 0, " SP" & CStr(osv.wServicePackMajor), "")
    End If
  End If
End Sub


Ну и не забываем про манифест, чтоб на Win 8.1 фигню не писало (правильно 6.3, а без манифеста будет 6.2).
Зная версию ядра и сервер/не сервер, названия операционок известны.
...
Рейтинг: 0 / 0
Определение версии OS, проблемы с Version Helper functions - вообще не работают
    #38516838
Клевер
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Зная версию ядра и сервер/не сервер, названия операционок известны. можешь выложить свой полный код определения ос?
мой способ. отличить xp от других. но он явнонеидеальный
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
Dim WshShell As Object
Set WshShell = CreateObject("WScript.Shell")
Dim WshProEnv As Object
Set WshProEnv = WshShell.Environment("SYSTEM")
Dim SysInfo As String
SysInfo = WshProEnv.Item("PROCESSOR_ARCHITECTURE")
Dim arrByte()   As Byte
'If SysInfo = "x86" Then Else

...
Рейтинг: 0 / 0
Определение версии OS, проблемы с Version Helper functions - вообще не работают
    #38517421
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Клеверможешь выложить свой полный код определения ос?
Вообще то код приведенный постом выше полный. А с учетом комментариев более чем полный.
Ты что читать не умеешь?

P.S. XP это 5.1

PP.S Или тебе надо полностью функцию написать кот. красиво пишет название OS в виде "Windows Vista Service Pack 2" ? Извини, но я еще для себя ее не написал, хотя это очень просто. 31-го утром времени хватило только на осознание сути. С Новым годом!

PPP.S Но для тебя думаю сгодится вариант с реестром, приведенный постом выше. Ой, извини, не угодил, он не полный, не разжевана ф-ция GetRegValue. Ну, извини, не угодил.
...
Рейтинг: 0 / 0
Определение версии OS, проблемы с Version Helper functions - вообще не работают
    #38517541
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как-то так, если нигде не ошибся:

Код: vbnet
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.
Public Function GetWinVersion() As String
  Dim osv As OSVERSIONINFOEX
  osv.dwOSVersionInfoSize = Len(osv)
  If GetVersionEx(osv) = 1 Then
    If osv.dwPlatformId = VER_PLATFORM_WIN32_NT Then
      Select Case osv.dwMajorVersion
        Case 5:
          Select Case osv.dwMinorVersion
            Case 1:
              GetWinVersion = "Windows XP"
            Case 2:
              If GetSystemMetrics(SM_SERVERR2) <> 0 Then
                GetWinVersion = "Windows Server 2003 R2"
              Else
                GetWinVersion = "Windows Server 2003"
              End If
            Case Else
          End Select
        Case 6:
          Select Case osv.dwMinorVersion
            Case 0:
              GetWinVersion = _
               IIf(osv.wProductType <> VER_NT_WORKSTATION, "Windows Server 2008", "Windows Vista")
            Case 1:
              GetWinVersion = _
               IIf(osv.wProductType <> VER_NT_WORKSTATION, "Windows Server 2008 R2", "Windows 7")
            Case 2:
              GetWinVersion = _
               IIf(osv.wProductType <> VER_NT_WORKSTATION, "Windows Server 2012", "Windows 8")
            Case 3: 'манифест!!!
              GetWinVersion = _
               IIf(osv.wProductType <> VER_NT_WORKSTATION, "Windows Server 2012 R2", "Windows 8.1")
            Case Else
          End Select
        Case Else
      End Select
      
      If GetWinVersion <> "" Then
        GetWinVersion = _
         GetWinVersion & IIf(osv.wServicePackMajor <> 0, " SP" & CStr(osv.wServicePackMajor), "")
      Else
        If osv.dwMajorVersion >= 6 Then
          'условно - для будущих версий Windows
          GetWinVersion = _
           IIf(osv.wProductType <> VER_NT_WORKSTATION, "Windows Server 2012 R2", "Windows 8.1")
        End If
      End If
    End If
  End If
End Function
...
Рейтинг: 0 / 0
Определение версии OS, проблемы с Version Helper functions - вообще не работают
    #38517762
Клевер
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77, спасибо)
...
Рейтинг: 0 / 0
Определение версии OS, проблемы с Version Helper functions - вообще не работают
    #38520009
Petr Alexeev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я столкнулся с аналогичной проблемой и хотел поделиться своим опытом.

Уточнение о Version Helper functions
Version Helper functions - это всё же функции, но не макросы. Просто они и объявлены, и определены в заголовочном файле versionhelpers.h, входящем в состав Windows SDK 8.1. При этом функции объявлены с ключевым словом __forceinline. Поэтому эти функции будут присутствовать в объектном коде лишь при следующих условиях:

Для разработки используется C/C++ (заголовочный файл versionhelpers.h можно включать в файлы исходного текста на C/C++).

В коде присутствуют вызовы этих функций или присутствуют указатели на функции (иначе компилятор может просто не включить функции в объектный файл).

Конечно ни в Kernel32.dll, ни в ntdll.dll Version Helper functions не содержатся. Очевидно, описание этих функций в MSDN не достаточно корректное. Кроме того, не понятно, как использовать Version Helper functions в программах, разработанных не на C/C++.

В результате я тоже отказался от использования Version Helper functions.

Недостаток GetVersionEx и манифеста приложения
Использование функции GetVersionEx в Windows 8.1 и Windows Server 2012 R2 требует декларирования совместимости в манифесте приложения:
Дмитрий77<!-- Windows 8.1 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>

Однако на сегодняшний день неизвестно, каким будет идентификатор следующей ОС после Windows 8.1 и Windows Server 2012 R2. Поэтому весьма вероятно, что после выпуска очередной ОС от Microsoft манифест приложения придётся обновлять и выпускать его новую версию.

Функции VerifyVersionInfo и VerSetConditionMask
Можно обойтись и без манифеста за счёт отказа от использования функции GetVersionEx. Для сравнения версии текущей ОС с указанным значением можно воспользоваться функциями VerifyVersionInfo ( http://msdn.microsoft.com/library/windows/desktop/ms725492.aspx ) и VerSetConditionMask ( http://msdn.microsoft.com/library/windows/desktop/ms725493.aspx ). Эти функции экспортируются kernel32.dll, а также работают и без манифеста приложения.

Для определения версии Windows удобно воспользоваться таблицей, содержащейся в разделе Remarks страницы описания структуры OSVERSIONINFOEX ( http://msdn.microsoft.com/library/windows/desktop/ms724833.aspx ).

Пример использования функций VerifyVersionInfo и VerSetConditionMask можно найти в статье: http://www.codeproject.com/Articles/678606/Part1-Overcoming-Windows-8-1s-deprecation-of-GetVe.

Успехов!
...
Рейтинг: 0 / 0
Определение версии OS, проблемы с Version Helper functions - вообще не работают
    #38520113
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petr Alexeev,

На самом деле для корректного функционирования проги как таковой достаточно проверить версию ядра.
Причем опыт показывает что для большинства задач достаточно проверить соответствие
>=6.0 (Виста или выше),
в редких случаях мне требовалось проверять >=6.1 (Win7 или выше),
и единственный раз потребовалось реально знать про Win 8
Частенько существенна разница между XP(5.1) и Win2003(5.2), но в данном случае разные версии ядра, а вот сервера начиная с 2008-го от клиентских версий ничем не отличаются.

Существенно x64 или win32, но это к данному вопросу никакого отношения не имеет.

Поэтому все эти прибамбасы с сервер/не сервер либо версиями Service Pack не более чем для красоты (отображение имени OS).

Что касается манифеста, у меня например прога адаптированная под Win8 (но не знавшая про 8.1) именно за счет его отсутствия не сделала одну ошибку потому что искренне считала версию =6.2 (Win8=), будучи запущенной на Win8.1

Ну а по поводу упомянутой таблицы, сильные уточнения ни к чему.
Что касается всяких "Windows Home Server". Хотя меня раз клиент достал с этим "Home Server", пришлось его установить, чтоб понять что это самый обычный Win 2003, правда нарочно изгаженный зачем-то (инсталлятор уничтожает ВСЕ данные на ВСЕХ дисках и рабочий стол запрятан под интерфейс для придурков с надписью "НЕ ВЛЕЗАЙ -УБЬЕТ", хотя никакой реальной "защиты" от полноценного использования нет и последнее лечится очень легко штатными средствами) и продаваемый по цене $100 за штуку вместо стандартных $1000-4000.
...
Рейтинг: 0 / 0
8 сообщений из 8, страница 1 из 1
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Определение версии OS, проблемы с Version Helper functions - вообще не работают
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]