簡體   English   中英

檢查是否存在Windows API函數

[英]Checking for existence of Windows API Functions

我是Windows編程的新手,我正在嘗試發現檢查Windows Shell API函數是否存在的最佳方法。 我想在Windows7中使用一些新的任務欄功能。

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

但我仍然希望我的程序可以被以前版本的Windows使用。 有沒有一種簡單的方法可以知道這些函數是否可以在最終用戶系統中調用。 我正在用C ++編程。

這取決於功能的種類。

對於普通(非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未在系統上注冊(並且實際上不受支持)。

但是,有時新的操作系統版本會在現有的coclass上引入新的接口。 一個例子是ITaskbarList3 ,Win7中的新增功能,但是在現有的coclass上提供,它實現了ITaskbarList並且可以追溯到Win95。 在這些情況下,您應該首先為最基本的接口實例化coclass,然后使用QueryInterface獲取新的接口版本,並通過檢查E_NOINTERFACE返回值來檢測它們是否不受支持。

LoadLibraryGetProcAddress將成為你的朋友。

另外,請查看本教程

我相信MSDN是你最好的選擇。 函數文檔的每個MSDN頁面都包含最后一節,說明哪個版本的Windows支持此功能。

例如,檢查GetModuleHandle的doumentation。 其中包含名為Requirements的部分,其中包含字段Minimum Supported ClientMinimum Supported Server

但是,如果要動態檢查函數是否存在,則可以通過LoadLibraryGetProcAddress執行此操作。

我不同意當前的解決方案。 你最終會得到相當多的不可讀的代碼。

一個更好的選擇是將功能包裝在自定義的Windows 7專用DLL中。 對於其他系統,請提供實現相同功能的DLL的另一個版本。 這通常可以是無操作。 例如,設置任務欄擴展的功能將是舊版Windows上的無操作。

這些DLL之間的動態切換是通過使用MSVC的延遲加載功能完成的。 當調用DLL中的第一個函數時,您可以在EXE中使用自定義鈎子來選擇正確的DLL版本,此時您就知道自己是否在Windows 7上運行。

您應該使用LoadLibrary和GetProcAddress來動態加載和調用新功能。

是的,您始終可以在運行時檢查庫中是否存在函數,並采取適當的操作。 檢查LoadLibrary和GetProcAddress API。 http://msdn.microsoft.com/en-us/library/ms683212(VS.85).aspx

如果你想在編譯時發現如果函數在你正在使用的操作系統上不可用(例如Win 95),那么就可以找到一個構建中斷,然后你可以定義一些宏, 這里記錄 :NTDDI_VERSION,_WIN32_WINNT,WINVER。

如果您希望應用程序在功能不可用時正常工作(例如,早於Win7的操作系統上的JumpLists),那么您應該組合使用LoadLibrary / GetProcAddress來確定您要查找的功能是否可用。

使用LoadLibarary獲取庫句柄,使用GerProcAddress獲取指向函數的指針。 對於當前操作系統不支持的那些函數,您將從GetLastError獲得ERROR_CALL_NOT_IMPLEMENTED錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM