Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
При использовании 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 могут создавать различные коды ошибок.