2015-09-03 2 views
10

Кто-нибудь знает, работает ли TOSVersion.Name в Windows 10?Проверка версии Windows на W10

У меня есть приложение vcl, в котором отображается событие формы, которое получает детали операционной системы и отображает их в поле TMemo, используя запись TOSVersion от SysUtils.

with mmoOSInfo.Lines do 
begin 
    Clear; 
    Add(TOSVersion.ToString); 
    Add(''); 
    Add('Architecture: ' + OSArchitectureToStr(TOSVersion.Architecture)); 
    Add('Platform: ' + OSPlatformToStr(TOSVersion.Platform) + 
    IntToStr(PlatformFromPointer)); 
    Add('Build: ' + IntToStr(TOSVersion.Build)); 
    Add('Major: ' + IntToStr(TOSVersion.Major)); 
    Add('Minor: ' + IntToStr(TOSVersion.Minor)); 
    Add('Name: ' + TOSVersion.Name); 
    Add('Service Pack - Major: ' + IntToStr(TOSVersion.ServicePackMajor)); 
    Add('Service Pack - Minor: ' + IntToStr(TOSVersion.ServicePackMinor)); 
end; 

код выполняется без каких-либо проблем на XP (Да, мы все еще используем его (вешает голову от стыда)), Vista, Windows 7, Windows 8.1, Настольный ПК, ноутбуки и Surface Pro, но не тогда, когда установлен на Windows 10.

Когда я отлаживаю использование paserver, TOSVersion.Name возвращается как: = 'Windows 8'. Я делаю что-то неправильно или ожидаю слишком много для TOSVersion для обнаружения Windows 10? Никакое исключение не запускается. Из 2-х ОС Windows 10 машин на меня есть доступ, один путь миграции был из ОС Windows 8.1, а другие один, однако был из Windows 7.

Большое спасибо

+0

Http: // jpetermugaas.com/versionhelpers.html – Ampere

+0

К сожалению, для вышеуказанной ссылки - я только что протестировал эту библиотеку на Win 10, и она НЕ работает! – Ampere

ответ

11

Две вещи остановить свой код от возвращения правильного варианта:

  1. X Е8 RTL, что вы используете еще до Windows, 10 и поэтому не имеет никакого знания ОС Windows 10.
  2. Ваш исполняемый файл не проявляет себя в качестве поддержки для Windows 10, и так GetVersionEx, который TOSVersion полагается, будет лгать версия.

Случается, что обновление XE8 1, я считаю, изменяет обнаружение версии для использования NetWkstaGetInfo, которое не подпадает под эту версию. Хотя вызов NetWkstaGetInfo делает утечку памяти, но это, вероятно, не важно, поскольку он вызывается только один раз.

Некоторые ссылки, относящиеся к этой теме:

Если вы абсолютно необходимо сообщить версию пользователю, то у вас есть множество вариантов:

  • Добавить опцию supportedOS в манифесте и включают GUID для Windows, 10. Это останавливает GetVersionEx от лжи. Затем используйте модифицированную версию TOSVersion или некоторые другие средства для получения версии.
  • Используйте запрос WMI.
  • Звоните NetServerGetInfo.
  • Звоните NetWkstaGetInfo.
  • Звонок RtlGetVersion.

Подробнее об этом вопросе: How to detect true Windows version? Обратите внимание, что принятый ответ устарел.

В качестве примера подхода WMI, вы можете использовать этот код:

function OperatingSystemDisplayName: string; 

    function GetWMIObject(const objectName: string): IDispatch; 
    var 
    chEaten: Integer; 
    BindCtx: IBindCtx; 
    Moniker: IMoniker; 
    begin 
    OleCheck(CreateBindCtx(0, bindCtx)); 
    OleCheck(MkParseDisplayName(BindCtx, PChar(objectName), chEaten, Moniker)); 
    OleCheck(Moniker.BindToObject(BindCtx, nil, IDispatch, Result)); 
    end; 

    function VarToString(const Value: OleVariant): string; 
    begin 
    if VarIsStr(Value) then begin 
     Result := Trim(Value); 
    end else begin 
     Result := ''; 
    end; 
    end; 

    function FullVersionString(const Item: OleVariant): string; 
    var 
    Caption, ServicePack, Version, Architecture: string; 
    begin 
    Caption := VarToString(Item.Caption); 
    ServicePack := VarToString(Item.CSDVersion); 
    Version := VarToString(Item.Version); 
    Architecture := ArchitectureDisplayName(SystemArchitecture); 
    Result := Caption; 
    if ServicePack <> '' then begin 
     Result := Result + ' ' + ServicePack; 
    end; 
    Result := Result + ', version ' + Version + ', ' + Architecture; 
    end; 

var 
    objWMIService: OleVariant; 
    colItems: OleVariant; 
    Item: OleVariant; 
    oEnum: IEnumvariant; 
    iValue: LongWord; 

begin 
    Try 
    objWMIService := GetWMIObject('winmgmts:\\localhost\root\cimv2'); 
    colItems := objWMIService.ExecQuery('SELECT Caption, CSDVersion, Version FROM Win32_OperatingSystem', 'WQL', 0); 
    oEnum := IUnknown(colItems._NewEnum) as IEnumVariant; 
    if oEnum.Next(1, Item, iValue)=0 then begin 
     Result := FullVersionString(Item); 
     exit; 
    end; 
    Except 
    // yes, I know this is nasty, but come what may I want to use the fallback code below should the WMI code fail 
    End; 

    (* Fallback, relies on the deprecated function GetVersionEx, reports erroneous values 
    when manifest does not contain supportedOS matching the executing system *) 
    Result := TOSVersion.ToString; 
end; 
+0

Ужасно, что на рынках Emba XE8 готов к использованию Windows 10. –

+0

@JerryDodge - не больше. Новая версия - это то, что вам нужно, без сомнения, в соответствии с типами маркетинга. –

+0

Вы должны любить маркетинг :) - В стороне. Если я посмотрю на эту ссылку (https://msdn.microsoft.com/en-us/library/windows/desktop/dd371711%28v=vs.85%29.aspx), есть другие последствия для добавления записей supportedOS в манифест. Возможно, это хорошая идея добавить это к ответу. – Graymatter

2

Вы пытались с помощью настраиваемого манифест?

Я использую X Е8 и не имеет никаких проблем с TOSVersion распознающего для Windows 10 при использовании файла манифеста, который предназначается для Windows 8.1 и Windows, 10.

Моего заказа манифест сделан, чтобы сделать мое приложение «Windows 10» осведомленного.

Он следующее:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> 
    <assemblyIdentity 
    type="win32" 
    name="MrTheV Dev" 
    version="11.0.2804.9245" 
    processorArchitecture="*"/> 
    <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> 
    <security> 
     <requestedPrivileges> 
     <requestedExecutionLevel 
      level="asInvoker" 
      uiAccess="False"/> 
     </requestedPrivileges> 
    </security> 
    </trustInfo> 
    <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> 
     <application> 
      <!-- Windows 10 --> 
      <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/> 
      <!-- 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> 

я получил, что по этой ссылке: https://msdn.microsoft.com/fr-fr/library/windows/desktop/dn481241(v=vs.85).aspx

И TOSVersion.Tostring на под управлением Windows 10 1607 дисплеях:

Windows (Version 10.0, Build 14393, 64-bit Edition) 
Смежные вопросы