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


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

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

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

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

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

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

Shell32.dll

Версия Платформа распространения
4,0 Windows 95 и Microsoft Windows NT 4.0
4,71 Microsoft Internet Обозреватель 4.0. См. примечание 1.
4.72 Internet Обозреватель 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 Обозреватель 4.0. См. примечание 1.
4.72 Internet Обозреватель 4.01 и Windows 98. См. примечание 1.
4,7 Internet Обозреватель 3.x
5,0 Microsoft Internet Обозреватель 5 и Windows 98 SE. См. примечание 2.
5.5 Microsoft Internet Обозреватель 5.5 и Windows Millennium Edition (Windows Me)
6,0 Windows XP и Windows Vista

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

Примечание 2. Версия 5.0 Shlwapi.dll распространялась с Интернетом Обозреватель 5 и была обнаружена во всех системах, в которых был установлен Internet Обозреватель 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 . Если это так, используйте сведения в элементе ullVersion структуры DLLVERSIONINFO2 для сравнения версий, номеров сборок и выпусков пакетов обновления. Макрос 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>