visual-c++ microsoft - Rileva se Visual C++Redistributable per Visual Studio 2012 è installato




2015 windows (16)

Provare

HKLM\SOFTWARE\Microsoft\DevDiv\VC\Servicing\11.0

come punto di partenza. Lo userò come controllo per l'installazione del runtime VC ++ 11 (VS 2012).

Come rilevare se Visual C ++ Redistributable per Visual Studio 2012 è installato?

Ho provato su Google e nessuno ha fatto questa domanda, sorpresa!


La risposta a queste semplici domande non è purtroppo semplice, ma funziona nel 100% di tutti i sistemi, ed è persino estendibile ai numerosi framework .net.

La complessità deriva dal fatto che ci sono (e sono state) molte revisioni VC runtime che potrebbero portare al caso che sebbene i runtime VC10 siano stati installati, il loro numero di build non era abbastanza recente così il tuo EXE non si avvierebbe a meno che tu non abbia installato esatti tempi di esecuzione richiesti o uno dei runtime più recenti che consente a questa e alle precedenti versioni di utilizzare la stessa versione principale (l'inferno side-by-side). Inoltre, se si dispone di un EXE a 64 bit, è necessario verificare entrambi i runtime a 32 e 64 bit.

Detto questo, l'unico modo affidabile per determinare se i runtime per il tuo EXE sono installati è provare ad eseguire l'EXE - o un altro EXE che è costruito con le stesse impostazioni del tuo EXE principale e il cui unico scopo è fare - niente. Basta eseguire (il che significa che i runtime sono installati) o non riescono a funzionare (quando non è installato).

Ho eseguito le seguenti operazioni per un programma di installazione che richiedeva l'installazione dei runtime VC10 a 32 e 64 bit: Il programma di installazione tenta di avviare tutti i file EXE fittizi e, in caso di esito positivo, il runtime corrispondente viene considerato installato. Questo risolve anche lo scenario a 32/64 bit.

Questo, tra l'altro, funziona anche per determinare se il framework .net corretto è installato, il che è molto complicato in Windows 8 e 10, poiché il supporto integrato .net 3.5 supporta anche le versioni .net 3.0 e 2.0 - non ci sono voci di registro per questi. (E peggio ancora, non puoi nemmeno usare i programmi di installazione standard qui, devi usare il supporto integrato e scaricarlo via Windows, o ricostruire la tua app con .net 4, ma questa è un'altra storia).

L'EXE fittizio C ++ può essere creato utilizzando un progetto con il seguente codice (e un altro in una configurazione a 64 bit se necessario):

int _tmain(int argc, _TCHAR* argv[])
{
    return 0;
}

Ricordarsi di impostare le proprietà del progetto Utilizzo di MFC per l' utilizzo di MFC in una DLL condivisa . I file eseguibili avranno dimensioni di circa 4KB: un piccolo prezzo da pagare per un risultato sicuro.

Per offrire agli utenti una buona esperienza di installazione, è possibile fare quanto segue (il codice di esempio è per NSIS ):

Function TryLaunchApplication
  Pop $1 ; pathname
  nsExec::Exec $1
  Pop $0

  ${If} $0 == "error"
  ${OrIf} $0 != 0
    Push 0
  ${Else}
    Push 1
  ${EndIf}
FunctionEnd

e chiamarlo in una funzione, ad esempio, CheckRuntimes

Function CheckRuntimes
  ; Try to execute VC++ 10 application (32 bit)
  Push "Vc10RuntimeCheckerApp.exe"
  Call TryLaunchApplication
  Pop $Vc10RuntimesFound

  ; Add 64 bit check if required.
  ; Remember to try running the 64 bit EXE only on a 64 bit OS,
  ; which requires further checks.

  ; Try to execute .net application
  Push "DotNetRuntimeCheckerApp.exe"
  Call TryLaunchApplication
  Pop $DotNetFrameworkFound
FunctionEnd

Quindi avviare il controllo di runtime, ad esempio quando si esce dalla pagina di benvenuto e si memorizza il risultato nella cache, quindi non è necessario ricontrollare ogni volta che l'utente fa clic sul pulsante "Indietro" e "Avanti".

Quindi, creare una sezione di sola lettura nell'albero di installazione e preselezionarla o deselezionarla in una funzione che viene eseguita prima che venga visualizzata la pagina Componenti .

Ciò assicurerà che l'installazione di ciascun componente runtime mancante sia obbligatoria e verrà saltata se già presente.


Dipende dalla versione che stai usando. Queste due chiavi 2012 hanno funzionato bene con le versioni corrispondenti da scaricare per l'aggiornamento 4. Si prega di notare che alcune di queste posizioni possono essere dipendenti dal sistema operativo. Ho raccolto queste informazioni da una scatola x 10 di Windows 10 . Sto andando avanti e scarico tutte queste versioni redist e le chiavi di registro che cerco per rilevare l'installazione .:

Visual C ++ 2005

Microsoft Visual C++ 2005 Redistributable (x64)
Registry Key: HKLM\SOFTWARE\Classes\Installer\Products\1af2a8da7e60d0b429d7e6453b3d0182
Configuration: x64
Version: 6.0.2900.2180

URL di download diretto: https://download.microsoft.com/download/8/B/4/8B42259F-5D70-43F4-AC2E-4B208FD8D66A/vcredist_x64.EXE

Microsoft Visual C++ 2005 Redistributable (x86)
Registry Key: HKLM\SOFTWARE\Classes\Installer\Products\c1c4f01781cc94c4c8fb1542c0981a2a 
Configuration: x86
Version: 6.0.2900.2180

URL di download diretto: https://download.microsoft.com/download/8/B/4/8B42259F-5D70-43F4-AC2E-4B208FD8D66A/vcredist_x86.EXE

Visual C ++ 2008

Microsoft Visual C++ 2008 Redistributable (x64)
Registry Key: HKLM\SOFTWARE\Classes\Installer\Products\67D6ECF5CD5FBA732B8B22BAC8DE1B4D 
Configuration: x64
Version: 9.0.30729.5677

URL di download diretto: https://download.microsoft.com/download/5/D/8/5D8C65CB-C849-4025-8E95-C3966CAFD8AE/vcredist_x64.exe

Microsoft Visual C++ 2008 Redistributable (x86)
Registry Key: HKLM\SOFTWARE\Classes\Installer\Products\6E815EB96CCE9A53884E7857C57002F0
Configuration: x86
Version: 9.0.30729.5677

URL di download diretto: https://download.microsoft.com/download/5/D/8/5D8C65CB-C849-4025-8E95-C3966CAFD8AE/vcredist_x86.exe

Visual C ++ 2010

Microsoft Visual C++ 2010 Redistributable (x64)
Registry Key: HKLM\SOFTWARE\Classes\Installer\Products\1926E8D15D0BCE53481466615F760A7F 
Configuration: x64
Version: 10.0.40219.325

URL di download diretto: https://download.microsoft.com/download/1/6/5/165255E7-1014-4D0A-B094-B6A430A6BFFC/vcredist_x64.exe

Microsoft Visual C++ 2010 Redistributable (x86)
Registry Key: HKLM\SOFTWARE\Classes\Installer\Products\1D5E3C0FEDA1E123187686FED06E995A 
Configuration: x86
Version: 10.0.40219.325

URL di download diretto: https://download.microsoft.com/download/1/6/5/165255E7-1014-4D0A-B094-B6A430A6BFFC/vcredist_x86.exe

Visual C ++ 2012

Microsoft Visual C++ 2012 Redistributable (x64)
Registry Key: HKLM\SOFTWARE\Classes\Installer\Dependencies\{ca67548a-5ebe-413a-b50c-4b9ceb6d66c6} 
Configuration: x64
Version: 11.0.61030.0

URL di download diretto: https://download.microsoft.com/download/1/6/B/16B06F60-3B20-4FF2-B699-5E9B7962F9AE/VSU_4/vcredist_x64.exe

Microsoft Visual C++ 2012 Redistributable (x86)
Registry Key: HKLM\SOFTWARE\Classes\Installer\Dependencies\{33d1fd90-4274-48a1-9bc1-97e33d9c2d6f} 
Configuration: x86
Version: 11.0.61030.0

URL di download diretto: https://download.microsoft.com/download/1/6/B/16B06F60-3B20-4FF2-B699-5E9B7962F9AE/VSU_4/vcredist_x86.exe

Visual C ++ 2013

Microsoft Visual C++ 2013 Redistributable (x64)
Registry Key: HKLM\SOFTWARE\Classes\Installer\Dependencies\{050d4fc8-5d48-4b8f-8972-47c82c46020f} 
Configuration: x64
Version: 12.0.30501.0

URL di download diretto: https://download.microsoft.com/download/2/E/6/2E61CFA4-993B-4DD4-91DA-3737CD5CD6E3/vcredist_x64.exe

Microsoft Visual C++ 2013 Redistributable (x86)
Registry Key: HKLM\SOFTWARE\Classes\Installer\Dependencies\{f65db027-aff3-4070-886a-0d87064aabb1} 
Configuration: x86
Version: 12.0.30501.0

URL di download diretto: https://download.microsoft.com/download/2/E/6/2E61CFA4-993B-4DD4-91DA-3737CD5CD6E3/vcredist_x86.exe

Visual C ++ 2015

Microsoft Visual C++ 2015 Redistributable (x64) - 14.0.24215
Registry Key: HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Installer\Dependencies\{d992c12e-cab2-426f-bde3-fb8c53950b0d}
Configuration: x64
Version: 14.0.24215.1

URL di download diretto: https://download.microsoft.com/download/6/A/A/6AA4EDFF-645B-48C5-81CC-ED5963AEAD48/vc_redist.x64.exe

Microsoft Visual C++ 2015 Redistributable (x86) - 14.0.24215
Registry Key: HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Installer\Dependencies\{e2803110-78b3-4664-a479-3611a381656a}
Configuration: x86
Version: 14.0.24215.1

URL di download diretto: https://download.microsoft.com/download/6/A/A/6AA4EDFF-645B-48C5-81CC-ED5963AEAD48/vc_redist.x86.exe

Visual C ++ 2017

Avvertenza : è in uso una nuova convenzione di registro 2017, o non ancora finalizzata. Come sto indovinando le chiavi più in alto di: [HKEY_CLASSES_ROOT\Installer\Dependencies\,,amd64,14.0,bundle] e [HKEY_CLASSES_ROOT\Installer\Dependencies\,,x86,14.0,bundle]

sono soggetti a modifiche, o almeno hanno GUID nidificati diversi, ho intenzione di utilizzare l'elenco della chiave che termina con un GUID.

Microsoft Visual C++ 2017 Redistributable (x64) - 14.14.26405
Registry Key: [HKEY_CLASSES_ROOT\Installer\Dependencies\,,amd64,14.0,bundle\Dependents\{5b295ba9-ef89-4aeb-8acc-b61adb0b9b5f}]
Configuration: x64
Version: 14.14.26405.0

URL di download diretto: https://download.visualstudio.microsoft.com/download/pr/12192820/2cd2dba5748dc95950a5c42c2d2d78e4/VC_redist.x64.exe

Microsoft Visual C++ 2017 Redistributable (x86) - 14.14.26405
Registry Key: [HKEY_CLASSES_ROOT\Installer\Dependencies\,,x86,14.0,bundle\Dependents\{ec9c2282-a836-48a6-9e41-c2f0bf8d678b}]
Configuration: x86
Version: 14.14.26405.0

URL di download diretto: https://download.visualstudio.microsoft.com/download/pr/12192785/88b50ce70017bf10f2d56d60fcba6ab1/VC_redist.x86.exe

Changelog :
16 maggio 2018 - Aggiornamento della versione 2017 per 14.14.26405.0 come nuova voce di C ++ 2017
8 settembre 2017 - Aggiornamento della versione 2017 per 14.11.25325.0 come nuova voce di Visual C ++ 2017
7 aprile 2017 - Aggiornata la versione 2017 di 14.10.25008.0 come nuova voce di Visual C ++ 2017
24 ottobre 2016 - Aggiornate le informazioni sulla versione 2015 per 14.0.24215.1
18 agosto 2016 - Aggiornate le informazioni sulla versione 2015 per 14.0.24212
27 maggio 2016: informazioni aggiornate per l'aggiornamento 2 di MSVC2015

Per favore contattami qui se qualcuno di questi diventa obsoleto.


Sono riuscito a farlo con InnoSetup.

Ho controllato l'esistenza della chiave di registro:

HKLM\SOFTWARE\Microsoft\VisualStudio\11.0\VC\Runtimes

Se disinstallato, non esiste. Se installato, esiste.

A proposito, potrebbe anche essere nel Wow6432Node:

HKLM\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\11.0\VC\Runtimes


Controllare lo stato di installazione del prodotto tramite MsiQueryProductState equivale a controllare direttamente il registro, ma è comunque necessario il GUID per ProductCode .

Come accennato altrove, uno svantaggio di questi approcci è che ogni aggiornamento ha il proprio ProductCode!

Per fortuna, MSI fornisce un UpgradeCode che identifica una "famiglia" di prodotti. Puoi usare orca per aprire uno degli MSI per estrarre queste informazioni. Ad esempio, UpgradeCode per la ridistribuibile di VS2015 è {65E5BD06-6392-3027-8C26-853107D3CF1A}

È possibile utilizzare MsiEnumRelatedProducts per ottenere tutti gli ID prodotto per tale UpgradeCode. In pratica, poiché ogni aggiornamento redistore sostituisce il precedente, questo produrrà solo un ProductCode, ad esempio {B5FC62F5-A367-37A5-9FD2-A6E137C0096F} per VS2015 Update 2 x86.

Indipendentemente da ciò, è possibile controllare la versione tramite MsiGetProductInfo (productCode, INSTALLPROPERTY_VERSIONSTRING, ...) o funzioni simili da confrontare con la versione desiderata, ad esempio per verificare una versione equivalente o successiva.

Nota che all'interno di un'applicazione C ++ puoi usare _VC_CRT_MAJOR_VERSION , _VC_CRT_MINOR_VERSION , _VC_CRT_BUILD_VERSION se #include <crtversion.h> - in questo modo puoi determinare calcolare la versione CRT con cui è stato costruito il tuo binario.


Avevo bisogno della stessa cosa, e anche se AFAIK non può essere fatto a livello di programmazione, ha funzionato per me.

Sono appena andato su Start -> Disinstalla un programma, e ho fatto scorrere verso il basso fino a quando ho trovato il ridistribuibile VC ++, che include un numero di versione. Googling il numero di versione, mi ha detto che appartiene a VS2012 SP1.


Per me questa posizione ha funzionato: HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ DevDiv \ vc \ Servicing \ 11.0 \ RuntimeMinimum \ Version

Verifica quale versione hai dopo aver installato il pacchetto e utilizzalo come condizione nel tuo programma di installazione. (il mio è impostato su 11.0.50727 dopo l'installazione di VCred).


puoi cercare nel registro. In realtà non ho vs2012 ma ho vs2010.

Esistono 3 diverse (ma molto simili) chiavi di registro per ciascuno dei 3 pacchetti della piattaforma. Ogni chiave ha un valore DWORD chiamato "Installato" con valore 1.

  • HKLM \ SOFTWARE \ Microsoft \ VisualStudio \ 10.0 \ VC \ VCRedist \ x86

  • HKLM \ SOFTWARE \ Microsoft \ VisualStudio \ 10.0 \ VC \ VCRedist \ x64

  • HKLM \ SOFTWARE \ Microsoft \ VisualStudio \ 10.0 \ VC \ VCRedist \ ia64

Puoi usare la funzione di registro per quello ......


Mi sono imbattuto in questa domanda alla ricerca di una risposta nel contesto della verifica della ridistribuzione di Visual C ++ come parte di un programma di installazione MSI creato da WiX.

Non mi piace come il GUID cambi con la versione e il sistema operativo, quindi ho finito per creare un'azione personalizzata scritta in C # per verificare la ridistribuzione di Visual C ++.

Tutto quanto segue è specifico per Visual C ++ 2015 Redistributable (x64), ma può essere facilmente modificato per qualsiasi versione.

using Microsoft.Deployment.WindowsInstaller;
using Microsoft.Win32;

namespace CustomActions
{
    public class DependencyChecks
    {
        [CustomAction]
        public static ActionResult IsVC2015RedistInstalled(Session session)
        {
            session.Log("Begin Visual C++ 2015 Redistributable installation check.");

            var dependenciesKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Classes\\Installer\\Dependencies");

            foreach(var subKey in dependenciesKey.GetSubKeyNames())
            {
                var dependency = dependenciesKey.OpenSubKey(subKey);
                var displayName = (string)dependency.GetValue("DisplayName");
                if(displayName != null)
                {
                    if (displayName.Contains("Microsoft Visual C++ 2015 Redistributable (x64)"))
                    {
                        session.Log("Visual C++ 2015 Redistributable is installed.");
                        return ActionResult.Success;
                    }
                }
            }

            session.Log("Visual C++ 2015 Redistributable is not installed.");
            session.Message(InstallMessage.Error, new Record(1, "This application requires Visual C++ 2015 Redistributable. Please install, then run this installer again. https://www.microsoft.com/en-us/download/details.aspx?id=53587"));
            return ActionResult.Failure;
        }
    }
}

Quindi nel file wxs

<Binary Id='VC2015RedistCheck' SourceFile='!(wix.ResourcesDir=resources)\CustomActions.CA.dll'/>
    <CustomAction
      Id='VC2015RedistCheckAction'
      Execute='immediate'
      BinaryKey='VC2015RedistCheck'
      DllEntry="IsVC2015RedistInstalled"
      Return='check'/>

<InstallExecuteSequence>
  <Custom Action='VC2015RedistCheckAction' After='InstallInitialize'/>
</InstallExecuteSequence>

Basta andare su Pannello di controllo> Programmi e funzionalità, e appaiono tutti elencati lì.

Non sono un esperto e questa risposta è piuttosto semplice rispetto a quello che le persone stanno rispondendo (controllando il registro), quindi non sono sicuro che sia la risposta corretta ma ha fatto il trucco per me.


Ciò che più manca alla gente è il /reg:32 richiesto /reg:32 per verificare la chiave su Windows x64.

Consulta l' articolo dell'assistenza Microsoft su questo argomento.

Ecco uno script che dimostra come verificare correttamente la presenza di Visual C ++ Redistributable per Visual Studio 2012 Update 4.

@ECHO OFF

:Author
REM "CREATED BY WAR59312"
REM "FEB 7th 2017"

REM Clear Screen
CLS

TITLE Detect Visual C++ 2012 Redistributables

REM This Batch Script Detects If Visual C++ Redistributable for Visual Studio 2012 Update 4 Is Installed

:DetectWindowsOS
REM Are We Running On x86 Or x64
IF NOT DEFINED PROCESSOR_ARCHITEW6432 (
IF %PROCESSOR_ARCHITECTURE% EQU x86 (
REM Windows Is x86
GoTo Check32Bit
) ELSE (
REM Windows Is x64
SET NeededFor64BitOnly=/reg:32
GoTo Check64Bit
)) ELSE (
REM Windows Is Unknown But Assume x64 To Be Safe
SET NeededFor64BitOnly=/reg:32
GoTo Check64Bit
)

:Check64Bit
REM Checks If Visual C++ 64Bit Redistributable for Visual Studio 2012 Update 4 Is Installed
REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\11.0\VC\Runtimes\x64" /v "Version" %NeededFor64BitOnly% 2>NUL^ | (
  FIND "v11.0.61030.00" >NUL
) && (
  ECHO.
  ECHO 64bit Visual C++ Redistributable for Visual Studio 2012 Update 4 Is Installed
  ECHO.
  GoTo Check32Bit
) || (
   ECHO.
   ECHO 64bit Visual C++ Redistributable for Visual Studio 2012 Update 4 Is NOT Installed
   ECHO.
   GoTo Check32Bit
)

:Check32Bit
REM Checks If Visual C++ 32Bit Redistributable for Visual Studio 2012 Update 4 Is Installed
REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\11.0\VC\Runtimes\x86" /v "Version" %NeededFor64BitOnly% 2>NUL^ | (
  FIND "v11.0.61030.00" >NUL
) && (
   ECHO.
   ECHO 32bit Visual C++ Redistributable for Visual Studio 2012 Update 4 Is Installed
) || (
   ECHO.
   ECHO 32bit Visual C++ Redistributable for Visual Studio 2012 Update 4 Is NOT Installed
)

:END
ECHO.
PAUSE

EXIT

if RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\10.0\VC\VCRedist\x86","Installed") = 0 Then
  if RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\11.0\VC\Runtimes\x86","Installed") = 0 Then

Dal momento che Visual Studio 2010 e successivi hanno smesso di utilizzare WinSxS, potrebbe essere sufficiente controllare solo% windir% \ system32 \ msvcr110.dll. Se si desidera verificare di avere una versione abbastanza nuova, è possibile verificare se la versione del file è 11.0.50727.1 (VS2012 RTM) o 11.0.51106.1 (VS2012 Update 1).


Non è presente alcun elemento installcheck nel manifest del pacchetto bootstrapper fornito con Visual C ++. Indovina Microsoft vorrebbe installare sempre se lo si imposta come prerequisito.

Naturalmente è ancora possibile chiamare MsiQueryProductState per verificare se il pacchetto di redistore VC è installato tramite MSI, Il codice del pacchetto può essere trovato eseguendo

wmic product get

alla riga di comando, o se sei già su wmic: root \ cli, esegui

product where "Caption like '%C++ 2012%'"

È possibile verificare che il valore Installed sia 1 in questa posizione del Registro di sistema: HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\11.0\VC\Runtimes\x86 su sistemi a 64 bit. Nel codice che risulterebbe nell'accesso alla chiave di registro HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\11.0\VC\Runtimes\x86 . Si noti l'assenza di Wow6432Node .

Su un sistema a 32 bit il registro è lo stesso senza Wow6432Node : HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\11.0\VC\Runtimes\x86


La domanda di base è "perché chiami GetVersionExW in primo luogo?" La risposta a questa domanda determina invece cosa dovresti fare.

L'avvertimento di deprecazione è lì per dare agli sviluppatori un'idea del cambiamento di comportamento dell'appcompat che è iniziato in Windows 8.1. Consulta il ricettario sulla compatibilità di Windows e Windows Server: Windows 8, Windows 8.1 e Windows Server 2012 . In breve, quella funzione non restituisce quello che pensi che ritorni di default.

Storicamente, i controlli della versione del sistema operativo scritti male sono la fonte primaria di bug appcompat per gli aggiornamenti del sistema operativo Windows. Ci sono stati diversi approcci per tentare di mitigare questo problema (la versione di AppVerifier, l'API di VerifyVersionInfo , ecc.) E questo è il più aggressivo fino ad oggi.

VersionHelpers.h menzionato nei commenti si trova nell'SDK di Windows 8.1 fornito con Visual Studio 2013. Non sono una nuova API; sono solo codice di utilità che utilizza l'API di VerifyVersionInfo introdotta in Windows 2000. Queste funzioni servono per eseguire controlli di stile "Devi essere così in alto per cavalcare" che sono la classe di verifiche di versione che sono più spesso scritte male. Il codice è piuttosto semplice. Ad esempio, il test IsWindowsVistaSP2OrGreater è:

VERSIONHELPERAPI
IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor)
{
    OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0, {0}, 0, 0 };
    DWORDLONG        const dwlConditionMask = VerSetConditionMask(
        VerSetConditionMask(
        VerSetConditionMask(
            0, VER_MAJORVERSION, VER_GREATER_EQUAL),
               VER_MINORVERSION, VER_GREATER_EQUAL),
               VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);

    osvi.dwMajorVersion = wMajorVersion;
    osvi.dwMinorVersion = wMinorVersion;
    osvi.wServicePackMajor = wServicePackMajor;

    return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE;
}

VERSIONHELPERAPI
IsWindowsVistaSP2OrGreater()
{
    return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 2);
}

Non è necessario utilizzare VersionHelpers.h come si potrebbe semplicemente fare questo tipo di codice da soli, ma sono convenienti se si sta già utilizzando il compilatore VS 2013. Per i giochi, ho un articolo Cosa c'è in un numero di versione? che usa VerifyVersionInfo per fare il tipo di controlli ragionevoli che si dovrebbero fare per la distribuzione del gioco.

Nota se stai utilizzando VS 2013 con il set di strumenti della piattaforma v120_xp per il targeting di Windows XP, effettivamente utilizzerai l'SDK di Windows 7.1A e #include <VersionHelpers.h> non funzionerà. Ovviamente VerifyVersionInfo utilizzare direttamente VerifyVersionInfo .

L'altro uso principale di GetVersionExW è registri diagnostici e telemetria. In questo caso, un'opzione è quella di continuare a utilizzare tale API e assicurarsi di disporre delle giuste voci manifest nell'applicazione per garantire risultati ragionevolmente accurati. Vedi Manifest Madness per i dettagli su ciò che fai qui per raggiungere questo obiettivo. La cosa principale da tenere a mente è che, a meno che tu non aggiorni periodicamente il tuo codice, alla fine non riuscirai a ottenere informazioni completamente accurate in una versione futura del sistema operativo.

Tieni presente che è consigliabile inserire la sezione <compatibility> in un manifest incorporato, indipendentemente dal fatto che ti interessino i risultati di GetVersionEx come best practice generale. Ciò consente al sistema operativo di applicare automaticamente le future correzioni appcompat in base alla conoscenza di come l'app è stata originariamente testata.

Per i log diagnostici, un altro approccio che potrebbe essere un po 'più robusto è quello di prendere il numero di versione da una DLL di sistema come kernel32.dll usando GetFileVersionInfoW . Questo approccio ha una grossa grana: non provare l'analisi, fare paragoni o fare ipotesi sul codice in base alla versione del file ottenuta in questo modo; scrivilo da qualche parte . In caso contrario, si rischia di ricreare lo stesso problema di controllo della versione del sistema operativo che è stato risolto meglio con VerifyVersionInfo . Questa opzione non è disponibile per le app di Windows Store, le app per Windows Phone, ecc., Ma dovrebbe funzionare per le app desktop Win32.

#include <windows.h>
#include <stdint.h>
#include <memory>

#pragma comment(lib, "version.lib" )

bool GetOSVersionString( WCHAR* version, size_t maxlen )
{
    WCHAR path[ _MAX_PATH ];
    if ( !GetSystemDirectoryW( path, _MAX_PATH ) )
        return false;

    wcscat_s( path, L"\\kernel32.dll" );

    //
    // Based on example code from this article
    // http://support.microsoft.com/kb/167597
    //

    DWORD handle;
#if (_WIN32_WINNT >= _WIN32_WINNT_VISTA)
    DWORD len = GetFileVersionInfoSizeExW( FILE_VER_GET_NEUTRAL, path, &handle );
#else
    DWORD len = GetFileVersionInfoSizeW( path, &handle );
#endif
    if ( !len )
        return false;

    std::unique_ptr<uint8_t> buff( new (std::nothrow) uint8_t[ len ] );
    if ( !buff )
        return false;

#if (_WIN32_WINNT >= _WIN32_WINNT_VISTA)
    if ( !GetFileVersionInfoExW( FILE_VER_GET_NEUTRAL, path, 0, len, buff.get() ) )
#else
    if ( !GetFileVersionInfoW( path, 0, len, buff.get() ) )
#endif
        return false;

    VS_FIXEDFILEINFO *vInfo = nullptr;
    UINT infoSize;

    if ( !VerQueryValueW( buff.get(), L"\\", reinterpret_cast<LPVOID*>( &vInfo ), &infoSize ) )
        return false;

    if ( !infoSize )
        return false;

    swprintf_s( version, maxlen, L"%u.%u.%u.%u",
                HIWORD( vInfo->dwFileVersionMS ),
                LOWORD(vInfo->dwFileVersionMS),
                HIWORD(vInfo->dwFileVersionLS),
                LOWORD(vInfo->dwFileVersionLS) );

    return true;
}

Se c'è qualche altra ragione che chiami GetVersionExW , probabilmente non dovresti chiamarlo. Il controllo di un componente che potrebbe mancare non dovrebbe essere legato a un controllo di versione. Ad esempio, se la tua applicazione richiede Media Foundation, devi impostare "Devi essere così in alto per superare questo controllo" come IsWindowsVistaOrGreater per la distribuzione, ma in fase di esecuzione dovresti utilizzare il collegamento esplicito tramite LoadLibrary o LoadLibaryEx per segnalare un errore o utilizzare un fallback se MFPLAT.DLL non viene trovato.

Il collegamento esplicito non è un'opzione per le app di Windows Store. Windows 8.x risolve questo particolare problema avendo uno stub MFPLAT.DLL e MFStartUp restituirà E_NOTIMPL. Vedi "Chi ha spostato il mio [Windows Media] Cheese"?

Un altro esempio: se la tua applicazione vuole utilizzare Direct3D 11.2 se è disponibile e utilizza in altro modo DirectX 11.0, devi utilizzare una IsWindowsVistaSP2OrGreater minima IsWindowsVistaSP2OrGreater per l'implementazione, magari utilizzando D3D11InstallHelper . Quindi, in fase di runtime, dovresti creare il dispositivo DirectX 11.0 e, se fallisce, devi segnalare un errore. Se ottieni un ID3D11Device , avresti QueryInterface per un ID3D11Device2 che, se riesce, significa che stai utilizzando un sistema operativo che supporta DirectX 11.2. Vedi Anatomia di Direct3D 11 Crea dispositivo .

Se questa ipotetica applicazione Direct3D supporta Windows XP, si utilizzerà una barra di distribuzione di IsWindowsXPSP2OrGreater o IsWindowsXPSP3OrGreater , quindi in fase di esecuzione utilizzare il collegamento esplicito per cercare di trovare D3D11.DLL . Se non fosse presente, ricorreremo a Direct3D 9 - poiché impostiamo la barra minima, sappiamo che DirectX 9.0c o versioni successive è sempre presente.

Il loro punto chiave qui è che nella maggior parte dei casi non dovresti usare GetVersionEx .

Nota che con Windows 10 , VerifyVersionInfo e ottenere il timbro della versione del file tramite GetFileVersionInfo per kernel32.lib sono ora soggetti allo stesso comportamento manifest di GetVersionEx (cioè senza GUID manifest per Windows 10, restituisce risultati come se la versione del sistema operativo fosse 6.2 piuttosto che 10.0).

Per le app di Windows universali su Windows 10, è possibile utilizzare una nuova API AnalyticsInfo WinRT per ottenere una stringa del timbro di versione per i log diagnostici e la telemetria.







visual-c++