C#/WinRT

C#/WinRT — это набор средств в виде пакета NuGet, обеспечивающий поддержку проекций среды выполнения Windows (WinRT) для языка C#. Сборка проекции представляет собой сборку взаимодействия, которая позволяет программировать API-интерфейсы WinRT естественным и привычным способом для целевого языка. Проекция C#/WinRT скрывает сведения о взаимодействии между интерфейсами C# и WinRT и обеспечивает сопоставление многих типов WinRT соответствующим эквивалентам .NET, например строкам, URI, общим типам значений и универсальным коллекциям.

В настоящее время C#/WinRT обеспечивает поддержку использования интерфейсов API WinRT с помощью моникеров целевой платформы (TFM) в .NET. При указании моникера целевой платформы с определенной версией Windows SDK добавляются ссылки на проекцию Windows SDK и сборки среды выполнения, созданные C#/WinRT.

Пакет NuGet для C#/WinRT позволяет создавать собственные сборки взаимодействия WinRT для потребителей .NET и ссылаться на них. Кроме того, последняя версия C#/WinRT включает предварительную версию для создания типов WinRT в C#.

Дополнительные сведения см. в репозитории C#/WinRT на сайте GitHub.

Обоснование для использования C#/WinRT

.NET (прежнее название — .NET Core) — это кроссплатформенная среда выполнения с открытым кодом, с помощью которой можно создавать приложения для устройств, облаков и Интернета вещей.

В предыдущие версии .NET Framework и .NET Core были встроены средства поддержки технологии Windows под названием WinRT. Для обеспечения переносимости и эффективности .NET 6 и более поздних версий мы отключили поддержку проекций WinRT в компиляторе и среде выполнения .NET и включили ее в наборе инструментов C#/WinRT (см. статью Встроенная поддержка WinRT отключена в .NET). Задача C#/WinRT заключается в обеспечении такого же уровня поддержки WinRT, как и в более ранних версиях компилятора C# и среды выполнения .NET. Дополнительные сведения см. в статье Сопоставление типов .NET с типами среды выполнения Windows.

C#/WinRT также поддерживает компоненты в пакете SDK для приложений для Windows, включая WinUI 3. Пакет SDK для приложений для Windows выводит из ОС собственные элементы управления пользовательским интерфейсом Майкрософт и другие собственные компоненты. Это позволяет разработчикам приложений использовать новейшие элементы управления и компоненты в Windows 10 версии 1809 и выше.

Наконец, C#/WinRT является общим набором средств и предназначен для поддержки других сценариев, при которых встроенная поддержка WinRT недоступна в компиляторе C# или в среде выполнения .NET.

Новые возможности

Последние выпуски C#/WinRT можно найти на странице заметок о выпуске в репозитории GitHub.

Использование

Пакет NuGet для C#/WinRT можно использовать для создания проекций C# (также называемых сборками взаимодействия) из компонентов WinRT и при работе со статье Создание компонентов C#/WinRT. Дополнительные сведения о сценариях использования C#/WinRT см. в нашем репозитории в этом руководстве .

Создание и распространение сборки взаимодействия

API-интерфейсы WinRT определены в файлах метаданных Windows (WinMD). Пакет NuGet для C#/WinRT (Microsoft.Windows.CsWinRT) включает компилятор C#/WinRT (cswinrt.exe), с помощью которого можно обрабатывать файлы WinMD и создавать код C# для .NET. C#/WinRT на основе этих файлов компилирует сборку взаимодействия, аналогично тому, как C++/WinRT создает заголовки для проекции языка C++. Затем вы можете распространить сборку взаимодействия C#/WinRT вместе со сборкой реализации для создания ссылок на приложения .NET, обычно в виде пакета NuGet.

Дополнительные сведения о создании и распространении сборки взаимодействия см. в статье Создание проекции C# из компонента C++/WinRT и ее распространение в формате NuGet для приложений .NET.

Ссылка на сборку взаимодействия

Как правило, на сборки взаимодействия C#/WinRT ссылаются проекты приложений. Однако на них также могут ссылаться промежуточные сборки взаимодействия. Например, сборка взаимодействия WinUI ссылается на сборку взаимодействия Windows SDK.

Если вы распространяете сторонний компонент WinRT без официальной сборки взаимодействия, для создания собственных частных источников проекции в проекте приложения можно выполнить процедуру создания сборки взаимодействия. Мы не рекомендуем использовать этот подход, так как он может привести к конфликтам проекций одного и того же типа в рамках одного процесса. Для предотвращения таких ситуаций используются пакеты NuGet, созданные по схеме семантического версионирования. Предпочтительно использовать официальную сборку взаимодействия стороннего производителя.

Поддержка внедрения для типов WinRT (предварительная версия)

Начиная с версии C#/WinRT 1.4.1, включена поддержка внедрения проекции Windows SDK и источников среды выполнения для .NET и .NET Standard 2.0 в библиотеку или выходные данные приложения. Это полезно в случаях, когда использование типов Windows SDK является автономным. Поддержка внедрения устраняет зависимости от WinRT.Runtime.dll и Microsoft.Windows.SDK.NET.dll, что сокращает размер библиотеки или выходных данных приложения. Это также позволяет разработчикам библиотек предоставлять поддержку предыдущих версий и исключать настройку для разных версий.

Дополнительные сведения см. в документации по встраиванию C#/WinRT в нашем репозитории.

Активация типа WinRT

C#/WinRT поддерживает активацию типов WinRT, размещенных в операционной системе, а также сторонних компонентов, например Win2D. Поддержка активации сторонних компонентов в классическом приложении включена с активацией бесплатной регистрации WinRT (см. статью "Повышение непакетированных классических приложений с помощью компонентов среда выполнения Windows"), доступной в Windows 10 версии 1903 и более поздних версий. Собственные компоненты C++ должны установить для свойства Windows Desktop Compatible значение True либо через свойства проекта, либо через файл .vcxproj, чтобы ссылаться на двоичные файлы Microsoft.VCLibs.Desktop и пересылать их потребляющим приложениям. В противном случае для использования приложений потребуется пакет VCRT Forwarders, если компонент предназначен только для приложений UWP.

C#/WinRT также предоставляет резервный путь активации, если Windows не удается активировать тип, как описано выше. В этом случае C#/WinRT пытается определить расположение собственной библиотеки DLL реализации на основе полного имени типа, постепенно удаляя элементы. Например, резервная логика попытается активировать тип Contoso.Controls.Widget из перечисленных ниже модулей в такой последовательности:

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

C#/WinRT использует для поиска библиотеки DLL реализации альтернативный порядок поиска LoadLibrary. Пакет приложения, в котором предусмотрено использование такого резервного способа, наряду с модулем приложения должен включать библиотеку DLL реализации.

Распространенные ошибки и устранение неполадок

  • Ошибка: "Метаданные Windows не предоставляются или не обнаружены".

    Метаданные Windows можно указать с помощью свойства проекта <CsWinRTWindowsMetadata>, например:

    <CsWinRTWindowsMetadata>10.0.19041.0</CsWinRTWindowsMetadata>
    

    В C#/WinRT 1.2.1 и более поздних версий это свойство имеет значение по умолчанию TargetPlatformVersion, унаследованное от номера версии Windows SDK в свойстве TargetFramework.

  • Ошибка CS0246: не удалось найти имя типа или пространства имен Windows (отсутствует директива using или ссылка на сборку?)

    Чтобы устранить эту ошибку, измените свойство <TargetFramework>, чтобы оно указывало на конкретную версию Windows, например:

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

    Дополнительные сведения об указании свойства <TargetFramework> см. в документации по вызову API-интерфейсов среды выполнения Windows.

  • System.InvalidCastException при приведении к интерфейсу с атрибутом ComImport

    При приведении объекта к интерфейсу с атрибутом ComImport вам нужно будет использовать оператор .As<> вместо явного выражения приведения. Например:

    someObject.As<SomeComImportInterface>
    

    Дополнительные сведения см. в руководстве по COM-взаимодействию.

  • System.Runtime.InteropServices.COMException: Class not registered (0x80040154 (REGDB_E_CLASSNOTREG))

    • Если вы видите это исключение при использовании проекции C#/WinRT из компонента C++/WinRT, убедитесь, что компонент установил для свойства Windows Desktop Compatible значение True либо через свойства проекта, либо через файл .vcxproj.

Ошибки управления версиями пакета SDK для .NET

В проекте, созданном с использованием более ранней версии пакета SDK для .NET, чем у любой из его зависимостей, могут возникать следующие ошибки или предупреждения.

Сообщение об ошибке или предупреждающее сообщение Причина
Предупреждение MSB3277. Обнаружены конфликты между различными версиями WinRT.Runtime или Microsoft.Windows.SDK.NET, которые не удалось устранить. Это предупреждение сборки возникает при ссылке на библиотеку, которая предоставляет типы Windows SDK на своей поверхности API.
Ошибка CS1705: сборка "AssemblyName1" использует typeName, которая имеет более высокую версию, чем ссылка на сборку AssemblyName2. Эта ошибка компилятора сборки возникает при указании и использовании типов Windows SDK, представленных в библиотеке.
System.IO.FileLoadException Эта ошибка среды выполнения может возникнуть при вызове определенных API в библиотеке, которая не предоставляет типы Windows SDK.

Чтобы исправить эти ошибки, обновите пакет SDK для .NET до последней версии. Это обеспечит совместимость версий сборок среды выполнения и Windows SDK, используемых вашим приложением, со всеми зависимостями. Эти ошибки могут возникать при ранних обновлениях, связанных с обслуживанием, или обновлениях компонентов, в пакете SDK для .NET, так как исправления среды выполнения могут потребовать обновления нашей версии сборки.

Известные проблемы

Известные проблемы и критические изменения указаны в репозитории C#/WinRT в GitHub.

Если у вас возникли какие-либо функциональные проблемы с пакетом NuGet программы C#/WinRT, компилятором cswinrt.exe или созданными источниками проекции, сообщите нам о них на странице проблем с C#/WinRT.

Дополнительные ресурсы