C#/WinRT

C#/WinRT es un kit de herramientas con paquetes NuGet que proporciona compatibilidad con la proyección de Windows Runtime (WinRT) para el lenguaje C#. Un ensamblado de proyección se refiere a un ensamblado de interoperabilidad, que le permite programar las API de WinRT de una manera natural y familiar en función del idioma de destino. La proyección de C#/WinRT oculta los detalles de la interoperabilidad entre las interfaces de C# y WinRT, y proporciona asignaciones de muchos tipos de WinRT a los equivalentes adecuados de .NET, como cadenas, URI, tipos de valores comunes y colecciones genéricas.

Actualmente, C#/WinRT proporciona compatibilidad para consumir las API de WinRT mediante el uso de los monikers del marco de destino (TFM) de .NET. Al establecer el TFM con una versión específica de Windows SDK se agregan referencias a los ensamblados en tiempo de ejecución y de proyección de Windows SDK generados por C#/WinRT.

El paquete NuGet de C#/WinRT le permite crear y hacer referencia a sus propios ensamblados de interoperabilidad de WinRT para los clientes de .NET. La versión más reciente de C#/WinRT también incluye una versión preliminar de la creación de tipos de WinRT en C#.

Para obtener más información, consulte el repositorio de C#/WinRT en GitHub.

Motivación para C#/WinRT

.NET (anteriormente conocido como .NET Core) es un entorno de ejecución multiplataforma y de código abierto que se puede usar para compilar aplicaciones de dispositivo, nube e IoT.

Las versiones anteriores de .NET Framework y .NET Core tenían conocimientos integrados de WinRT, una tecnología específica de Windows. Para admitir los objetivos de portabilidad y eficiencia de .NET 6 y versiones posteriores, hemos quitado la compatibilidad con la proyección de WinRT del compilador de C# y del entorno de ejecución de .NET y la hemos movido al kit de herramientas de C#/WinRT (consulte La compatibilidad integrada con WinRT se ha quitado de .NET). El objetivo de C#/WinRT es proporcionar paridad con la compatibilidad integrada de WinRT proporcionada por las versiones anteriores del compilador de C# y el entorno de ejecución de .NET. Para más detalles, consulta Asignaciones de .NET de tipos de Windows Runtime.

C#/WinRT también admite componentes del SDK de Aplicaciones para Windows, como WinUI 3. El SDK de Aplicaciones para Windows permite sacar del sistema operativo los controles nativos de la interfaz de usuario de Microsoft y otros componentes nativos. Esto permite a los desarrolladores de aplicaciones usar los controles y componentes más recientes en Windows 10, versión 1809 y versiones posteriores.

Por último, C#/WinRT es un kit de herramientas general y está diseñado para admitir otros escenarios en los que la compatibilidad integrada con WinRT no está disponible en el compilador de C# o el entorno de ejecución de .NET.

Novedades

Las versiones más recientes de C#/WinRT se pueden encontrar en nuestra página de notas de la versión del repositorio de GitHub.

Uso

El paquete NuGet de C#/WinRT se puede usar para generar proyecciones de C# (también denominadas ensamblados de interoperabilidad) a partir de componentes de WinRT y en Creación de componentes de C#/WinRT. Para obtener más detalles sobre los escenarios de uso para C#/WinRT, consulte la guía de uso de nuestro repositorio.

Generación y distribución de un ensamblado de interoperabilidad

Las API de WinRT se definen en archivos de metadatos de Windows (WinMD). El paquete NuGet de C#/WinRT (Microsoft.Windows.CsWinRT) incluye el compilador de C#/WinRT, cswinrt.exe, que puede usar para procesar archivos WinMD y generar código de .NET en C#. C#/WinRT compila estos archivos de origen en ensamblados de interoperabilidad, de forma similar a como C++/WinRT genera encabezados para la proyección de lenguaje C++. A continuación, puede distribuir el ensamblado de interoperabilidad de C#/WinRT junto con el ensamblado de implementación al que hacen referencia las aplicaciones de .NET, normalmente como paquete NuGet.

Para obtener más información sobre cómo generar y distribuir un ensamblado de interoperabilidad, consulte Generación de una proyección de C# a partir de un componente de C++/WinRT y distribución como paquete NuGet para aplicaciones de .NET.

Referencia a un ensamblado de interoperabilidad

Normalmente, los proyectos de aplicación hacen referencia a los ensamblados de interoperabilidad de C#/WinRT. Pero, a su vez, también pueden hacer referencia a ellos los ensamblados de interoperabilidad intermedios. Por ejemplo, el ensamblado de interoperabilidad WinUI haría referencia al ensamblado de interoperabilidad de Windows SDK.

Si distribuye un componente de WinRT de terceros sin un ensamblado de interoperabilidad oficial, un proyecto de aplicación puede seguir el procedimiento para crear un ensamblado de interoperabilidad para generar sus propios orígenes de proyección privados. No recomendamos este enfoque, ya que puede producir proyecciones en conflicto del mismo tipo dentro de un proceso. El empaquetado de NuGet, según el esquema de Semantic Versioning, está diseñado para evitar esto. Se prefiere un ensamblado de interoperabilidad de terceros oficial.

Compatibilidad integrada con tipos de WinRT (versión preliminar)

A partir de la versión 1.4.1 de C#/WinRT, se incluye compatibilidad para integrar la proyección de Windows SDK y los orígenes del entorno en tiempo de ejecución para .NET y .NET Standard 2.0 en la salida de la biblioteca o aplicación. Esto resulta útil en los casos en que el uso de tipos de Windows SDK es independiente. La compatibilidad integrada quita las dependencias WinRT.Runtime.dll y Microsoft.Windows.SDK.NET.dll, lo que reduce el tamaño de salida de la biblioteca o la aplicación. También permite a los desarrolladores de bibliotecas proporcionar compatibilidad de nivel inferior y elimina la necesidad de admitir múltiples destinos.

Para obtener más información, consulte la documentación sobre la integración de C#/WinRT en nuestro repositorio.

Activación de tipos de WinRT

C#/WinRT admite la activación de tipos de WinRT hospedados por el sistema operativo, así como componentes de terceros, como Win2D. La compatibilidad con la activación de componentes de terceros en una aplicación de escritorio se habilita con la activación de WinRT sin registro (consulte el blog sobre la mejora de aplicaciones de escritorio no empaquetadas mediante componentes de Windows Runtime), disponible en Windows 10, versión 1903 y versiones posteriores. Los componentes nativos de C++ deben establecer la propiedad Compatible con el escritorio de Windows en True a través de las propiedades del proyecto o del archivo .vcxproj, para hacer referencia y reenviar los archivos binarios Microsoft.VCLibs.Desktop a aplicaciones de consumo. De lo contrario, el paquete VCRT Forwarders será necesario mediante el consumo de aplicaciones si el componente solo tiene como destino aplicaciones para UWP.

C#/WinRT también proporciona una ruta de reserva de activación si Windows no puede activar el tipo tal y como se ha descrito anteriormente. En este caso, C#/WinRT intenta encontrar un archivo DLL de implementación nativo en función del nombre de tipo completo, quitando progresivamente los elementos. Por ejemplo, la lógica de reserva intentaría activar el tipo Contoso.Controls.Widget desde los módulos siguientes, en secuencia:

  1. Contoso.Controls.Widget.dll
  2. Contoso.Controls.dll
  3. Contoso.dll

C#/WinRT usa el orden de búsqueda alternativo LoadLibrary para buscar un archivo DLL de implementación. Una aplicación que se base en este comportamiento de reserva debe empaquetar el archivo DLL de implementación junto con el módulo de la aplicación.

Errores comunes y solución de problemas

  • Error: "No se han proporcionado ni detectado metadatos de Windows".

    Puede especificar los metadatos de Windows mediante la propiedad de proyecto <CsWinRTWindowsMetadata>; por ejemplo:

    <CsWinRTWindowsMetadata>10.0.19041.0</CsWinRTWindowsMetadata>
    

    En C#/WinRT versión 1.2.1 y posteriores, esta propiedad tiene como valor predeterminado TargetPlatformVersion, que se deriva de la versión de Windows SDK especificada en la propiedad TargetFramework.

  • Error CS0246: No se pudo encontrar el nombre del espacio de nombres o el tipo "Windows" (¿le falta una directiva de uso o una referencia de ensamblado?).

    Para solucionar este error, edite la propiedad <TargetFramework> para que tenga como destino una versión específica de Windows; por ejemplo:

    <TargetFramework>net6.0-windows10.0.19041.0</TargetFramework>
    

    Consulte los documentos acerca de las llamadas a las API de Windows en tiempo de ejecución para obtener más información sobre cómo especificar la propiedad <TargetFramework>.

  • System.InvalidCastException al convertir a una interfaz que tiene el atributo ComImport.

    Al convertir un objeto en una interfaz que tiene el atributo ComImport, deberá usar el operador .As<> en lugar de usar una expresión de conversión explícita. Por ejemplo:

    someObject.As<SomeComImportInterface>
    

    Para obtener más información, consulte la guía de interoperabilidad COM.

  • System.Runtime.InteropServices.COMException: Clase no registrada (0x80040154 (REGDB_E_CLASSNOTREG))

    • Si ve esta excepción al consumir una proyección de C#/WinRT desde un componente de C++/WinRT, asegúrese de que el componente ha establecido la propiedad Compatible con el escritorio de Windows esté establecida en True a través de las propiedades del proyecto o a través del archivo .vcxproj.

Errores del control de versiones del SDK de .NET

Puede encontrar los siguientes errores o advertencias en un proyecto compilado con una versión del SDK de .NET anterior a cualquiera de sus dependencias.

Mensaje de error o advertencia Motivo
Advertencia MSB3277: Se encontraron conflictos entre diferentes versiones de WinRT.Runtime o Microsoft.Windows.SDK.NET que no se pudieron resolver. Esta advertencia de compilación se produce cuando se hace referencia a una biblioteca que expone los tipos de Windows SDK en su superficie de API.
Error CS1705: El ensamblado "AssemblyName1" usa el elemento "TypeName", que tiene una versión superior a la del ensamblado "AssemblyName2" al que se hace referencia. Este error del compilador se produce al hacer referencia y consumir los tipos de Windows SDK que están expuestos en una biblioteca.
System.IO.FileLoadException Este error en tiempo de ejecución puede producirse al llamar a determinadas API de una biblioteca que no expone los tipos de Windows SDK.

Para corregir estos errores, actualice el SDK de .NET a la versión más reciente. De este modo, se asegurará de que las versiones del ensamblado en tiempo de ejecución y de Windows SDK que usa la aplicación sean compatibles con todas las dependencias. Recuerde que estos errores pueden producirse con actualizaciones de características o de mantenimiento anticipadas en el SDK de .NET, ya que las correcciones en tiempo de ejecución pueden requerir actualizaciones de las versiones de ensamblado.

Problemas conocidos

Los problemas conocidos y los cambios importantes se anotan en el repositorio de GitHub de C#/WinRT.

Si tienes algún problema funcional con el paquete NuGet de C#/WinRT, el compilador cswinrt.exe o los orígenes de proyección generados, envíanos los problemas a través de la página de problemas de C#/WinRT.

Recursos adicionales