Uso del entorno de ejecución de SDK de Aplicaciones para Windows para aplicaciones empaquetadas con ubicación externa o sin empaquetar

Nota:

Si la aplicación está instalada mediante la tecnología MSIX, consulte SDK de Aplicaciones para Windows guía de implementación para aplicaciones empaquetadas dependientes del marco.

Si la aplicación no está instalada mediante MSIX (es decir, si está empaquetada con una ubicación externa o sin empaquetar), debe inicializar el SDK de Aplicaciones para Windows antes de usar características como las de WinUI 3, el ciclo de vida de las aplicaciones, MRT Core y DWriteCore. La aplicación debe inicializar el entorno de ejecución de SDK de Aplicaciones para Windows antes de usar cualquier otra característica del SDK de Aplicaciones para Windows.

  • A partir de SDK de Aplicaciones para Windows 1.0, esto se puede realizar automáticamente al iniciar su aplicación mediante la inicialización automática (configure la propiedad del proyecto <WindowsPackageType>None</WindowsPackageType>). Para obtener una demostración, consulte Create your first WinUI project.
  • Pero si tiene necesidades avanzadas (como controlar errores mostrando su propia interfaz de usuario personalizada o registro, o si necesita cargar una versión del SDK de Aplicaciones para Windows diferente de la versión con la que creó), continúe leyendo este tema. En esos escenarios, en lugar de la inicialización automática, puede llamar explícitamente a la API de arranque.

Cualquiera de las dos técnicas anteriores permite que una aplicación que no use MSIX tome una dependencia dinámica de la SDK de Aplicaciones para Windows en tiempo de ejecución.

Para obtener información general sobre las dependencias dinámicas, consulte Paquetes de marco MSIX y dependencias dinámicas.

En segundo plano y desactivación de los autoinicializadores

El código generado por la propiedad WindowsPackageType mencionada anteriormente utiliza inicializadores automáticos para llamar a la API del bootstrapper. El bootstrapper se encarga de la tarea más pesada: encontrar el SDK de aplicaciones de Windows y permitir que el proceso actual lo utilice. El código generado controla la inicialización y el apagado. Puede controlar el comportamiento de la inicialización con las siguientes propiedades de project:

  • <WindowsAppSDKBootstrapAutoInitializeOptions_Default>true</WindowsAppSDKBootstrapAutoInitializeOptions_Default>
    • Use las opciones predeterminadas.
  • <WindowsAppSDKBootstrapAutoInitializeOptions_None>true</WindowsAppSDKBootstrapAutoInitializeOptions_None>
    • No utilice opciones.
  • <WindowsAppSDKBootstrapAutoInitializeOptions_OnError_DebugBreak>true</WindowsAppSDKBootstrapAutoInitializeOptions_OnError_DebugBreak>
  • <WindowsAppSDKBootstrapAutoInitializeOptions_OnError_DebugBreak_IfDebuggerAttached>true</WindowsAppSDKBootstrapAutoInitializeOptions_OnError_DebugBreak_IfDebuggerAttached>
    • Llame a DebugBreak() si se produce un error solo si un depurador está asociado al proceso.
  • <WindowsAppSDKBootstrapAutoInitializeOptions_OnError_FailFast>true</WindowsAppSDKBootstrapAutoInitializeOptions_OnError_FailFast>
    • Realiza una detección rápida de fallos si se produce un error.
  • <WindowsAppSDKBootstrapAutoInitializeOptions_OnNoMatch_ShowUI>true</WindowsAppSDKBootstrapAutoInitializeOptions_OnNoMatch_ShowUI>
    • Pida al usuario que adquiera el SDK de Aplicaciones para Windows runtime si no se encuentra uno coincidente.
  • <WindowsAppSDKBootstrapAutoInitializeOptions_OnPackageIdentity_NoOp>true</WindowsAppSDKBootstrapAutoInitializeOptions_OnPackageIdentity_NoOp>
    • Se ejecuta correctamente si se invoca en un proceso con identidad de paquete (de lo contrario, falla y se devuelve un error).

Si quieres que la aplicación tenga control explícito, puedes llamar directamente a boostrapper API al principio del inicio de la aplicación. En ese caso, no necesita WindowsPackageType en su archivo de proyecto.

Nota:

Además de la inicialización automática y la API de arranque, el SDK de Aplicaciones para Windows también proporciona una implementación de la API de dependencia dynamic. Esta API permite que las aplicaciones sin empaquetar tomen una dependencia de any paquete de marco (no solo el paquete de marco de SDK de Aplicaciones para Windows) y la API de arranque la usa internamente. Para obtener más información sobre la API de dependencia dinámica, consulte Uso de la API de dependencia dinámica para hacer referencia a paquetes MSIX en tiempo de ejecución.

Optar por no participar (o participar) en inicializadores automáticos

La propiedad del proyecto <WindowsAppSdkBootstrapInitialize>false</WindowsAppSdkBootstrapInitialize> desactiva el inicializador automático descrito anteriormente (no se llama a la API del bootstrapper). Esto permite a la aplicación asumir la responsabilidad y llamar directamente a la API de arranque.

A partir de la versión 1.2 del SDK de Aplicaciones para Windows (desde el canal estable), los inicializadores automáticos solo se aplican a los proyectos que producen un ejecutable (es decir, La propiedad OutputType project está establecida en Exe o WinExe). Esto es para evitar la adición de inicializadores automáticos a archivos DLL de biblioteca de clases y otros archivos no ejecutables de forma predeterminada. Si necesitas un inicializador automático en un archivo no ejecutable (por ejemplo, una DLL de prueba cargada por un ejecutable de proceso anfitrión que no inicializa el bootstrapper), puedes habilitar explícitamente un inicializador automático en tu proyecto con <WindowsAppSdkBootstrapInitialize>true</WindowsAppSdkBootstrapInitialize>.

Uso de la API de Bootstrapper

Importante

La función MddBootstrapInitialize2 mencionada a continuación está disponible a partir de la versión 1.1.

La API de arranque consta de tres funciones de C/C++ declaradas en el archivo de encabezado mddbootstrap.h en el SDK de Aplicaciones para Windows: MddBootstrapInitialize, MddBootstrapInitialize2 y MddBootstrapShutdown. La librería bootstrapper proporciona esas funciones en SDK de Aplicaciones para Windows. Esa biblioteca es un archivo DLL pequeño que debe distribuir con la aplicación; no forma parte del propio paquete de marco.

MddBootstrapInitialize2

Esta función inicializa el proceso de llamada para usar la versión del paquete de marco de SDK de Aplicaciones para Windows que mejor coincida con los criterios que se pasan a los parámetros de función. Normalmente, esto da como resultado hacer referencia a la versión del paquete de marco que coincide con el paquete NuGet SDK de Aplicaciones para Windows instalado. Si varios paquetes cumplen los criterios, se selecciona el mejor candidato. Esta función debe ser una de las primeras llamadas en el inicio de la aplicación para asegurarse de que el componente de arranque puede inicializar correctamente el SDK de Aplicaciones para Windows y agregar la referencia en tiempo de ejecución al paquete de marco.

La API de bootstrapper utiliza la API de dependencias dinámicas para agregar el paquete de marco del entorno de ejecución del SDK de Aplicaciones para Windows al grafo de paquetes del proceso actual y además habilitar el acceso al paquete.

Esta función también inicializa el Dynamic Dependency Lifetime Manager (DDLM). Ese componente proporciona la infraestructura para evitar que el sistema operativo atienda al paquete de framework de SDK de Aplicaciones para Windows mientras está siendo utilizado por una aplicación desempaquetada.

MddBootstrapShutdown

Esta función revierte los cambios realizados en el proceso actual que fueron efectuados por una llamada a MddBootstrapInitialize. Después de llamar a esta función, la aplicación ya no puede llamar a SDK de Aplicaciones para Windows API, incluida la API de dependencias dinámicas.

Esta función también desactiva el Gestor de Vida Útil de Dependencias Dinámicas (DDLM) para que Windows pueda administrar el paquete del marco de trabajo según sea necesario.

Envoltura .NET para la API del bootstrapper

Aunque se puede llamar a la API del bootstrapper de C/C++ directamente desde aplicaciones .NET, esto requiere el uso de platform invoke para llamar a las funciones. En SDK de Aplicaciones para Windows 1.0 y versiones posteriores, hay disponible un contenedor de .NET para la API de arranque en el ensamblado Microsoft.WindowsAppRuntime.Bootstrap.Net.dll. Ese ensamblado proporciona una API más sencilla y natural para que los desarrolladores de .NET accedan a la funcionalidad del bootstrapper. La clase Bootstrap proporciona funciones estáticas Initialize, TryInitialize y Shutdown que encapsulan llamadas a las funciones MddBootstrapInitialize y MddBootstrapShutdown para los escenarios más comunes. Para obtener un ejemplo que muestra cómo usar el contenedor de .NET para la API de arranque, consulte las instrucciones de C# en Tutorial: Usar la API de arranque en una aplicación empaquetada con ubicación externa o sin empaquetar que usa el SDK de Aplicaciones para Windows.

Para obtener más información sobre el wrapper de .NET para la API de arranque, consulte los siguientes recursos:

Contenedor de C++ para la API de arranque

Hay disponible un contenedor de C++ para la API de arranque a partir de SDK de Aplicaciones para Windows 1.1.

Consulte Bootstrapper C++ API (API de C++).

Declaración de la compatibilidad del sistema operativo en el manifiesto de aplicación

Para declarar la compatibilidad con el sistema operativo (SO) y evitar que el SDK de aplicaciones de Windows adopte por defecto el comportamiento de Windows 8 (y los posibles fallos), puedes incluir un manifiesto de aplicación side-by-side en tu aplicación empaquetada con ubicación externa o en tu aplicación sin empaquetar. Consulte Manifiestos de aplicación (es el archivo que declara elementos como el reconocimiento de PPP y se inserta en .exe de la aplicación durante la compilación). Esto puede ser un problema si agrega SDK de Aplicaciones para Windows compatibilidad con una aplicación existente, en lugar de crear una nueva a través de una plantilla de Visual Studio project.

Si aún no dispone de un manifiesto de aplicación side-by-side en su proyecto, añada un nuevo archivo XML al proyecto y asígnele un nombre según se recomienda en Manifiestos de aplicación. Agregue al archivo el elemento de compatibilidad y los elementos secundarios que se muestran en el ejemplo siguiente. Estos valores controlan el nivel de peculiaridades de los componentes que se ejecutan en el proceso de la aplicación.

Reemplace el atributo Id del elemento maxversiontested por el número de versión de Windows que tenga como destino (debe ser 10.0.17763.0 o una versión posterior). Tenga en cuenta que establecer un valor superior significa que las versiones anteriores de Windows no ejecutarán correctamente la aplicación porque cada versión de Windows solo conoce las versiones anteriores. Por lo tanto, si quieres que la aplicación se ejecute en Windows 10, versión 1809 (10.0; Compilación 17763), debe dejar el valor 10.0.17763.0 tal como está o agregar varios maxversiontested para los distintos valores que admite la aplicación.

<?xml version="1.0" encoding="UTF-8"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
        <application>
            <!-- Windows 10, version 1809 (10.0; Build 17763) -->
            <maxversiontested Id="10.0.17763.0"/>
            <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
        </application>
    </compatibility>
</assembly>

Consulte también