Partager via


Construction pour OneCore

Quand vous utilisez Visual Studio pour générer du code en mode utilisateur pour Windows 10, vous pouvez personnaliser les options de l’éditeur de liens pour cibler des versions spécifiques de Windows. Tenez compte des facteurs suivants :

  • Le fichier binaire généré doit-il s’exécuter uniquement sur la version la plus récente de Windows ? Ou doit-il s’exécuter sur des versions antérieures, telles que Windows 7 ?

  • Votre projet a-t-il des dépendances UWP ?

Par exemple, lorsque vous créez un projet de pilote UMDF v2, Visual Studio est lié à OneCoreUAP.lib par défaut. Il en résulte un fichier binaire qui s’exécute sur la version la plus récente de Windows et autorise l’ajout de fonctionnalités UWP.

Toutefois, en fonction de vos besoins, vous pouvez choisir de lier à OneCore.lib. Le tableau suivant présente les scénarios applicables à chaque bibliothèque :

Bibliothèque Scénario
OneCore.lib Toutes les éditions de Windows 7 et versions ultérieures, aucune prise en charge UWP
OneCoreUAP.lib Windows 7 et versions ultérieures, éditions UWP (Desktop, IoT, HoloLens, mais pas Nano Server) de Windows 10

Notes

Pour modifier les options de l’éditeur de liens dans Visual Studio, choisissez propriétés du projet et accédez à Éditeur de liens-Entrée-Dépendances>> supplémentaires.

Un sous-ensemble d’API Windows se compile correctement, mais retourne des erreurs d’exécution sur les éditions non-Desktop OneCore (par exemple Mobile ou IoT).

Par exemple, la fonction InstallApplication retourne ERROR_ NOT_SUPPORTED sur les éditions non-Desktop OneCore. L’outil ApiValidator signale également ces problèmes. La section suivante explique comment les corriger.

Correction des erreurs ApiValidator à l’aide de IsApiSetImplemented

Si votre code appelle des API non universelles, vous pouvez voir les erreurs ApiValidator suivantes :

  • Error: <Binary Name> has unsupported API call to <Module Name><Api Name>

    Si votre application ou votre pilote de base doit s’exécuter sur Windows 10 ainsi que sur des versions antérieures de Windows, vous devez supprimer les appels d’API dans la catégorie ci-dessus.

  • Error: <Binary Name> has a dependency on <Module Name><Api Name> but is missing: IsApiSetImplemented("<contract-name-for-Module>)

    Les appels d’API dans la catégorie ci-dessus compilent correctement, mais peuvent ne pas se comporter comme prévu au moment de l’exécution, en fonction du système d’exploitation cible. Pour passer la spécification de la couche d’API pour les pilotes Windows, encapsulez ces appels avec IsApiSetImplemented.

Cela vous permet de compiler votre code sans erreur. Ensuite, au moment de l’exécution, si l’ordinateur cible ne dispose pas de l’API nécessaire, IsApiSetImplemented retourne FALSE.

Les exemples de code suivants illustrent comment procéder.

Exemple de code : Utilisation directe de l’API, sans évaluation de l’existence

Ce code s’exécute correctement sur les versions de Windows antérieures à Windows 10, mais son exécution sur une édition OneCore de Windows 10 entraîne l’échec de WTSEnumerateSessions : 78 ou ERROR_CALL_NOT_IMPLEMENTED 120 (0x78).

Cet exemple de code échoue à l’exigence de couche d’API des pilotes Windows avec les erreurs ApiValidator suivantes :

ApiValidation: Error: FlexLinkTest.exe has a dependency on 'wtsapi32.dll!WTSEnumerateSessionsW' but is missing: IsApiSetImplemented("ext-ms-win-session-wtsapi32-l1-1-0")
ApiValidation: Error: FlexLinkTest.exe has a dependency on 'wtsapi32.dll!WTSFreeMemory' but is missing: IsApiSetImplemented("ext-ms-win-session-wtsapi32-l1-1-0")
ApiValidation: NOT all binaries are Universal

Voici le code :

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

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

    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;
}

Exemple de code : utilisation directe de l’API, après évaluation de l’existence

Cet exemple montre comment appeler IsApiSetImplemented. Cet exemple transmet l’exigence de couche d’API des pilotes Windows avec la sortie ApiValidator suivante :

ApiValidation: All binaries are Universal

Voici le code :

#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;
}
  • Passez en revue les options de l’éditeur de liens ci-dessus et mettez à jour votre projet Visual Studio en conséquence.
  • Utilisez l’outil ApiValidator dans wdk. Cet outil s’exécute automatiquement lorsque vous générez un pilote dans Visual Studio.
  • Utilisez les tests d’exécution pour vérifier que votre code en mode utilisateur s’exécute comme prévu dans les éditions non-Desktop OneCore. Notez que les API stubbed peuvent générer des codes d’erreur différents.

Voir aussi