Criar para OneCore
Ao usar o Visual Studio para criar códigos de modo de usuário para Windows 10, você pode personalizar as opções do vinculador para direcionar versões específicas do Windows. Considere os seguintes fatores:
O binário criado deve ser executado somente na versão mais recente do Windows? Ou deve ser executado em versões anteriores, como o Windows 7?
Seu projeto tem alguma dependência UWP?
Por exemplo, quando você cria um novo projeto de driver UMDF v2, o Visual Studio é vinculado a OneCoreUAP.lib
por padrão. Isso resulta em um binário que é executado na versão mais recente do Windows e permite a adição da funcionalidade UWP.
No entanto, dependendo dos seus requisitos, você pode optar por vincular à OneCore.lib
. A tabela a seguir mostra os cenários aplicáveis a cada biblioteca:
Biblioteca | Cenário |
---|---|
OneCore.lib |
Todas as edições do Windows 7 e posteriores, sem suporte para UWP |
OneCoreUAP.lib |
Windows 7 e versões posteriores, edições UWP (Desktop, IoT, HoloLens, mas não Nano Server) do Windows 10 |
Observação
Para alterar as opções do vinculador no Visual Studio, escolha as propriedades do projeto e navegue até Dependências adicionais de> entrada> do vinculador.
Um subconjunto de APIs do Windows é compilado corretamente, mas retorna erros de runtime em edições OneCore que não são Desktop (por exemplo, Mobile ou IoT).
Por exemplo, a função InstallApplication retorna ERROR_ NOT_SUPPORTED
em edições OneCore não Desktop. A ferramenta ApiValidator também relata esses problemas. A próxima seção descreve como corrigi-los.
Corrigir erros do ApiValidator usando IsApiSetImplemented
Se o código chamar APIs não universais, você poderá ver os seguintes erros do ApiValidator:
Error: <Binary Name> has unsupported API call to <Module Name><Api Name>
Se o aplicativo ou driver base precisar ser executado no Windows 10, bem como em versões anteriores do Windows, você deverá remover as chamadas de API na categoria acima.
Error: <Binary Name> has a dependency on <Module Name><Api Name> but is missing: IsApiSetImplemented("<contract-name-for-Module>)
As chamadas de API na categoria acima são compiladas corretamente, mas podem não se comportar conforme o esperado no tempo de execução, dependendo do sistema operacional de destino. Para passar o requisito de camadas de API para drivers do Windows, encapsule essas chamadas com IsApiSetImplemented.
Isso permite que você compile seu código sem erros. Em seguida, no tempo de execução, se o computador de destino não tiver a API necessária, IsApiSetImplemented retornará FALSE.
Os exemplos de código a seguir ilustram como fazer isso.
Exemplo de código: uso direto da API, sem avaliar a existência
Esse código é executado corretamente em versões do Windows anteriores ao Windows 10, mas executá-lo em uma edição OneCore do Windows 10 resulta em falha WTSEnumerateSessions: 78 ou ERROR_CALL_NOT_IMPLEMENTED 120 (0x78).
Este exemplo de código falha no requisito de camadas de API dos drivers do Windows com os seguintes erros do 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
Este é o código :
#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;
}
Exemplo de código: uso direto da API, depois de avaliar a existência
Este exemplo mostra como chamar IsApiSetImplemented. Este exemplo passa o requisito de camadas de API dos drivers do Windows com a seguinte saída do ApiValidator:
ApiValidation: All binaries are Universal
Este é o código :
#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;
}
Ações recomendadas
- Analise as opções do vinculador acima e atualize seu projeto do Visual Studio adequadamente.
- Use a ferramenta ApiValidator no WDK. Essa ferramenta é executada automaticamente quando você cria um driver no Visual Studio.
- Use o teste de tempo de execução para verificar se o código do modo de usuário é executado conforme o esperado em edições OneCore que não são Desktop. As APIs de amostra podem gerar códigos de erro diferentes.