Compartir vía


Creación de OneCore

Cuando se usa Visual Studio para compilar código en modo de usuario para Windows 10, puede personalizar las opciones del enlazador para dirigirse a versiones específicas de Windows. Tenga en cuenta los siguientes factores:

  • ¿Debería ejecutarse el binario compilado solo en la versión más reciente de Windows? ¿O debería ejecutarse en versiones anteriores, como Windows 7?

  • ¿El proyecto tiene dependencias para UWP ?

Por ejemplo, al crear un nuevo proyecto de controlador UMDF v2, Visual Studio vincula de OneCoreUAP.lib forma predeterminada. Esto da como resultado un archivo binario que se ejecuta en la versión más reciente de Windows y permite la adición de la funcionalidad de UWP.

Sin embargo, dependiendo de sus requisitos, puede elegir en su lugar vincular a OneCore.lib. En la tabla siguiente se muestran los escenarios aplicables a cada biblioteca:

Biblioteca Escenario
OneCore.lib Todas las ediciones de Windows 7 y versiones posteriores, sin compatibilidad con UWP
OneCoreUAP.lib Ediciones de Windows 7 y posteriores para UWP (Desktop, IoT, HoloLens, pero no Nano Server) de Windows 10

Nota

Para cambiar las opciones del enlazador en Visual Studio, elija las propiedades del proyecto y vaya a Linker-Input-Additional> Dependencies(Dependencias adicionales del vinculador).>

Un subconjunto de API de Windows se compila de forma limpia, pero devuelve errores en tiempo de ejecución en ediciones que no son de escritorio OneCore (por ejemplo, Mobile o IoT).

Por ejemplo, la función InstallApplication devuelve ERROR_ NOT_SUPPORTED en ediciones que no son de Escritorio OneCore. La herramienta ApiValidator también notifica estos problemas. En la sección siguiente se describe cómo corregirlos.

Corrección de errores de ApiValidator mediante IsApiSetImplemented

Si el código llama a las API no universales, es posible que vea los siguientes errores de ApiValidator :

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

    Si la aplicación o el controlador base deben ejecutarse en Windows 10 así como en versiones anteriores de Windows, debe quitar las llamadas API en la categoría anterior.

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

    Las llamadas API de la categoría anterior se compilan correctamente, pero es posible que no se comporten según lo previsto en tiempo de ejecución, en función del sistema operativo de destino. Para pasar el requisito de capas de API para controladores de Windows, encapsula estas llamadas con IsApiSetImplemented.

Esto le permite compilar el código sin errores. A continuación, en tiempo de ejecución, si la máquina de destino no tiene la API necesaria, IsApiSetImplemented devuelve FALSE.

En los ejemplos de código siguientes se muestra cómo hacerlo.

Ejemplo de código: uso directo de la API, sin evaluar la existencia

Este código se ejecuta correctamente en versiones de Windows anteriores a Windows 10, pero ejecutarlo en una edición de OneCore de Windows 10 da como resultado un error WTSenumerateSessions: 78 o ERROR_CALL_NOT_IMPLEMENTED 120 (0x78).

Este ejemplo de código produce un error en el requisito de capas de API de controladores de Windows con los siguientes errores de 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 es el 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;
}

Ejemplo de código: Uso directo de la API, después de evaluar la existencia

En este ejemplo se muestra cómo llamar a IsApiSetImplemented. En este ejemplo se pasa el requisito de capas de API de controladores de Windows con la siguiente salida de ApiValidator :

ApiValidation: All binaries are Universal

Este es el 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;
}
  • Revise las opciones del enlazador anteriores y actualice el proyecto de Visual Studio en consecuencia.
  • Use la herramienta ApiValidator en WDK. Esta herramienta se ejecuta automáticamente al compilar un controlador en Visual Studio.
  • Use pruebas en tiempo de ejecución para comprobar que el código en modo de usuario se ejecuta según lo previsto en ediciones que no son de Escritorio OneCore. Tenga en cuenta que las API de código auxiliar pueden generar códigos de error diferentes.

Consulte también