Llamada a las a API de Windows Runtime en aplicaciones de escritorio
Artículo
En este artículo se describe cómo configurar los proyectos de aplicación de escritorio para usar las API de Windows Runtime (WinRT) que proporciona el sistema operativo Windows y agregar experiencias modernas de Windows 11 y Windows 10 a las aplicaciones de escritorio.
Modificación de un proyecto de .NET para usar las API de Windows Runtime
Hay varias opciones para los proyectos de .NET:
A partir de .NET 6, puede especificar un moniker de la plataforma de destino (TFM) en el archivo de proyecto para acceder a las API de WinRT. Esta opción se admite en proyectos que tienen como destino Windows 10, versión 1809 o posterior.
Para versiones anteriores de .NET, puede instalar el paquete NuGet Microsoft.Windows.SDK.Contracts para agregar todas las referencias necesarias al proyecto. Esta opción se admite en proyectos que tienen como destino Windows 10, versión 1803 o posterior.
Si el proyecto tiene varios destinos .NET 6 (o posterior) y versiones anteriores de .NET, puede configurar el archivo del proyecto para usar ambas opciones.
.NET 6 y versiones posteriores: uso de la opción de moniker de la plataforma de destino
Esta opción solo se admite en proyectos que usan .NET 6 (o una versión posterior), y están destinados a Windows 10, versión 1809 o una versión posterior del sistema operativo. Al especificar un TFM específico de la versión del sistema operativo Windows en el archivo del proyecto, se agrega una referencia al paquete de destino del SDK de Windows adecuado. Para obtener más información general sobre este escenario, consulte la entrada de blog Llamada de API de Windows en .NET.
Con el proyecto abierto en Visual Studio, haga clic con el botón derecho en el proyecto en Explorador de soluciones y elija Editar archivo de proyecto. El archivo de proyecto debería tener un aspecto similar al siguiente.
Nota
En el ejemplo siguiente se muestra un elemento OutputTypeWinExe, que especifica un ejecutable de GUI de Windows (e impide que se abra una ventana de consola cuando se ejecuta la aplicación). Si la aplicación no tiene ninguna GUI, OutputType tendrá un valor diferente. Puede llamar a las API de WinRT desde aplicaciones de GUI de Windows, aplicaciones de consola y bibliotecas. Además, es posible que el valor de TargetFramework no coincida exactamente con el ejemplo siguiente.
En versiones posteriores de .NET, puede reemplazar el valor por la versión pertinente, por ejemplo, net8.0-windows10.0.19041.0.
Guarde los cambios y cierre el archivo de proyecto.
Las API de WinRT no se admiten en .NET 6 ni versiones posteriores
En .NET 6 y versiones posteriores, hay varias API de Windows Runtime (WinRT) en el espacio de nombres Windows.UI que no se admiten. Para las API que se enumeran a continuación, existen versiones de API equivalentes en el espacio de nombres WinUI (Microsoft.UI) (por ejemplo, Microsoft.UI.Text). Las siguientes API de WinRT no se admiten en .NET 6 y versiones posteriores:
Windows.UI.Text (todas las clases en este espacio de nombres, exceptoWindows.UI.Text.FontStretch, Windows.UI.Text.FontStyle, Windows.UI.Text.FontWeight, Windows.UI.Text.UnderlineType, y todas las clases en el espacio de nombres Windows.UI.Text.Core)
Windows.UI.Xaml (todas las clases en este espacio de nombres)
Compatibilidad con varias versiones del sistema operativo Windows
La propiedad TargetFramework específica de la versión del sistema operativo Windows determina la versión de Windows SDK con la que se compila la aplicación. Esta propiedad determina el conjunto de API accesibles en tiempo de compilación y proporciona valores predeterminados para TargetPlatformVersion y TargetPlatformMinVersion (si no se establece explícitamente). No es necesario definir explícitamente la propiedad TargetPlatformVersion en el archivo de proyecto, ya que la establece automáticamente la versión del sistema operativo de TargetFramework.
TargetPlatformMinVersion se puede invalidar para que sea menor que TargetPlatformVersion (determinado por la versión de la propiedad TargetFramework). Esto permite que una aplicación se ejecute en versiones anteriores del sistema operativo. Por ejemplo, puede establecer lo siguiente en el archivo de proyecto para admitir la aplicación de nivel inferior en Windows 10, versión 1809.
Tenga en cuenta que establecer TargetPlatformMinVersion en una versión inferior a TargetPlatformVersion crea la posibilidad de llamar a API no disponibles. Al llamar a API de WinRT que no están disponibles en todas las versiones de sistema operativo admitidas, se recomienda proteger estas llamadas con comprobaciones ApiInformation. Para más información, consulte Aplicaciones adaptables para versiones.
Versiones anteriores de .NET: Instale el paquete NuGet Microsoft.Windows.SDK.Contracts.
Use esta opción si la aplicación usa .NET Core 3.x o .NET Framework. Esta opción se admite en proyectos que tienen como destino Windows 10, versión 1803 o posterior.
En Visual Studio, haga clic en Herramientas-> Administrador de paquetes NuGet-> Configuración del Administrador de paquetes.
Asegúrate de que PackageReference está seleccionado para Formato predeterminado de administración de paquetes.
Una vez hayas creado tu proyecto en Visual Studio, haz clic con el botón derecho en el Explorador de soluciones y elige Administrar paquetes NuGet.
En la ventana Administrador de paquetes NuGet, selecciona la pestaña Examinar y busca Microsoft.Windows.SDK.Contracts.
Una vez encontrado el paquete Microsoft.Windows.SDK.Contracts, en el panel derecho de la ventana Administrador de paquetes NuGet, selecciona la Versión del paquete que quieres instalar en función de la versión de Windows 10 de destino deseada:
10.0.19041.xxxx: elija esta versión para Windows 10, versión 2004.
10.0.18362.xxxx: elije esta versión para Windows 10, versión 1903.
10.0.17763.xxxx: elije esta versión para Windows 10, versión 1809.
10.0.17134.xxxx: elije esta versión para Windows 10, versión 1803.
Haga clic en Instalar.
Configuración de proyectos que tienen como destino diferentes versiones de .NET
Si el proyecto tiene varios destinos de .NET 6 (o posterior) y versiones anteriores (incluidos .NET Core 3.x y .NET Framework), puede configurar el archivo del proyecto para que use el moniker de la plataforma de destino (TFM) a fin de extraer automáticamente las referencias de API de WinRT para .NET 6 y usar el paquete NuGet Microsoft.Windows.SDK.Contracts para versiones anteriores.
Con el proyecto abierto en Visual Studio, haga clic con el botón derecho en el proyecto en Explorador de soluciones y elija Editar archivo de proyecto. En el ejemplo siguiente se muestra un archivo de proyecto para una aplicación que usa .NET Core 3.1.
Nota
En el ejemplo siguiente se muestra un elemento OutputTypeWinExe, que especifica un ejecutable de GUI de Windows (e impide que se abra una ventana de consola cuando se ejecuta la aplicación). Si la aplicación no tiene ninguna GUI, OutputType tendrá un valor diferente. Puede llamar a las API de WinRT desde aplicaciones de GUI de Windows, aplicaciones de consola y bibliotecas. Además, es posible que el valor de TargetFramework no coincida exactamente con el ejemplo siguiente.
Reemplace el elemento TargetFramework del archivo por un elemento TargetFrameworks (tenga en cuenta el plural). En este elemento, especifique los monikers de la plataforma de destino (TFM) para todas las versiones de .NET que quiera establecer como destino, separadas por punto y coma.
Para .NET 6 o versiones posteriores, use uno de los siguientes monikers de la plataforma de destino (TFM):
net6.0-windows10.0.17763.0: si la aplicación tiene como destino Windows 10, versión 1809.
net6.0-windows10.0.18362.0: si la aplicación tiene como destino Windows 10, versión 1903.
net6.0-windows10.0.19041.0: si la aplicación tiene como destino Windows 10, versión 2004.
net6.0-windows10.0.22000.0: si la aplicación tiene como destino la versión inicial de Windows 11.
net6.0-windows10.0.22621.0: si la aplicación tiene como destino Windows 11, versión 22H2.
net6.0-windows10.0.26100.0: si la aplicación tiene como destino Windows 11, versión 24H2.
Para .NET Core 3.x, use netcoreapp3.0 o netcoreapp3.1.
Para .NET Framework, use net46.
En el ejemplo siguiente se muestra cómo establecer varios destinos .NET Core 3.1 y .NET 6 (para Windows 10, versión 2004).
Después del elemento PropertyGroup, agregue un elemento PackageReference que incluya una instrucción condicional que instale el paquete NuGet Microsoft.Windows.SDK.Contracts para cualquier versión de .NET Core 3.x o .NET Framework que la aplicación tenga como destino. El elemento PackageReference debe ser un elemento secundario de un elemento ItemGroup. En el siguiente ejemplo, se muestra cómo hacerlo para .NET Core 3.1.
Guarde los cambios y cierre el archivo de proyecto.
Modificación de un proyecto de C++ de escritorio (Win32) para usar las API de Windows Runtime
Use C++/WinRT para utilizar las API de WinRT. C++/WinRT es una moderna proyección de lenguaje C++17 totalmente estándar para las API de WinRT, implementada como una biblioteca basada en archivos de encabezado y diseñada para proporcionarle acceso de primera clase a la API moderna de Windows.
Ya estás listo para agregar experiencias modernas que dan a conocer cuándo los usuarios ejecutan tu aplicación en Windows 10. Usa este flujo de diseño.
✅En primer lugar, decida qué experiencias quiere agregar
Hay muchas entre las que elegir. Por ejemplo, puedes simplificar el flujo de pedidos de compra mediante las API de rentabilidad o dirigir la atención a tu aplicación cuando tengas algo interesante que compartir, por ejemplo, una nueva imagen que otro usuario ha publicado.
Aunque los usuarios ignoren o descarten el mensaje, pueden verlo de nuevo en el centro de actividades y, a continuación, hacer clic en el mensaje para abrir tu aplicación. Esto aumenta la relación con tu aplicación y tiene la ventaja adicional de que la aplicación parezca perfectamente integrada con el sistema operativo. Te mostraremos el código para esa experiencia más adelante en este artículo.
A menudo nos escucharás usar los términos mejorar y ampliar, por lo que vamos a detenernos un momento para explicar exactamente qué significan cada uno.
Usamos el término mejorar para describir las API de WinRT a las que puede llamar directamente desde la aplicación de escritorio, independientemente que sea, o no, una aplicación empaquetada. Cuando hayas elegido una experiencia de Windows 10, identifica las API que necesitas para crearla y comprueba si esa API aparece en esta lista. Esta es una lista de las API a las que puedes llamar directamente desde tu aplicación de escritorio. Si tu API no aparece en esta lista, se debe a que la funcionalidad asociada a esa API solo se puede ejecutar dentro de un proceso de UWP. A menudo, incluyen API que representan XAML de UWP, como un control de mapa de UWP o una advertencia de seguridad de Windows Hello.
Nota
Aunque normalmente no se puede llamar a las API que representan XAML de UWP directamente desde el escritorio, es posible que puedas usar enfoques alternativos. Si quieres hospedar controles XAML de UWP u otras experiencias visuales personalizadas, puedes usar islas XAML (a partir de Windows 10, versión 1903) y la capa visual (a partir de Windows 10, versión 1803). Estas características se pueden usar en aplicaciones de escritorio empaquetadas o sin empaquetar.
Si ha optado por empaquetar la aplicación de escritorio, otra opción es ampliar la aplicación agregando un proyecto de UWP a la solución. El proyecto de escritorio sigue siendo el punto de entrada de tu aplicación, pero el proyecto de UWP te proporciona acceso a todas las API que no aparecen en esta lista. La aplicación de escritorio puede comunicarse con el proceso de UWP mediante un servicio de aplicaciones. Tenemos muchos consejos para darte sobre cómo configurarlo. Si quieres agregar una experiencia que requiere un proyecto de UWP, consulta Ampliación con componentes de UWP.
✅Consulte los contratos de API
Si puedes llamar a la API directamente desde tu aplicación de escritorio, abre un navegador y busca el tema de referencia para esa API.
Debajo del resumen de la API, encontrarás una tabla en la que se describe el contrato de API para esa API. Este es un ejemplo de esa tabla:
Si tienes una aplicación de escritorio basada en .NET, agrega una referencia a ese contrato de API y luego establece la propiedad Copia local de ese archivo en False. Si tienes un proyecto basado en C++, agrega a Directorios de inclusión adicionales una ruta de acceso a la carpeta que contiene este contrato.
✅Llame a las API para agregar la experiencia
Este es el código que usarías para mostrar la ventana de notificación que hemos visto anteriormente. Estas API aparecen en esta lista para que puedas agregar este código a la aplicación de escritorio y ejecutarlo en este momento.
C#
using Windows.Foundation;
using Windows.System;
using Windows.UI.Notifications;
using Windows.Data.Xml.Dom;
...
privatevoidShowToast()
{
string title = "featured picture of the day";
string content = "beautiful scenery";
string image = "https://picsum.photos/360/180?image=104";
string logo = "https://picsum.photos/64?image=883";
string xmlString =
$@"<toast><visual>
<binding template='ToastGeneric'>
<text>{title}</text>
<text>{content}</text>
<image src='{image}'/>
<image src='{logo}' placement='appLogoOverride' hint-crop='circle'/>
</binding>
</visual></toast>";
XmlDocument toastXml = new XmlDocument();
toastXml.LoadXml(xmlString);
ToastNotification toast = new ToastNotification(toastXml);
ToastNotificationManager.CreateToastNotifier().Show(toast);
}
Compatibilidad con bases de instalación de Windows XP, Windows Vista y Windows 7/8
Puedes modernizar tu aplicación para Windows 10 sin tener que crear una nueva rama ni mantener bases de código independientes.
Si quieres compilar archivos binarios independientes para los usuarios de Windows 10, usa la compilación condicional. Si prefieres compilar un conjunto de archivos binarios que implementas en todos los usuarios de Windows, usa las comprobaciones en tiempo de ejecución.
Echemos un vistazo rápido a cada opción.
Compilación condicional
Puedes mantener una base de código y compilar un conjunto de archivos binarios solo para los usuarios de Windows 10.
En primer lugar, agrega una nueva configuración de compilación al proyecto.
Para esa configuración de compilación, cree una constante para identificar el código que llama a las API de WinRT.
Para los proyectos basados en .NET, la constante se llama constante de compilación condicional.
Para los proyectos basados en C++, la constante se llama definición del preprocesador.
Agrega esa constante antes de cualquier bloque de código UWP.
El compilador compila ese código solo si esa constante está definida en la configuración de compilación activa.
Comprobaciones en tiempo de ejecución
Puedes compilar un conjunto de archivos binarios para todos tus usuarios de Windows independientemente de qué versión de Windows ejecuten. La aplicación solo llama a las API de WinRT si el usuario ejecuta la aplicación como una aplicación empaquetada en Windows 10.
¿Tienes alguna pregunta? Pregúntanos en Stack Overflow. Nuestro equipo supervisa estas etiquetas. También puede preguntar en nuestros foros.
Colaborar con nosotros en GitHub
El origen de este contenido se puede encontrar en GitHub, donde también puede crear y revisar problemas y solicitudes de incorporación de cambios. Para más información, consulte nuestra guía para colaboradores.
Comentarios de Windows developer
Windows developer es un proyecto de código abierto. Seleccione un vínculo para proporcionar comentarios:
Cómo resolver el problema de no poder hacer referencia al componente de metadatos de Windows directamente desde una aplicación que tiene como destino .NET 5 o versiones posteriores.
Mejore la aplicación de escritorio para los usuarios mediante una llamada a las funciones de interoperabilidad y a las interfaces de interoperabilidad COM de WinRT, proyectadas en .NET.
Cómo hacer referencia a un componente con la compatibilidad integrada con WinRT desde una aplicación que tiene como destino .NET 5 o una versión posterior.
En este tema, se explica cómo usar [C#/WinRT](/windows/uwp/csharp-winrt/) para generar un ensamblado de proyección (o interoperabilidad) de C# .NET a partir de un componente de Windows Runtime de C++/WinRT y distribuirlo como un Paquete NuGet para aplicaciones .NET.