Создание для 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 могут создавать различные коды ошибок.