Поделиться через


Версии оболочки и библиотеки DLL Shlwapi

В этом разделе описывается, как определить версию библиотек DLL оболочки, в которой работает приложение, и как нацелить приложение на определенную версию.

Номера версий DLL

Все, кроме горстки элементов программирования, рассмотренных в документации оболочки, содержатся в двух библиотеках DLL: Shell32.dll и Shlwapi.dll. Из-за текущих улучшений различные версии этих БИБЛИОТЕК DLL реализуют различные функции. В справочной документации по Оболочке каждый элемент программирования указывает минимальный поддерживаемый номер версии DLL. Этот номер версии указывает, что элемент программирования реализуется в этой версии и последующих версиях библиотеки DLL, если иное не указано. Если номер версии не указан, элемент программирования реализуется во всех существующих версиях библиотеки DLL.

До Windows XP новые версии Shell32.dll и Shlwapi.dll иногда предоставляются с новыми версиями Windows Internet Explorer. По состоянию на Windows XP эти библиотеки DLL больше не предоставлялись как распространяемые файлы за пределами новых версий Windows. В следующей таблице описаны различные версии БИБЛИОТЕК DLL и их распространение в Microsoft Internet Explorer 3.0, Windows 95 и Microsoft Windows NT 4.0.

Shell32.dll версии 4.0 находятся в исходных версиях Windows 95 и Microsoft Windows NT 4.0. Оболочка не была обновлена с выпуском Internet Explorer 3.0, поэтому Shell32.dll не имеет версии 4.70. Shell32.dll версии 4.71 и 4.72 были отправлены с соответствующими выпусками Internet Explorer, но они не обязательно установлены (см. примечание 1). Для выпусков, последующих к Microsoft Internet Explorer 4.01 и Windows 98, номера версий для Shell32.dll и Shlwapi.dll размыкаться. Как правило, следует предположить, что библиотеки DLL имеют разные номера версий и тестируют каждую отдельно.

Shell32.dll

Версия Платформа распространения
4.0 Windows 95 и Microsoft Windows NT 4.0
4.71 Microsoft Internet Explorer 4.0. См. примечание 1.
4.72 Internet Explorer 4.01 и Windows 98. См. примечание 1.
5.0 Windows 2000 и Windows Millennium Edition (Windows Me). См. примечание 2.
6.0 Windows XP
6.0.1 Windows Vista
6.1 Windows 7

Shlwapi.dll

Версия Платформа распространения
4.0 Windows 95 и Microsoft Windows NT 4.0
4.71 Internet Explorer 4.0. См. примечание 1.
4.72 Internet Explorer 4.01 и Windows 98. См. примечание 1.
4.7 Internet Explorer 3.x
5.0 Microsoft Internet Explorer 5 и Windows 98 SE. См. примечание 2.
5.5 Microsoft Internet Explorer 5.5 и Windows Millennium Edition (Windows Me)
6.0 Windows XP и Windows Vista

Примечание 1. Все системы с Internet Explorer 4.0 или 4.01 имели связанную версию Shlwapi.dll (4.71 или 4.72 соответственно). Однако для систем до Windows 98 internet Explorer 4.0 и 4.01 можно установить с интегрированной оболочкойили без нее. Если Internet Explorer был установлен с интегрированной оболочкой, также была установлена связанная версия Shell32.dll (4.71 или 4.72). Если Internet Explorer был установлен без встроенной оболочки, Shell32.dll осталось как версия 4.0. Другими словами, наличие Shlwapi.dll версии 4.71 или 4.72 в системе не гарантирует, что Shell32.dll имеет одинаковый номер версии. Все системы Windows 98 имеют версию 4.72 Shell32.dll.

примечание 2. версии 5.0 Shlwapi.dll распределена с Internet Explorer 5 и была обнаружена во всех системах, на которых установлен Internet Explorer 5, за исключением Windows 2000. Версия 5.0 Shell32.dll была распределена изначально с Windows 2000 и Windows Millennium Edition (Windows Me) вместе с версией 5.0 Shlwapi.dll.

Использование DllGetVersion для определения номера версии

Начиная с версии 4.71 библиотеки DLL оболочки, среди прочего, начали экспорт DllGetVersion. Эта функция может вызываться приложением, чтобы определить, какая версия DLL присутствует в системе.

Заметка

Библиотеки DLL не обязательно экспортируют DllGetVersion. Всегда тестируйте его перед попыткой его использования.

Для версий Windows, предшествующих Windows 2000, DllGetVersion возвращает структуру DLLVERSIONINFO, содержащую основные и незначительные номера версий, номер сборки и идентификатор платформы. Для систем Windows 2000 и более поздних версий DllGetVersion вместо этого может вернуться структура DLLVERSIONINFO2. Помимо сведений, предоставленных DLLVERSIONINFO, DLLVERSIONINFO2также предоставляет номер исправления, определяющий последний установленный пакет обновления, который обеспечивает более надежный способ сравнения номеров версий. Так как первый элемент DLLVERSIONINFO2 является структурой DLLVERSIONINFO, то более поздняя структура является обратно совместимой.

Использование DllGetVersion

Следующая пример функции GetVersion загружает указанную библиотеку DLL и пытается вызвать ее функцию DllGetVersion. В случае успешного выполнения макрос используется для упаковки основных и дополнительных номеров версий из структуры DLLVERSIONINFO в DWORD, возвращаемой вызывающему приложению. Если библиотека DLL не экспортирует DllGetVersion, функция возвращает ноль. В системах Windows 2000 и более поздних версий можно изменить функцию для обработки возможности, что DllGetVersion возвращает структуру DLLVERSIONINFO2. Если да, используйте сведения в этой DLLVERSIONINFO2 структуре ullVersion для сравнения версий, номеров сборки и выпусков пакета обновления. Макрос MAKEDLLVERULL упрощает задачу сравнения этих значений с этими значениями в ullVersion.

Заметка

Использование LoadLibrary неправильно может представлять угрозу безопасности. Сведения о том, как правильно загружать библиотеки DLL с различными версиями Windows, см. в документации по 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;
}

В следующем примере кода показано, как использовать GetVersion для проверки того, является ли Shell32.dll версия 6.0 или более поздней.

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

Версии проекта

Чтобы обеспечить совместимость приложения с различными целевыми версиями файла .dll, макросы версий присутствуют в файлах заголовков. Эти макросы используются для определения, исключения или переопределиния определенных определений для разных версий библиотеки DLL. Дополнительные сведения об этих макросах см. в использовании заголовков Windows.

Например, имя макроса _WIN32_IE обычно встречается в старых заголовках. Вы несете ответственность за определение макроса в виде шестнадцатеричного числа. Этот номер версии определяет целевую версию приложения, использующую библиотеку DLL. В следующей таблице показаны доступные номера версий и влияние каждого из них на приложение.

Версия Описание
0x0200 Приложение совместимо с Shell32.dll версии 4.00 и более поздней. Приложение не может реализовать функции, добавленные после версии 4.00.
0x0300 Приложение совместимо с Shell32.dll версии 4.70 и более поздними версиями. Приложение не может реализовать функции, добавленные после версии 4.70.
0x0400 Приложение совместимо с Shell32.dll версии 4.71 и более поздней. Приложение не может реализовать функции, добавленные после версии 4.71.
0x0401 Приложение совместимо с Shell32.dll версии 4.72 и более поздней. Приложение не может реализовать функции, добавленные после версии 4.72.
0x0500 Приложение совместимо с Shell32.dll и Shlwapi.dll версии 5.0 и более поздней. Приложение не может реализовать функции, добавленные после версии 5.0 Shell32.dll и Shlwapi.dll.
0x0501 Приложение совместимо с Shell32.dll и Shlwapi.dll версии 5.0 и более поздней. Приложение не может реализовать функции, добавленные после версии 5.0 Shell32.dll и Shlwapi.dll.
0x0600 Приложение совместимо с Shell32.dll и Shlwapi.dll версии 6.0 и более поздней. Приложение не может реализовать функции, добавленные после версии 6.0 Shell32.dll и Shlwapi.dll.

Если макрос _WIN32_IE в проекте не определен, он автоматически определяется как 0x0500. Чтобы определить другое значение, можно добавить следующее в директивы компилятора в файле make; замените нужный номер версии для 0x0400.

/D _WIN32_IE=0x0400

Другой метод — добавить строку, аналогичную приведенной ниже в исходном коде, прежде чем включать файлы заголовков Оболочки. Замените нужный номер версии 0x0400.

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