2015-09-03 21 views
10

Qualcuno sa se TOSVersion.Name funziona ancora su Windows 10?Controllo della versione di Windows su W10

Possiedo un'applicazione vcl con un evento show di form che ottiene i dettagli del sistema operativo e li visualizza in una casella TMemo utilizzando il record TOSVersion di 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; 

il codice viene eseguito senza problemi su XP (Sì stiamo ancora usando (appende testa per la vergogna)), Vista, Windows 7, Windows 8.1, desktop PC, computer portatili e Pro di superficie, ma non quando installato su Windows 10.

Quando eseguo il debug con paserver, TOSVersion.Name ritorna come: = 'Windows 8'. Sto facendo qualcosa di sbagliato o mi aspetto troppo perché TOSVersion rilevi Windows 10? Nessuna eccezione è stata attivata. Dei 2 x di Windows 10 macchine che hanno accesso a, un percorso di migrazione è stato da Windows 8.1, l'altro invece era da Windows 7.

Molte grazie

+0

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

+0

Mi spiace, per il link sopra - ho appena testato quella libreria su Win 10 e NON funziona! – Ampere

risposta

11

Due cose si fermano il codice da restituire la versione corretta:

  1. Il XE8 RTL che si utilizza è anteriore di Windows 10 e quindi non ha alcuna conoscenza di Windows 10.
  2. l'eseguibile non si manifesta come supporto di Windows 10, e così GetVersionEx, che si basa su TOSVersion, giacerà su la versione.

Accade così che l'aggiornamento XE8 1, credo, cambi il rilevamento della versione per utilizzare NetWkstaGetInfo che non è soggetto a questa versione. Anche se la chiamata a NetWkstaGetInfo perde memoria, ma probabilmente non è importante poiché viene chiamata solo una volta.

Alcuni link relativi a questo argomento

Se è assolutamente necessario segnalare la versione per l'utente, allora si hanno una varietà di opzioni:

  • aggiungere l'opzione supportedOS al vostro manifesto e includono il GUID per Windows 10. Ciò si ferma GetVersionEx da sdraiato. Quindi utilizzare una versione modificata di TOSVersion o altri mezzi per ottenere la versione.
  • Utilizzare una query WMI.
  • Chiama NetServerGetInfo.
  • Chiama NetWkstaGetInfo.
  • Chiama RtlGetVersion.

Maggiori dettagli in questa domanda: How to detect true Windows version? Anche se nota che la risposta accettata v'è out-of-date.

Come esempio dell'approccio WMI, è possibile utilizzare questo codice:

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

La cosa triste è che Emba commercializza che XE8 è pronto per Windows 10. –

+0

@JerryDodge Non più. La nuova versione è ciò di cui hai bisogno, senza dubbio, in base ai tipi di marketing. –

+0

Devi amare il marketing :) - A parte questo. Se guardo questo link (https://msdn.microsoft.com/en-us/library/windows/desktop/dd371711%28v=vs.85%29.aspx) ci sono altre implicazioni per aggiungere le voci supportOS agli manifesto. Forse è una buona idea aggiungerlo alla risposta. – Graymatter

2

Hai provato a usare un manifesto personalizzato?

utilizzare XE8 e non hanno problemi con TOSVersion riconoscimento di Windows 10 quando si utilizza un file manifesto che gli obiettivi di Windows 8.1 e Windows 10.

mio manifesto personalizzato è fatto per rendere la mia applicazione "Windows 10" consapevole.

E è la seguente:

<?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> 

ho ottenuto che da questo link: https://msdn.microsoft.com/fr-fr/library/windows/desktop/dn481241(v=vs.85).aspx

E TOSVersion.Tostring su un Windows 10 1607 schermi:

Windows (Version 10.0, Build 14393, 64-bit Edition) 
Problemi correlati