Versioni delle DLL di shell e Shlwapi

In questa sezione viene descritto come determinare la versione delle DLL shell in esecuzione nell'applicazione e come eseguire la destinazione dell'applicazione per una versione specifica.

Numeri di versione DLL

Tutti gli elementi di programmazione descritti nella documentazione di Shell sono contenuti in due DLL: Shell32.dll e Shlwapi.dll. A causa dei miglioramenti in corso, diverse versioni di queste DLL implementano funzionalità diverse. Nella documentazione di riferimento di Shell ogni elemento di programmazione specifica un numero minimo di versione DLL supportato. Questo numero di versione indica che l'elemento di programmazione viene implementato in tale versione e nelle versioni successive della DLL, a meno che non sia specificato diversamente. Se non viene specificato alcun numero di versione, l'elemento di programmazione viene implementato in tutte le versioni esistenti della DLL.

Prima di Windows XP, le nuove versioni di Shell32.dll e Shlwapi.dll sono state talvolta fornite con nuove versioni di Windows Internet Explorer. A partire da Windows XP, tali DLL non sono più state fornite come file ridistribuibili all'esterno delle nuove versioni di Windows stesso. Nella tabella seguente vengono descritte le diverse versioni dll e il modo in cui sono stati distribuiti a Microsoft Internet Explorer 3.0, Windows 95 e Microsoft Windows NT 4.0.

Shell32.dll versione 4.0 è disponibile nelle versioni originali di Windows 95 e Microsoft Windows NT 4.0. Shell non è stato aggiornato con la versione di Internet Explorer 3.0, quindi Shell32.dll non ha una versione 4.70. Shell32.dll versioni 4.71 e 4.72 sono state fornite con le versioni corrispondenti di Internet Explorer, ma non sono necessariamente installate (vedere la nota 1). Per le versioni successive a Microsoft Internet Explorer 4.01 e Windows 98, i numeri di versione per Shell32.dll e Shlwapi.dll diverge. In generale, è consigliabile presupporre che le DLL abbiano numeri di versione diversi e testarne ognuna separatamente.

Shell32.dll

Versione Piattaforma di distribuzione
4,0 Windows 95 e Microsoft Windows NT 4.0
4.71 Microsoft Internet Explorer 4.0. Vedere la nota 1.
4.72 Internet Explorer 4.01 e Windows 98. Vedere la nota 1.
5.0 Windows 2000 e Windows Millennium Edition (Windows Me). Vedere la nota 2.
6.0 Windows XP
6.0.1 Windows Vista
6.1 Windows 7

Shlwapi.dll

Versione Piattaforma di distribuzione
4,0 Windows 95 e Microsoft Windows NT 4.0
4.71 Internet Explorer 4.0. Vedere la nota 1.
4.72 Internet Explorer 4.01 e Windows 98. Vedere la nota 1.
4.7 Internet Explorer 3.x
5.0 Microsoft Internet Explorer 5 e Windows 98 SE. Vedere la nota 2.
5.5 Microsoft Internet Explorer 5.5 e Windows Millennium Edition (Windows Me)
6.0 Windows XP e Windows Vista

Nota 1: Tutti i sistemi con Internet Explorer 4.0 o 4.01 avevano rispettivamente la versione associata di Shlwapi.dll (4.71 o 4.72). Tuttavia, per i sistemi precedenti a Windows 98, Internet Explorer 4.0 e 4.01 possono essere installati con o senza ciò che era noto come shell integrata. Se Internet Explorer è stato installato con shell integrata, è stata installata anche la versione associata di Shell32.dll (4.71 o 4.72). Se Internet Explorer è stato installato senza shell integrata, Shell32.dll è rimasto come versione 4.0. In altre parole, la presenza della versione 4.71 o 4.72 di Shlwapi.dll in un sistema non garantisce che Shell32.dll abbia lo stesso numero di versione. Tutti i sistemi Windows 98 hanno la versione 4.72 di Shell32.dll.

Nota 2: La versione 5.0 di Shlwapi.dll è stata distribuita con Internet Explorer 5 ed è stata trovata in tutti i sistemi in cui è stato installato Internet Explorer 5, ad eccezione di Windows 2000. La versione 5.0 di Shell32.dll è stata distribuita in modo nativo con Windows 2000 e Windows Millennium Edition (Windows Me), insieme alla versione 5.0 di Shlwapi.dll.

Uso di DllGetVersion per determinare il numero di versione

A partire dalla versione 4.71, le DLL shell, tra le altre, hanno iniziato ad esportare DllGetVersion. Questa funzione può essere chiamata da un'applicazione per determinare quale versione DLL è presente nel sistema.

Nota

Le DLL non esportano necessariamente DllGetVersion. Testa sempre per esso prima di tentare di usarlo.

Per le versioni di Windows precedenti a Windows 2000, DllGetVersion restituisce una struttura DLLVERSIONINFO contenente i numeri di versione principali e secondari, il numero di compilazione e un ID piattaforma. Per i sistemi Windows 2000 e versioni successive, DllGetVersion potrebbe invece restituire una struttura DLLVERSIONINFO2 . Oltre alle informazioni fornite tramite DLLVERSIONINFO, DLLVERSIONINFO2 fornisce anche il numero di hotfix che identifica il Service Pack installato più recente, che offre un modo più affidabile per confrontare i numeri di versione. Poiché il primo membro di DLLVERSIONINFO2 è una struttura DLLVERSIONINFO , la struttura successiva è compatibile con le versioni precedenti.

Uso di DllGetVersion

La funzione GetVersion di esempio seguente carica una DLL specificata e tenta di chiamare la funzione DllGetVersion . In caso di esito positivo, usa una macro per creare il pacchetto dei numeri di versione principali e secondari dalla struttura DLLVERSIONINFO in una DWORD restituita all'applicazione chiamante. Se la DLL non esporta DllGetVersion, la funzione restituisce zero. Con i sistemi Windows 2000 e versioni successive, è possibile modificare la funzione per gestire la possibilità che DllGetVersion restituisce una struttura DLLVERSIONINFO2 . In tal caso, usare le informazioni contenute nel membro ullVersion della struttura DLLVERSION2 per confrontare le versioni, i numeri di compilazione e le versioni del Service Pack. La macro MAKEDLLVERULL semplifica l'attività di confronto di questi valori a quelli in ullVersion.

Nota

L'uso di LoadLibrary in modo errato può rappresentare rischi di sicurezza. Per informazioni su come caricare correttamente le DLL con versioni diverse di Windows, vedere la documentazione di LoadLibrary .

#include "stdafx.h"
#include "windows.h"
#include "windef.h"
#include "winbase.h"
#include "shlwapi.h"

#define PACKVERSION(major,minor) MAKELONG(minor,major)

DWORD GetVersion(LPCTSTR lpszDllName)
{
    HINSTANCE hinstDll;
    DWORD dwVersion = 0;

    /* For security purposes, LoadLibrary should be provided with a fully qualified 
       path to the DLL. The lpszDllName variable should be tested to ensure that it 
       is a fully qualified path before it is used. */
    hinstDll = LoadLibrary(lpszDllName);
    
    if(hinstDll)
    {
        DLLGETVERSIONPROC pDllGetVersion;
        pDllGetVersion = (DLLGETVERSIONPROC)GetProcAddress(hinstDll, "DllGetVersion");

        /* Because some DLLs might not implement this function, you must test for 
           it explicitly. Depending on the particular DLL, the lack of a DllGetVersion 
           function can be a useful indicator of the version. */

        if(pDllGetVersion)
        {
            DLLVERSIONINFO dvi;
            HRESULT hr;

            ZeroMemory(&dvi, sizeof(dvi));
            dvi.info1.cbSize = sizeof(dvi);

            hr = (*pDllGetVersion)(&dvi);

            if(SUCCEEDED(hr))
            {
               dwVersion = PACKVERSION(dvi.info1.dwMajorVersion, dvi.info1.dwMinorVersion);
            }
        }
        FreeLibrary(hinstDll);
    }
    return dwVersion;
}

L'esempio di codice seguente illustra come è possibile usare GetVersion per testare se Shell32.dll è la versione 6.0 o successiva.

LPCTSTR lpszDllName = L"C:\\Windows\\System32\\Shell32.dll";
DWORD dwVer = GetVersion(lpszDllName);
DWORD dwTarget = PACKVERSION(6,0);

if(dwVer >= dwTarget)
{
    // This version of Shell32.dll is version 6.0 or later.
}
else
{
    // Proceed knowing that version 6.0 or later additions are not available.
    // Use an alternate approach for older the DLL version.
}

Versioni del progetto

Per assicurarsi che l'applicazione sia compatibile con versioni diverse di un file di .dll, le macro di versione sono presenti nei file di intestazione. Queste macro vengono usate per definire, escludere o ridefinire determinate definizioni per versioni diverse della DLL. Vedere Uso delle intestazioni di Windows per una descrizione approfondita di queste macro.

Ad esempio, il nome della macro _WIN32_IE viene comunemente trovato nelle intestazioni precedenti. È responsabile della definizione della macro come numero esadecimale. Questo numero di versione definisce la versione di destinazione dell'applicazione che usa la DLL. Nella tabella seguente vengono illustrati i numeri di versione disponibili e l'effetto che ogni oggetto ha sull'applicazione.

Versione Descrizione
0x0200 L'applicazione è compatibile con Shell32.dll versione 4.00 e successiva. L'applicazione non può implementare le funzionalità aggiunte dopo la versione 4.00.
0x0300 L'applicazione è compatibile con Shell32.dll versione 4.70 e successiva. L'applicazione non può implementare le funzionalità aggiunte dopo la versione 4.70.
0x0400 L'applicazione è compatibile con Shell32.dll versione 4.71 e successiva. L'applicazione non può implementare le funzionalità aggiunte dopo la versione 4.71.
0x0401 L'applicazione è compatibile con Shell32.dll versione 4.72 e successiva. L'applicazione non può implementare funzionalità aggiunte dopo la versione 4.72.
0x0500 L'applicazione è compatibile con Shell32.dll e Shlwapi.dll versione 5.0 e successiva. L'applicazione non può implementare funzionalità aggiunte dopo la versione 5.0 di Shell32.dll e Shlwapi.dll.
0x0501 L'applicazione è compatibile con Shell32.dll e Shlwapi.dll versione 5.0 e successiva. L'applicazione non può implementare funzionalità aggiunte dopo la versione 5.0 di Shell32.dll e Shlwapi.dll.
0x0600 L'applicazione è compatibile con Shell32.dll e Shlwapi.dll versione 6.0 e successiva. L'applicazione non può implementare funzionalità aggiunte dopo la versione 6.0 di Shell32.dll e Shlwapi.dll.

Se non si definisce la macro _WIN32_IE nel progetto, viene definita automaticamente come 0x0500. Per definire un valore diverso, è possibile aggiungere quanto segue alle direttive del compilatore nel file make; sostituire il numero di versione desiderato per 0x0400.

/D _WIN32_IE=0x0400

Un altro metodo consiste nell'aggiungere una riga simile al seguente nel codice sorgente prima di includere i file di intestazione shell. Sostituire il numero di versione desiderato per 0x0400.

#define _WIN32_IE 0x0400
#include <commctrl.h>