Проверка существования функций Windows API - PullRequest
6 голосов
/ 15 июля 2009

Я новичок в программировании Windows и пытаюсь найти лучший способ проверить наличие функций API оболочки Windows. Я хочу использовать некоторые новые функции панели задач в Windows7.

https://msdn.microsoft.com/en-us/library/dd378460%28VS.85%29.aspx#custom_jump_lists

Но я все еще хочу, чтобы моя программа работала в предыдущих версиях Windows. Существует ли простой способ узнать, доступны ли функции для вызова в системе конечных пользователей. Я программирую на C ++.

Ответы [ 8 ]

9 голосов
/ 15 июля 2009

Зависит от видов функций.

Для простых (не COM) функций единственным способом является использование LoadLibrary и GetProcAddress. Если любой из них дает сбой, вы знаете, что в ОС отсутствует эта функция. Написание этих объявлений типов указателей функций для указателей функций, дублирующих существующие сигнатуры функций, может быть утомительным, хотя в VC ++ 2010 для этого можно использовать decltype. Например:

HMODULE user32 = LoadLibraryW(L"user32");
if (user32 != NULL)
{
    auto messageBoxW = reinterpret_cast<decltype(MessageBoxW)*>(GetProcAddress(user32, "MessageBoxW"));
    if (messageBoxW != NULL)
    {
        messageBoxW(HWND_DESKTOP, L"Hello!", NULL, MB_OK);
    }
}

Однако многие API-интерфейсы оболочки открываются через компоненты и интерфейсы COM. Эти случаи разные. Иногда вам нужно иметь дело с совершенно новыми компонентами; например IApplicationDestinations - это новый интерфейс в Win7, и coclass, который его реализует, также является новым. В этих случаях вы можете просто сделать CoCreateInstance и проверить возвращаемое значение для REGDB_E_CLASSNOTREG - это означает, что такой кокласс не зарегистрирован в системе (и, по сути, не поддерживается).

Иногда, однако, новые версии ОС вводят новые интерфейсы на существующих коклассах. Примером является ITaskbarList3, новый в Win7, но предоставленный на существующем Coclass, который реализует ITaskbarList и восходит к Win95. В этих случаях вы должны сначала создать экземпляр класса для самого простого интерфейса, а затем использовать QueryInterface для получения новых версий интерфейса и обнаружить, что они не поддерживаются, проверив возвращаемое значение для E_NOINTERFACE.

2 голосов
/ 15 июля 2009

LoadLibrary и GetProcAddress будут вашими друзьями.

Кроме того, ознакомьтесь с этим руководством .

1 голос
/ 15 июля 2009

Я не согласен с текущими решениями. В итоге вы получите нечитаемый код.

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

Динамическое переключение между этими DLL выполняется с помощью функции отложенной загрузки MSVC. Вы можете использовать пользовательский хук в вашем EXE, чтобы выбрать правильную версию DLL при вызове первой функции в вашей DLL, когда вы знаете, работаете ли вы в Windows 7.

1 голос
/ 15 июля 2009

Я считаю, что MSDN - ваш лучший выбор для этого. Каждая страница MSDN для документации функции в конце содержит раздел, в котором указано, какая версия Windows поддерживает эту функцию.

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

Однако, если вы хотите динамически проверять существование функций, вы можете сделать это через LoadLibrary и GetProcAddress .

0 голосов
/ 15 июля 2009

Используйте LoadLibarary для получения дескриптора библиотеки и GerProcAddress для получения указателя на функцию. Для тех функций, которые не поддерживаются текущей ОС, вы получите ошибку ERROR_CALL_NOT_IMPLEMENTED от GetLastError.

0 голосов
/ 15 июля 2009

Если вы хотите узнать во время компиляции, чтобы получить разрыв сборки, если функция недоступна в целевой ОС (например, в Win 95), то вы можете определить некоторые макросы, документированные здесь : NTDDI_VERSION, _WIN32_WINNT, WINVER.

Если вы хотите, чтобы ваше приложение работало нормально, когда функциональность недоступна (например, JumpLists на ОС старше Win7), вам следует выполнить комбинацию LoadLibrary / GetProcAddress, чтобы выяснить, доступна ли нужная функция.

0 голосов
/ 15 июля 2009

Да, вы всегда можете проверить наличие функции в библиотеке во время выполнения и предпринять соответствующие действия. Проверьте API-интерфейсы LoadLibrary и GetProcAddress. http://msdn.microsoft.com/en-us/library/ms683212(VS.85).aspx

0 голосов
/ 15 июля 2009

Вы должны использовать LoadLibrary и GetProcAddress для динамической загрузки и вызова новой функциональности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...