Dela via


Identifiera tillgänglighet för API-uppsättningar

I vissa fall kan ett angivet API-uppsättningskontraktsnamn avsiktligt mappas till ett tomt modulnamn på vissa Windows-enheter. Orsakerna till detta varierar, men ett vanligt exempel är att en dyr funktion när det gäller systemresurser kan tas bort från Windows-operativsystemet när den konfigureras för en resursbegränsad enhet. Detta innebär en utmaning för program att hantera valfria funktioner på API-nivå på ett smidigt sätt.

Den traditionella metoden för att testa om ett Win32-API är tillgängligt är att använda LoadLibrary eller GetProcAddress. Dessa är dock inte ett tillförlitligt sätt att testa API-uppsättningar på grund av omvänd vidarebefordran stöd i Windows 10 och senare. När omvänd vidarebefordran tillämpas på ett visst API kan LoadLibrary eller GetProcAddress matcha en giltig funktionspekare även om den interna implementeringen har tagits bort. I det här fallet pekar funktionspekaren på en stub-funktion som helt enkelt returnerar ett fel.

För att identifiera det här fallet kan du använda funktionen IsApiSetImplemented för att fråga den underliggande tillgängligheten för en viss API-implementering. Det här testet verifierar att anrop av den här funktionen resulterar i att en funktionell implementering av API:et körs.

Följande kodexempel visar hur du använder IsApiSetImplemented för att avgöra om funktionen WTSEnumerateSessions är tillgänglig på den aktuella enheten innan den anropas.

#include <windows.h>
#include <stdio.h>
#include <Wtsapi32.h>

int __cdecl wmain(int /* argc */, PCWSTR /* argv */ [])
{
    PWTS_SESSION_INFO pInfo = {};
    DWORD count = 0;

    if (!IsApiSetImplemented("ext-ms-win-session-wtsapi32-l1-1-0"))
    {
        wprintf(L"IsApiSetImplemented on ext-ms-win-session-wtsapi32-l1-1-0 returns FALSE\n");
    }
    else
    {
        if (WTSEnumerateSessionsW(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pInfo, &count))
        {
            wprintf(L"SessionCount = %d\n", count);

            for (ULONG i = 0; i < count; i++)
            {
                PWTS_SESSION_INFO pCurInfo = &pInfo[i];
                wprintf(L"    %s: ID = %d, state = %d\n", pCurInfo->pWinStationName, 
                    pCurInfo->SessionId, pCurInfo->State);
            }

            WTSFreeMemory(pInfo);
        }
        else
        {
            wprintf(L"WTSEnumerateSessions failure : %x\n", GetLastError());
        }
    }

    return 0;
}