检查是否存在Windows API函数

时间:2009-07-15 03:59:17

标签: c++ winapi windows-7

我是Windows编程的新手,我正在尝试发现检查Windows Shell API函数是否存在的最佳方法。我想在Windows7中使用一些新的任务栏功能。

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

但我仍然希望我的程序可以被以前版本的Windows使用。有没有一种简单的方法可以知道这些函数是否可以在最终用户系统中调用。我正在用C ++编程。

8 个答案:

答案 0 :(得分:9)

这取决于功能的种类。

对于普通(非COM)功能,唯一的方法是使用LoadLibraryGetProcAddress。如果任何一个失败,您知道操作系统缺少该功能。为复制现有函数签名的函数指针编写那些函数指针类型声明可能很繁琐,但在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);
    }
}

但是,许多Shell API都是通过COM组件和接口公开的。那些情况不同。有时你需要处理全新的组件;例如IApplicationDestinations是Win7中的新接口,实现它的coclass也是新的。在这些情况下,您可以执行CoCreateInstance,并检查REGDB_E_CLASSNOTREG的返回值 - 这意味着此类coclass未在系统上注册(实际上,并且不受支持)。< / p>

然而,有时候,新的OS版本会在现有的coclass上引入新的接口。一个例子是ITaskbarList3,在Win7中是新的,但是在现有的coclass上提供,它实现ITaskbarList并且可以追溯到Win95。在这些情况下,您应该首先为最基本的接口实例化coclass,然后使用QueryInterface获取新的接口版本,并通过检查E_NOINTERFACE的返回值来检测它们是否不受支持。 / p>

答案 1 :(得分:2)

LoadLibraryGetProcAddress将是您的朋友。

另外,请查看this tutorial

答案 2 :(得分:1)

我相信MSDN是你最好的选择。函数文档的每个MSDN页面最后都包含一个部分,说明哪个版本的Windows支持此功能。

例如,检查GetModuleHandle的号码。其中包含名为要求的部分,其中包含字段最低支持客户端最低支持服务器

但是,如果您想动态检查功能是否存在,则可以通过LoadLibraryGetProcAddress执行此操作。

答案 3 :(得分:1)

我不同意当前的解决方案。你最终会得到相当多的无法读取的代码。

更好的替代方法是将功能包装在自定义的Windows 7专用DLL中。对于其他系统,请提供实现相同功能的DLL的另一个版本。这通常可以是无操作。例如。设置任务栏扩展的功能将是旧版Windows上的无操作。

这些DLL之间的动态切换是通过使用MSVC的延迟加载功能完成的。当调用DLL中的第一个函数时,您可以在EXE中使用自定义钩子来选择正确的DLL版本,此时您就知道是否在Windows 7上运行。

答案 4 :(得分:0)

您应该使用LoadLibrary和GetProcAddress来动态加载和调用新功能。

答案 5 :(得分:0)

是的,您始终可以在运行时检查库中是否存在函数,并采取适当的操作。 检查LoadLibrary和GetProcAddress API。 http://msdn.microsoft.com/en-us/library/ms683212(VS.85).aspx

答案 6 :(得分:0)

如果你想在编译时找到以便在你正在使用的操作系统上没有该功能时获得构建中断(例如Win 95),那么你可以定义一些宏,记录here :NTDDI_VERSION,_WIN32_WINNT,WINVER。

如果您希望您的应用在功能不可用时正常工作(例如,早于Win7的操作系统上的JumpLists),那么您应该组合使用LoadLibrary / GetProcAddress来确定您正在寻找的功能是否可用。 / p>

答案 7 :(得分:0)

使用LoadLibarary获取库句柄,使用GerProcAddress获取指向函数的指针。对于当前操作系统不支持的功能,您将从ERROR_CALL_NOT_IMPLEMENTED收到GetLastError错误。