Guía de implementación del SDK de aplicaciones de Windows para aplicaciones dependientes del marco de trabajo empaquetadas con ubicación externa o sin empaquetar

En este tema se proporciona una guía sobre la implementación de aplicaciones empaquetadas con ubicación externa, o sin empaquetar, y que usan el SDK de Aplicaciones para Windows.

  • Estas aplicaciones son aplicaciones de escritorio (no aplicaciones para UWP).
  • Se pueden escribir en un lenguaje .NET, como C#, o en C++.
  • Para su interfaz de usuario, pueden usar WinUI 3, WPF o WinForms u otro marco de interfaz de usuario.

Información general

Los desarrolladores de paquetes con ubicación externa y aplicaciones sin empaquetar son responsables de implementar los paquetes del entorno de ejecución necesarios del SDK de Aplicaciones para Windows en sus usuarios finales. Para ello, se puede ejecutar el instalador o instalar directamente los paquetes MSIX. Estas opciones se describen con más detalle en la sección Implementación del entorno de ejecución del SDK de Aplicaciones para Windows más adelante.

Las aplicaciones empaquetadas con ubicación externa y las aplicaciones sin empaquetar también tienen requisitos adicionales del entorno de ejecución. Debe inicializar el acceso al entorno de ejecución del SDK de Aplicaciones para Windows mediante la API Bootstrapper. Además, la API Dynamic Dependencies se puede usar si la aplicación utiliza otros paquetes de marco aparte del SDK de Aplicaciones para Windows. Estos requisitos se describen con más detalle en la sección Requisitos del entorno de ejecución para aplicaciones empaquetadas con ubicación externa o sin empaquetar más adelante.

Requisitos previos

Requisitos previos adicionales

  • Las versiones experimentales y preliminares del SDK de Aplicaciones para Windows requieren que la instalación de prueba esté habilitada para instalar el entorno de ejecución.
    • La instalación de prueba se habilita automáticamente en Windows 10, versión 2004 y posteriores.

    • Si el equipo de desarrollo o el equipo de implementación ejecutan Windows 11, confirme si la instalación de prueba está habilitada:

      • Configuración>Privacidad y seguridad>Para desarrolladores. Asegúrese de que la opción Modo de desarrollador esté activada.
    • Si el equipo de desarrollo o el equipo de implementación ejecutan Windows 10, versión 1909 o anterior, confirme si la instalación de prueba está habilitada:

      • Configuración>Actualización y seguridad>Para desarrolladores>Usar características de desarrollador. Confirme que la opción Instalación de prueba de aplicaciones o Modo de desarrollador esté seleccionada.
    • La opción Modo de desarrollador incluye la instalación de prueba, así como otras características.

      Nota:

      Si el equipo se administra en un entorno empresarial, puede haber una directiva que impida que se cambie esta configuración. En ese caso, si recibe un error cuando usted o la aplicación intentan instalar el entorno de ejecución de SDK de Aplicaciones para Windows, póngase en contacto con el profesional de TI para habilitar la instalación de prueba o el Modo de desarrollador.

Implementación del entorno de ejecución de SDK de Aplicaciones para Windows

Las aplicaciones empaquetadas con ubicación externa y las aplicaciones sin empaquetar tienen dos opciones para implementar el entorno de ejecución de SDK de Aplicaciones para Windows:

  • Opción 1: Utilizar el instalador: El instalador silencioso distribuye todos los paquetes MSIX del SDK de Aplicaciones para Windows. Hay disponible un instalador independiente para cada una de las arquitecturas X64, X86 y Arm64.
  • Opción 2: Instalar los paquetes directamente: Puede hacer que la herramienta MSI o la instalación existente instalen los paquetes MSIX para el SDK de Aplicaciones para Windows.

Opción 1: Utilizar el instalador

Puede ejecutar el instalador para implementar todos los paquetes del entorno de ejecución del SDK de Aplicaciones para Windows. El instalador está disponible en Descargas para el SDK de Aplicaciones para Windows. Cuando se ejecute el instalador (.exe), debería ver una salida similar a la siguiente:

Deploying package: Microsoft.WindowsAppRuntime.1.0_0.318.928.0_x64__8wekyb3d8bbwe
Package deployment result : 0x0

Deploying package: Microsoft.WindowsAppRuntime.1.0_0.318.928.0_x86__8wekyb3d8bbwe
Package deployment result : 0x0

Deploying package: MicrosoftCorporationII.WindowsAppRuntime.Main.1.0_0.318.928.0_x64__8wekyb3d8bbwe
Package deployment result : 0x0
Provisioning result : 0x0

Deploying package: Microsoft.WindowsAppRuntime.Singleton_0.318.928.0_x64__8wekyb3d8bbwe
Package deployment result : 0x0
Provisioning result : 0x0

Deploying package: Microsoft.WinAppRuntime.DDLM.0.318.928.0-x6_0.318.928.0_x64__8wekyb3d8bbwe
Package deployment result : 0x0
Provisioning result : 0x0

Deploying package: Microsoft.WinAppRuntime.DDLM.0.318.928.0-x8_0.318.928.0_x86__8wekyb3d8bbwe
Package deployment result : 0x0
Provisioning result : 0x0

All install operations successful.

Puede ejecutar el instalador sin interacción del usuario y suprimir todas las salidas de texto con la opción --quiet:

WindowsAppRuntimeInstall.exe --quiet

También puede elegir forzar la actualización de los paquetes MSIX y apagar los procesos del SDK de Aplicaciones para Windows que se ejecutan actualmente mediante la opción --force. Esta característica se introdujo en 1.1.

WindowsAppRuntimeInstall.exe --force

Para ver todas las opciones de línea de comandos del instalador, ejecute WindowsAppRuntimeInstall --h.

Una vez completada la instalación, puede ejecutar la aplicación empaquetada con ubicación externa o la aplicación sin empaquetar. Para ver un ejemplo de cómo compilar y ejecutar una aplicación empaquetada con ubicación externa o sin empaquetar que utilice el SDK de Aplicaciones para Windows, consulte Tutorial: Uso de la API de arranque en una aplicación empaquetada con ubicación externa o desempaquetada que usa el SDK de Aplicaciones para Windows.

Encadene el instalador del SDK de Aplicaciones para Windows a la configuración de la aplicación.

Si tiene un programa de instalación personalizado para la aplicación, puede encadenar el proceso de instalación del SDK de Aplicaciones para Windows en el proceso de instalación de la aplicación. Actualmente, el instalador del SDK de Aplicaciones para Windows no proporciona una interfaz de usuario predeterminada, por lo que deberá encadenar mediante la interfaz de usuario personalizada de la instalación.

Puede iniciar y realizar un seguimiento silencioso de la instalación del SDK de Aplicaciones para Windows mientras muestra su propia vista del progreso de la instalación mediante ShellExecute. El instalador del SDK de Aplicaciones para Windows desempaqueta silenciosamente el paquete MSIX de la aplicación de Windows y llama al método PackageManager.AddPackageAsync para completar la instalación. Esto es muy similar a otros instaladores de entorno de ejecución que pueda haber usado, como .NET, Visual C++ o DirectX.

Para obtener un ejemplo de código que muestra cómo ejecutar el instalador del SDK de Aplicaciones para Windows desde el programa de instalación, consulte la función RunInstaller en las pruebas funcionales del instalador.

Ejemplo del instalador

Consulte el ejemplo siguiente para ver cómo iniciar el instalador desde un programa de instalación de Win32 sin que aparezca una ventana de consola durante la instalación:

Solución de problemas

Códigos de retorno

En la tabla siguiente se enumeran los códigos de retorno más comunes para el instalador .exe del SDK de Aplicaciones para Windows. Los códigos devueltos son los mismos para todas las versiones del instalador.

Código devuelto Descripción
0x0 La instalación o el aprovisionamiento de los paquetes se completaron correctamente.
0x80073d06 No se pudieron instalar uno o varios paquetes.
0x80070005 No se pudo instalar o aprovisionar todo el sistema porque la aplicación no se ejecuta con privilegios elevados o el usuario encargado de la instalación no tiene privilegios de administrador.

Errores de instalación

Si el instalador del SDK de Aplicaciones para Windows devuelve un error durante la instalación, devolverá un código de error que describe el problema.

Opción 2: Implementar directamente paquetes del entorno de ejecución del SDK de Aplicaciones para Windows

Como alternativa al uso del instalador del SDK de Aplicaciones para Windows para la implementación a los usuarios finales, puedes implementar manualmente los paquetes MSIX a través del programa o MSI de la aplicación. Esta opción puede ser la mejor para los desarrolladores que desean tener más control.

Para ver un ejemplo en el que se muestra cómo el programa de instalación puede instalar los paquetes MSIX, consulte install.cpp en el código del instalador del SDK de Aplicaciones para Windows.

Para comprobar si el SDK de Aplicaciones para Windows ya está instalado (y, si es así, qué versión), puede comprobar si hay familias de paquetes específicas llamando a PackageManager.FindPackagesForUserWithPackageTypes.

Desde un proceso sin empaquetar mediumIL (plena confianza) (consulte Elemento Application), puede usar el código siguiente para comprobar si hay un paquete registrado en el usuario actual:

using Windows.Management.Deployment;

public class WindowsAppSDKRuntime
{
    public static IsPackageRegisteredForCurrentUser(
        string packageFamilyName,
        PackageVersion minVersion,
        Windows.System.ProcessorArchitecture architecture,
        PackageTypes packageType)
    {
        ulong minPackageVersion = ToVersion(minVersion);

        foreach (var p : PackageManager.FindPackagesForUserWithPackageTypes(
            string.Empty, packageFamilyName, packageType)
        {
            // Is the package architecture compatible?
            if (p.Id.Architecture != architecture)
            {
                continue;
            }

            // Is the package version sufficient for our needs?
            ulong packageVersion = ToVersion(p.Id.Version);
            if (packageVersion < minPackageVersion)
            {
                continue;
            }

            // Success.
            return true;
        }

        // No qualifying package found.
        return false;
    }

    private static ulong ToVersion(PackageVersion packageVersion)
    {
        return ((ulong)packageVersion.Major << 48) |
               ((ulong)packageVersion.Minor << 32) |
               ((ulong)packageVersion.Build << 16) |
               ((ulong)packageVersion.Revision);
    }
}

Para el escenario anterior, llamar a FindPackagesForUserWithPackageTypes es preferible llamar a FindPackagesForUser. Esto se debe a que puede restringir la búsqueda a (en este ejemplo), solo los paquetes de marco o principal. Además, evita buscar coincidencias con otros tipos de paquetes (como recurso, opcional o agrupación) que no son de interés para este ejemplo.

Para usar el contexto de usuario actual o de llamada, establezca el parámetro userSecurityId en una cadena vacía.

Y ahora hay información que le ayudará a decidir cómo llamar a la función en el ejemplo de código anterior. Un entorno de ejecución instalado correctamente se compone de varios paquetes que dependen de la arquitectura de CPU del sistema:

  • En una máquina x86: Fwk=[x86], Main=[x86], Singleton=[x86], DDLM=[x86].
  • En una máquina x64: Fwk=[x86, x64], Main=[x64], Singleton=[x64], DDLM=[x86, x64].
  • En una máquina arm64: Fwk=[x86, x64, arm64], Main=[arm64], Singleton=[arm64], DDLM=[x86, x64, arm64].

Para los paquetes Main y Singleton , su arquitectura debe coincidir con la arquitectura de CPU del sistema; por ejemplo, paquetes x64 en un sistema x64. Para el paquete Framework , un sistema x64 puede ejecutar aplicaciones x64 y x86; de forma similar, un sistema arm64 puede ejecutar aplicaciones arm64, x64 y x86. Una comprobación de paquetes DDLM es similar a una comprobación de Framework, excepto que PackageType=main, y packagefamilyname difieren, y más de un packagefamilyname (diferente) podría ser aplicable, debido al esquema de nomenclatura único de DDLM. Para obtener más información, consulta la especificación de paquetes MSIX. Por lo tanto, las comprobaciones son más parecidas a las siguientes:

public static bool IsRuntimeRegisteredForCurrentUser(PackageVersion minVersion)
{
    ProcessorArchitecture systemArchitecture = DetectSystemArchitecture();

    return IsFrameworkRegistered(systemArchitecture, minVersion) &&
           IsMainRegistered(systemArchitecture, minVersion) &&
           IsSingletonRegistered(systemArchitecture, minVersion) &&
           IsDDLMRegistered(systemArchitecture, minVersion);
}

private static ProcecssorArchitecture DetectSystemArchitecture()
{
    // ...see the call to IsWow64Process2(), and how the result is used...
    // ...as per `IsPackageApplicable()` in
    // [install.cpp](https://github.com/microsoft/WindowsAppSDK/blob/main/installer/dev/install.cpp)
    // line 99-116...
    // ...WARNING: Use IsWow64Process2 to detect the system architecture....
    // ...         Other similar APIs exist, but don't give reliably accurate results...
}

private static bool IsFrameworkRegistered(ProcessorArchitecture systemArchitecture,
    PackageVersion minVersion)
{
    // Check x86.
    if (!IsPackageRegisteredForCurrentUser(
        global::Microsoft.WindowsAppSDK.Runtime.Packages.Framework.PackageFamilyName,
        minVersion, ProcessorArchitecture.X86,
        PackageTypes.Framework))
    {
        return false;
    }

    // Check x64 (if necessary).
    if ((systemArchitecture == ProcessorArchitecture.X64) || 
        (systemArchitecture == ProcessorArchitcture.Arm64))
    {
        if (!IsPackageRegisteredForCurrentUser(
            global::Microsoft.WindowsAppSDK.Runtime.Packages.Framework.PackageFamilyName,
            minVersion, ProcessorArchitecture.X64,
            PackageTypes.Framework))
        {
            return false;
        }
    }

    // Check arm64 (if necessary).
    if (systemArchitecture == ProcessorArchitcture.Arm64)
    {
        if (!IsPackageRegisteredForCurrentUser(
            global::Microsoft.WindowsAppSDK.Runtime.Packages.Framework.PackageFamilyName,
            minVersion, ProcessorArchitecture.Arm64,
            PackageTypes.Framework))
        {
            return false;
        }
    }

    return true;
}

private static bool IsMainRegistered(ProcessorArchitecture systemArchitecture,
    PackageVersion minVersion)
{
    return IsPackageRegisteredForCurrentUser(
        global::Microsoft.WindowsAppSDK.Runtime.Packages.Main.PackageFamilyName,
        minVersion,
        systemArchitecture,
        PackageTypes.Main);
}

private static bool IsSingletonRegistered(ProcessorArchitecture systemArchitecture,
    PackageVersion minVersion)
{
    return IsPackageRegisteredForCurrentUser(
        global::Microsoft.WindowsAppSDK.Runtime.Packages.Singleton.PackageFamilyName,
        minVersion,
        systemArchitecture,
        PackageTypes.Main);
}

private static bool IsDDLMRegistered(ProcessorArchitecture systemArchitecture,
    PackageVersion minVersion)
{
    // ...similar to IsFrameworkRegistered, but the packageFamilyName is more complicated...
    // ...and no predefined constant is currently available...
    // ...for more details, see
    // https://github.com/microsoft/WindowsAppSDK/blob/main/specs/Deployment/MSIXPackages.md.
}

La información y el código anterior tratan el escenario de detección básico. Para detectar si el tiempo de ejecución se aprovisiona para todos los usuarios, o para hacer lo anterior desde un contenedor de aplicaciones o hacerlo desde un proceso empaquetado mediumIL , se necesita lógica adicional.

Escenarios de implementación

  • Instalación del entorno de ejecución del SDK de Aplicaciones para Windows en todo el sistema : La instalación en todo el sistema modifica la máquina para todos los usuarios, incluidos los nuevos usuarios que se agreguen más adelante. Si la aplicación se ejecuta con privilegios elevados y el usuario que se encarga de la instalación tiene privilegios de administrador, el instalador llamará a ProvisionPackageForAllUsersAsync para registrar los paquetes MSIX en todo el sistema. Si el registro en todo el sistema no se completa correctamente, la instalación se completará solo para el usuario actual que realiza la instalación. En un entorno empresarial administrado, el administrador de TI debe poder aprovisionar para todos los usuarios como de costumbre.

  • Arquitecturas redistribuidas por el instalador de SDK de Aplicaciones para Windows: el instalador de SDK de Aplicaciones para Windows está disponible en las x86arquitecturas , x64y Arm64 . Cada versión del instalador incluye los paquetes MSIX solo para la arquitectura específica para la que se denomina. Por ejemplo, si ejecuta en x86 WindowsAppRuntimeInstall.exe un dispositivo x64 o Arm64, ese x86 instalador se implementará en ese dispositivo solo los paquetes de la arquitectura x86.

  • Todos los paquetes MSIX del SDK de Aplicaciones para Windows ya están instalados en el equipo: Los paquetes MSIX se instalan en una ubicación en todo el sistema con solo una copia en el disco. Si una aplicación intenta instalar el SDK de Aplicaciones para Windows cuando todas las dependencias de paquete MSIX ya están instaladas en la máquina, no se realiza la instalación.

  • Uno o varios de los paquetes MSIX del SDK de Aplicaciones para Windows no están instalados en el equipo: Al implementar el SDK de Aplicaciones para Windows, intente instalar siempre todos los paquetes MSIX (marcos, Main, Singleton, DDLM) para asegurarse de que todas las dependencias estén instaladas y evitar afectar a la experiencia del usuario final.

Requisitos del entorno de ejecución para aplicaciones empaquetadas con ubicación externa o sin empaquetar

Las aplicaciones empaquetadas con ubicación externa o sin empaquetar tienen requisitos adicionales del entorno de ejecución para usar el entorno de ejecución del SDK de Aplicaciones para Windows. Esto implica hacer referencia e inicializar el paquete de marco del SDK de Aplicaciones para Windows en tiempo de ejecución. Además, la API Dynamic Dependencies se puede usar para hacer referencia a otros paquetes de marco aparte del SDK de Aplicaciones para Windows.

Uso del entorno de ejecución del SDK de Aplicaciones para Windows

Las aplicaciones empaquetadas con ubicación externa y sin empaquetar deben llamar a la API Bootstrapper para usar el SDK de Aplicaciones para Windows en tiempo de ejecución. Esto es necesario para que la aplicación pueda usar las características del SDK de Aplicaciones para Windows, como WinUI, Ciclo de vida de la aplicación, MRT Core y DWriteCore. Un componente del programa previo permite que las aplicaciones empaquetadas con ubicación externa y sin empaquetar realicen estas tareas importantes:

  • Busque y cargue el paquete de marco del SDK de Aplicaciones para Windows en el grafo de paquetes de la aplicación.
  • Inicialice Dynamic Dependency Lifetime Manager (DDLM) para el paquete de marco del SDK de Aplicaciones para Windows. El propósito de DDLM es evitar el mantenimiento del paquete de marco del SDK de Aplicaciones para Windows mientras está en uso por parte de una aplicación empaquetada con ubicación externa o sin empaquetar.

La manera más sencilla de cargar el entorno de ejecución del SDK de Aplicaciones para Windows para aplicaciones empaquetadas con ubicación externa y sin empaquetar es establecer la propiedad <WindowsPackageType>None</WindowsPackageType> en el archivo de proyecto (.csproj o .vcxproj). También puede llamar a la API Bootstrapper directamente en el código de inicio de la aplicación para tener más control sobre la inicialización. Para obtener más información, consulte Uso del entorno de ejecución de SDK de Aplicaciones para Windows para aplicaciones empaquetadas con ubicación externa o sin empaquetar y Tutorial: Uso de la API de arranque en una aplicación empaquetada con ubicación externa o desempaquetada que usa el SDK de Aplicaciones para Windows.

La compatibilidad de Dynamic Dependencies permite que las aplicaciones empaquetadas con ubicación externa y sin empaquetar mantengan su mecanismo de implementación existente, como MSI o cualquier instalador, y puedan aprovechar el SDK de Aplicaciones para Windows en su aplicación. Las aplicaciones empaquetadas, empaquetadas con ubicación externa y sin empaquetar pueden usar dependencias dinámicas; aunque esto está pensado principalmente para aplicaciones empaquetadas con ubicación externa y sin empaquetar.

Hay un DDLM para cada versión y arquitectura del paquete de marco del SDK de Aplicaciones para Windows. Es decir, en un equipo x64 es posible que tenga una versión x86 y x64 de DDLM para admitir aplicaciones de ambas arquitecturas.

Referencia a otros paquetes de marco mediante la API Dynamic Dependencies

Si desea usar características de otros paquetes de marcos fuera del SDK de Aplicaciones para Windows (por ejemplo, DirectX), las aplicaciones empaquetadas con ubicación externa y sin empaquetar pueden llamar a la API Dynamic Dependencies. Además del componente de programa previo, el SDK de Aplicaciones para Windows también proporciona un conjunto más amplio de funciones de C/C++ y clases winRT que implementan la API Dynamic Dependencies. Esta API está diseñada para usarse para hacer referencia a cualquier paquete de marco dinámicamente en tiempo de ejecución.

Para obtener más información, consulte Uso dinámico de paquetes de marcos MSIX desde la aplicación de escritorio y el ejemplo de Dynamic Dependencies.

Implementación de archivos .winmd en la máquina de destino

Junto con la aplicación, se recomienda seguir adelante e implementar archivos de metadatos de Windows (.winmd). Los metadatos se pueden usar en varias API y comportamientos en tiempo de ejecución, y su ausencia puede limitar o interrumpir la funcionalidad. Por ejemplo, los metadatos se pueden utilizar para serializar objetos más allá de los límites de apartamentos, y la necesidad de serializar puede depender del rendimiento de la máquina. Dado que no hay ninguna forma determinista de saber si necesita metadatos, debe implementar .winmda menos que le preocupe mucho el tamaño.