Versões de DLL do Shell e Shlwapi

Esta seção descreve como determinar em qual versão das DLLs do Shell seu aplicativo está em execução e como direcionar seu aplicativo para uma versão específica.

Números de versão de DLL

Todos, exceto alguns dos elementos de programação discutidos na documentação do Shell, estão contidos em duas DLLs: Shell32.dll e Shlwapi.dll. Devido a aprimoramentos contínuos, diferentes versões dessas DLLs implementam recursos diferentes. Em toda a documentação de referência do Shell, cada elemento de programação especifica um número mínimo de versão de DLL com suporte. Esse número de versão indica que o elemento de programação é implementado nessa versão e nas versões subsequentes da DLL, a menos que seja especificado de outra forma. Se nenhum número de versão for especificado, o elemento de programação será implementado em todas as versões existentes da DLL.

Antes do Windows XP, novas versões de Shell32.dll e Shlwapi.dll às vezes eram fornecidas com novas versões do Windows Internet Explorer. A partir do Windows XP, essas DLLs não eram mais fornecidas como arquivos redistribuíveis fora das novas versões do próprio Windows. A tabela a seguir descreve as diferentes versões de DLL e como elas foram distribuídas desde o Microsoft Internet Explorer 3.0, Windows 95 e Microsoft Windows NT 4.0.

Shell32.dll versão 4.0 é encontrada nas versões originais do Windows 95 e do Microsoft Windows NT 4.0. O Shell não foi atualizado com a versão da Internet Explorer 3.0, portanto, Shell32.dll não tem uma versão 4.70. Shell32.dll versões 4.71 e 4.72 foram enviadas com as versões de Explorer da Internet correspondentes, mas não foram necessariamente instaladas (consulte a observação 1). Para versões subsequentes ao Microsoft Internet Explorer 4.01 e Windows 98, os números de versão para Shell32.dll e Shlwapi.dll divergem. Em geral, você deve assumir que as DLLs têm números de versão diferentes e testar cada um separadamente.

Shell32.dll

Versão Plataforma de Distribuição
4,0 Windows 95 e Microsoft Windows NT 4.0
4,71 Microsoft Internet Explorer 4.0. Consulte a observação 1.
4.72 Internet Explorer 4.01 e Windows 98. Consulte a observação 1.
5,0 Windows 2000 e Windows Millennium Edition (Windows Me). Consulte a observação 2.
6,0 Windows XP
6.0.1 Windows Vista
6.1 Windows 7

Shlwapi.dll

Versão Plataforma de Distribuição
4,0 Windows 95 e Microsoft Windows NT 4.0
4,71 Internet Explorer 4.0. Consulte a observação 1.
4.72 Internet Explorer 4.01 e Windows 98. Consulte a observação 1.
4.7 Internet Explorer 3.x
5,0 Microsoft Internet Explorer 5 e Windows 98 SE. Consulte a observação 2.
5.5 Microsoft Internet Explorer 5.5 e Windows Millennium Edition (Windows Me)
6,0 Windows XP e Windows Vista

Observação 1: Todos os sistemas com a Internet Explorer 4.0 ou 4.01 tinham a versão associada de Shlwapi.dll (4.71 ou 4.72, respectivamente). No entanto, para sistemas anteriores ao Windows 98, a Internet Explorer 4.0 e 4.01 pode ser instalada com ou sem o que era conhecido como Shell integrado. Se o Explorer da Internet foi instalado com o Shell integrado, a versão associada do Shell32.dll (4.71 ou 4.72) também foi instalada. Se o Explorer da Internet foi instalado sem o Shell integrado, Shell32.dll permaneceu como a versão 4.0. Em outras palavras, a presença da versão 4.71 ou 4.72 de Shlwapi.dll em um sistema não garante que Shell32.dll tenha o mesmo número de versão. Todos os sistemas Windows 98 têm a versão 4.72 de Shell32.dll.

Observação 2: A versão 5.0 do Shlwapi.dll foi distribuída com a Internet Explorer 5 e foi encontrada em todos os sistemas nos quais a Internet Explorer 5 foi instalada, com exceção do Windows 2000. A versão 5.0 do Shell32.dll foi distribuída nativamente com o Windows 2000 e o Windows Millennium Edition (Windows Me), juntamente com a versão 5.0 do Shlwapi.dll.

Usando DllGetVersion para determinar o número de versão

A partir da versão 4.71, as DLLs do Shell, entre outras, começaram a exportar DllGetVersion. Essa função pode ser chamada por um aplicativo para determinar qual versão de DLL está presente no sistema.

Observação

As DLLs não exportam necessariamente DllGetVersion. Sempre teste para ele antes de tentar usá-lo.

Para versões do Windows anteriores ao Windows 2000, DllGetVersion retorna uma estrutura DLLVERSIONINFO que contém os números de versão principal e secundária, o número de build e uma ID de plataforma. Para sistemas Windows 2000 e posteriores, DllGetVersion pode retornar uma estrutura DLLVERSIONINFO2 . Além das informações fornecidas por meio de DLLVERSIONINFO, DLLVERSIONINFO2também fornece o número de hotfix que identifica o service pack instalado mais recente, que fornece uma maneira mais robusta de comparar números de versão. Como o primeiro membro de DLLVERSIONINFO2 é uma estrutura DLLVERSIONINFO , a estrutura posterior é compatível com versões anteriores.

Usando DllGetVersion

A função GetVersion de exemplo a seguir carrega uma DLL especificada e tenta chamar sua função DllGetVersion . Se tiver êxito, ele usará uma macro para empacotar os números de versão principal e secundária da estrutura DLLVERSIONINFO em um DWORD retornado ao aplicativo de chamada. Se a DLL não exportar DllGetVersion, a função retornará zero. Com o Windows 2000 e sistemas posteriores, você pode modificar a função para lidar com a possibilidade de que DllGetVersion retorne uma estrutura DLLVERSIONINFO2 . Nesse caso, use as informações no membro ullVersion da estrutura DLLVERSIONINFO2 para comparar versões, números de build e versões do service pack. A macro MAKEDLLVERULL simplifica a tarefa de comparar esses valores com aqueles em ullVersion.

Observação

Usar LoadLibrary incorretamente pode representar riscos de segurança. Consulte a documentação do LoadLibrary para obter informações sobre como carregar corretamente DLLs com diferentes versões do Windows.

#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;
}

O exemplo de código a seguir ilustra como você pode usar GetVersion para testar se Shell32.dll é a versão 6.0 ou posterior.

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.
}

Versões do projeto

Para garantir que seu aplicativo seja compatível com diferentes versões direcionadas de um arquivo .dll, as macros de versão estão presentes nos arquivos de cabeçalho. Essas macros são usadas para definir, excluir ou redefinir determinadas definições para diferentes versões da DLL. Consulte Usando os cabeçalhos do Windows para obter uma descrição detalhada dessas macros.

Por exemplo, o nome da macro _WIN32_IE geralmente é encontrado em cabeçalhos mais antigos. Você é responsável por definir a macro como um número hexadecimal. Esse número de versão define a versão de destino do aplicativo que está usando a DLL. A tabela a seguir mostra os números de versão disponíveis e o efeito que cada um tem em seu aplicativo.

Versão Descrição
0x0200 O aplicativo é compatível com Shell32.dll versão 4.00 e posterior. O aplicativo não pode implementar recursos que foram adicionados após a versão 4.00.
0x0300 O aplicativo é compatível com Shell32.dll versão 4.70 e posterior. O aplicativo não pode implementar recursos que foram adicionados após a versão 4.70.
0x0400 O aplicativo é compatível com Shell32.dll versão 4.71 e posterior. O aplicativo não pode implementar recursos que foram adicionados após a versão 4.71.
0x0401 O aplicativo é compatível com Shell32.dll versão 4.72 e posterior. O aplicativo não pode implementar recursos que foram adicionados após a versão 4.72.
0x0500 O aplicativo é compatível com Shell32.dll e Shlwapi.dll versão 5.0 e posterior. O aplicativo não pode implementar recursos que foram adicionados após a versão 5.0 do Shell32.dll e Shlwapi.dll.
0x0501 O aplicativo é compatível com Shell32.dll e Shlwapi.dll versão 5.0 e posterior. O aplicativo não pode implementar recursos que foram adicionados após a versão 5.0 do Shell32.dll e Shlwapi.dll.
0x0600 O aplicativo é compatível com Shell32.dll e Shlwapi.dll versão 6.0 e posterior. O aplicativo não pode implementar recursos que foram adicionados após a versão 6.0 do Shell32.dll e Shlwapi.dll.

Se você não definir a macro _WIN32_IE em seu projeto, ela será definida automaticamente como 0x0500. Para definir um valor diferente, você pode adicionar o seguinte às diretivas do compilador no arquivo make; substitua o número de versão desejado por 0x0400.

/D _WIN32_IE=0x0400

Outro método é adicionar uma linha semelhante à seguinte no código-fonte antes de incluir os arquivos de cabeçalho do Shell. Substitua o número de versão desejado por 0x0400.

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