Поделиться через


Создание для OneCore

При использовании Visual Studio для создания кода пользовательского режима для Windows 10 можно настроить параметры компоновщика для целевых версий Windows. Обратите внимание на следующие факторы:

  • Должен ли созданный двоичный файл выполняться только в последней версии Windows? Или он должен работать в более ранних версиях, таких как Windows 7?

  • У вашего проекта есть зависимости UWP ?

Например, при создании проекта драйвера UMDF версии 2 Visual Studio по умолчанию ссылается OneCoreUAP.lib на нее. Это приводит к двоичному файлу, работающему в последней версии Windows, и позволяет добавлять функции UWP.

Однако в зависимости от ваших требований вы можете вместо этого выбрать ссылку на OneCore.lib. В следующей таблице показаны сценарии, применимые к каждой библиотеке:

Библиотека Сценарий
OneCore.lib Все выпуски Windows 7 и более поздних версий не поддерживают UWP
OneCoreUAP.lib Выпуски Windows 7 и более поздних версий UWP (Настольные компьютеры, IoT, HoloLens, но не Nano Server) Windows 10

Примечание.

Чтобы изменить параметры компоновщика в Visual Studio, выберите свойства проекта и перейдите в раздел Linker-Input-Additional>> Dependencies.

Подмножество API Windows компилируется чисто, но возвращает ошибки среды выполнения в выпусках OneCore, отличных от настольных компьютеров (например, Mobile или IoT).

Например, функция InstallApplication возвращается ERROR_ NOT_SUPPORTED в выпусках OneCore, отличных от Desktop. Средство ApiValidator также сообщает об этих проблемах. В следующем разделе описывается, как их исправить.

Исправление ошибок ApiValidator с помощью IsApiSetImplemented

Если код вызывает не универсальные API, могут появиться следующие ошибки ApiValidator :

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

    Если приложению или базовому драйверу необходимо запустить в Windows 10, а также более ранних версиях Windows, необходимо удалить вызовы API в приведенной выше категории.

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

    Вызовы API в приведенной выше категории компилируются точно, но могут не вести себя должным образом во время выполнения в зависимости от целевой операционной системы. Чтобы передать требование уровня API для драйверов Windows, обтекайте эти вызовы с помощью IsApiSetImplemented.

Это позволяет компилировать код без ошибок. Затем во время выполнения, если целевой компьютер не имеет необходимого API, IsApiSetImplemented возвращает значение FALSE.

В следующих примерах кода показано, как это сделать.

Пример кода: прямое использование API без оценки существования

Этот код работает хорошо в версиях Windows ранее Windows 10, но при запуске его в выпуске OneCore Windows 10 приводит к сбою WTSEnumerateSessions: 78 или ERROR_CALL_NOT_IMPLEMENTED 120 (0x78).

Этот пример кода завершается ошибкой требования к уровню API драйверов Windows со следующими ошибками ApiValidator :

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

Вот этот код:

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

Пример кода: прямое использование API после оценки наличия

В этом примере показано, как вызвать IsApiSetImplemented. В этом примере выполняется требование уровня API драйверов Windows со следующими выходными данными ApiValidator :

ApiValidation: All binaries are Universal

Вот этот код:

#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;
}
  • Просмотрите приведенные выше параметры компоновщика и обновите проект Visual Studio соответствующим образом.
  • Используйте средство ApiValidator в WDK. Это средство запускается автоматически при создании драйвера в Visual Studio.
  • Используйте тестирование среды выполнения, чтобы убедиться, что код пользовательского режима выполняется в выпусках OneCore, отличных от desktop. Обратите внимание, что ступеные API могут создавать различные коды ошибок.

См. также