Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этом разделе мы рассмотрим использование C#/WinRT для генерации .NET сборки проекции C# (или межоперационного взаимодействия) из компонента C++/WinRT среда выполнения Windows и распространение ее в виде пакета NuGet для .NET приложений.
В .NET 6 и более поздних версий потребление файлов метаданных Windows (WinMD) больше не поддерживается (см. Встроенная поддержка WinRT удаляется из .NET). Вместо этого средство C#/WinRT можно использовать для создания сборки проекции для любого файла WinMD, который затем позволяет использовать компоненты WinRT из .NET приложений. Узел проекции также называется узлом взаимодействия. В этом пошаговом руководстве показано, как выполнить следующие действия.
- Используйте пакет C#/WinRT для создания проекции C# из компонента C++/WinRT.
- Распространите компонент вместе с сборкой проекции как пакет NuGet.
- Используйте пакет NuGet из консольного приложения .NET.
Предпосылки
В этом пошаговом руководстве и соответствующем примере требуются следующие средства и компоненты:
- Visual Studio 2022 или более поздней версии с установленной рабочей нагрузкой разработки универсальная платформа Windows. В Installation Details>универсальная платформа Windows development проверьте средства C++ (v14x) для универсальная платформа Windows.
- .NET пакет SDK 8.0 (LTS) или более поздней версии.
Мы будем использовать Visual Studio 2022 или более поздней версии и .NET 8 в этом пошаговом руководстве.
Это важно
Кроме того, необходимо скачать или клонировать пример кода для этого раздела из примера проекции C#/WinRT на GitHub. Перейдите CsWinRTи нажмите зеленую кнопку code, чтобы получить URL-адрес git clone. Обязательно прочитайте файл README.md для примера.
Создание простого компонента C++/WinRT среда выполнения Windows
Для выполнения этого пошагового руководства необходимо сначала создать компонент C++/WinRT среда выполнения Windows (WRC), из которого необходимо создать сборку проекции C#.
В этом пошаговом руководстве используется SimpleMathComponent WRC из примера проекции C#/WinRT на GitHub, который вы уже скачали или клонировали. SimpleMathComponent был создан из шаблона проекта среда выполнения Windows (C++/WinRT) Visual Studio.
Чтобы открыть проект SimpleMathComponent в Visual Studio, откройте файл \CsWinRT\src\Samples\NetProjectionSample\CppWinRTComponentProjectionSample.sln, который вы найдете в скачивании или клоне репозитория.
Код в этом проекте предоставляет функциональные возможности для основных математических операций, показанных в файле заголовка ниже.
// SimpleMath.h
...
namespace winrt::SimpleMathComponent::implementation
{
struct SimpleMath: SimpleMathT<SimpleMath>
{
SimpleMath() = default;
double add(double firstNumber, double secondNumber);
double subtract(double firstNumber, double secondNumber);
double multiply(double firstNumber, double secondNumber);
double divide(double firstNumber, double secondNumber);
};
}
Можно подтвердить, что для свойства Windows Desktop Compatible задано значение Yes для проекта компонента SimpleMathComponent C++/WinRT среда выполнения Windows. Для этого в свойствах project для SimpleMathComponent, в разделе Configuration Properties>General>Project Defaults, Задайте для свойства Windows Desktop Compatible значение Yes. Это гарантирует, что правильные библиотеки среды выполнения загружаются для использования .NET настольными приложениями.
Для получения более подробной информации о создании компонента C++/WinRT и генерации файла WinMD см. в разделе компоненты среда выполнения Windows с использованием C++/WinRT.
Замечание
Если вы реализуете IInspectable::GetRuntimeClassName в компоненте, должен вернуть допустимое имя класса WinRT. Так как C#/WinRT использует строку имени класса для взаимодействия, неправильное имя класса среды выполнения вызовет InvalidCastException.
Добавьте проект проекции в решение компонента
Сначала, когда решение CppWinRTComponentProjectionSample все еще открыто в Visual Studio, удалите проект SimpleMathProjection из данного решения. Затем удалите из файловой системы папку SimpleMathProjection (или переименуйте ее, если вы предпочитаете). Эти действия необходимы, чтобы вы могли следовать этому пошаговому руководству.
Добавьте в решение новый проект библиотеки C#.
- В Обозреватель решений щелкните правой кнопкой мыши узел решения и щелкните Add>New Project.
- В диалоговом окне Добавление нового проекта в поле поиска введите Библиотеку классов. Выберите C# в списке языков, а затем выберите Windows из списка платформ. Выберите шаблон проекта C#, который просто называется Библиотека классов (без префиксов и суффиксов), и нажмите Далее.
- Назовите новый проект SimpleMathProjection. Расположение должно быть уже задано в той же
\CsWinRT\src\Samples\NetProjectionSampleпапке, в которой находится папка SimpleMathComponent. Пожалуйста, подтвердите это. Затем нажмите Далее. - На странице Additional information выберите .NET 8.0 (долгосрочная поддержка) и выберите Create.
Удалите файл-заглушку Class1.cs из проекта.
Чтобы установить пакет C#/WinRT NuGet, выполните следующие действия.
- В Обозреватель решений щелкните правой кнопкой мыши на проекте SimpleMathProjection и выберите Управление пакетами NuGet.
- На вкладке Browse введите или вставьте Майкрософт.Windows. CsWinRT в поле поиска выберите элемент с последней версией, а затем щелкните Install, чтобы установить пакет в проект SimpleMathProjection.
Добавьте в проект SimpleMathProjection ссылку на проект SimpleMathComponent. В Обозреватель решений щелкните правой кнопкой мыши узел Dependencies в узле SimpleMathProjection project, Выберите Add Project Reference и выберите SimpleMathComponent project >OK.
Пока не пытайтесь создать проект. Мы будем делать это позже.
На данный момент Обозреватель решений должен выглядеть примерно так (номера версий будут отличаться).
Сборка проектов из исходного кода
Для решения CppWinRTComponentProjectionSample в примере проекции C#/WinRT (который вы скачали или клонировали из GitHub, и теперь он открыт), местоположение выходных данных сборки настроено с помощью файла Directory.Build.props для сборки вне исходного каталога. Это означает, что файлы из выходных данных сборки создаются за пределами исходной папки. Рекомендуем компилировать из исходного кода при использовании инструмента C#/WinRT. Это предотвращает непреднамеренное получение всех *.cs файлов в корневом каталоге проекта, что может привести к ошибкам повторяющегося типа (например, при компиляции для нескольких конфигураций и платформ).
Несмотря на то что это уже настроено для решения CppWinRTComponentProjectionSample, выполните приведенные ниже действия, чтобы попрактиковаться в настройке самостоятельно.
Чтобы настроить решение для сборки из источника, выполните следующие действия.
Убедитесь, что решение CppWinRTComponentProjectionSample остается открытым, щелкните правой кнопкой мыши на узле решения и выберите Добавить>Новый элемент. Выберите элемент XML-файла и назовите его Directory.Build.props (без
.xmlрасширения). Нажмите кнопку "Да" , чтобы перезаписать существующий файл.Замените содержимое Directory.Build.props конфигурацией ниже.
<Project> <PropertyGroup> <BuildOutDir>$([MSBuild]::NormalizeDirectory('$(SolutionDir)', '_build', '$(Platform)', '$(Configuration)'))</BuildOutDir> <OutDir>$([MSBuild]::NormalizeDirectory('$(BuildOutDir)', '$(MSBuildProjectName)', 'bin'))</OutDir> <IntDir>$([MSBuild]::NormalizeDirectory('$(BuildOutDir)', '$(MSBuildProjectName)', 'obj'))</IntDir> </PropertyGroup> </Project>Сохраните и закройте файл Directory.Build.props .
Изменение файла проекта для выполнения C#/WinRT
Прежде чем вызвать cswinrt.exe средство для создания сборки проекции, необходимо сначала изменить файл проекта, чтобы указать несколько свойств проекта.
В Обозреватель решений дважды щелкните узел SimpleMathProjection, чтобы открыть файл проекта в редакторе.
Обновите элемент
TargetFrameworkдля использования с конкретной версией Windows SDK. Это добавляет зависимости сборки, которые необходимы для поддержки интероперабельности и проекции. Этот пример предназначен для пакета SDK Windows версии net6.0-windows10.0.0.19041.0 (также известный как Windows 10 версии 2004). Укажите для элементаPlatform, чтобы результирующую проекционную сборку можно использовать для любой архитектуры приложения. Чтобы разрешить ссылки на приложения для поддержки более ранних версий пакета SDK Windows, можно также задать свойствоTargetPlatformMinimumVersion.<PropertyGroup> <TargetFramework>net8.0-windows10.0.19041.0</TargetFramework> <!-- Set Platform to AnyCPU to allow consumption of the projection assembly from any architecture. --> <Platform>AnyCPU</Platform> </PropertyGroup>Замечание
В этом пошаговом руководстве и соответствующем примере кода решение создается для x64 и Release. Обратите внимание, что проект SimpleMathProjection настроен для сборки под AnyCPU для всех конфигураций архитектуры решения.
Добавьте второй
PropertyGroupэлемент (сразу после первого), который задает несколько свойств C#/WinRT.<PropertyGroup> <CsWinRTIncludes>SimpleMathComponent</CsWinRTIncludes> <CsWinRTGeneratedFilesDir>$(OutDir)</CsWinRTGeneratedFilesDir> </PropertyGroup>Ниже приведены некоторые сведения о параметрах в этом примере:
- Свойство
CsWinRTIncludesуказывает, какие пространства имен необходимо проецировать. - Свойство
CsWinRTGeneratedFilesDirзадает выходной каталог, в котором создаются исходные файлы проекции. Это свойство имеет значениеOutDir, определенное в Directory.Build.props из приведенного выше раздела.
- Свойство
Сохраните и закройте файл SimpleMathProjection.csproj и щелкните, чтобы перезагрузить проекты при необходимости.
Создание пакета NuGet с проекцией
Чтобы распространить сборку проекции для разработчиков приложений .NET, можно автоматически создать пакет NuGet при создании решения, добавив дополнительные свойства проекта. Для целевых объектов .NET пакет NuGet должен включать сборку проекции и сборку реализации из компонента.
Чтобы добавить файл спецификации NuGet (
.nuspec) в проект SimpleMathProjection , выполните приведенные ниже действия.- В Обозреватель решений щелкните правой кнопкой мыши узел SimpleMathProjection, выберите Add>New Folder и назовите папку nuget.
- Щелкните правой кнопкой мыши папку nuget, выберите Добавить>Новый элемент, выберите XML-файли назовите его SimpleMathProjection.nuspec.
В Обозреватель решений дважды щелкните узел SimpleMathProjection, чтобы открыть файл проекта в редакторе. Добавьте следующую группу свойств в открытый файл SimpleMathProjection.csproj (сразу после двух существующих
PropertyGroupэлементов), чтобы автоматически создать пакет. Эти свойства указываютNuspecFileи каталог для создания пакета NuGet.<PropertyGroup> <GeneratedNugetDir>.\nuget\</GeneratedNugetDir> <NuspecFile>$(GeneratedNugetDir)SimpleMathProjection.nuspec</NuspecFile> <OutputPath>$(GeneratedNugetDir)</OutputPath> <GeneratePackageOnBuild>true</GeneratePackageOnBuild> </PropertyGroup>Замечание
Если вы предпочитаете создавать пакет отдельно, можно также запустить
nuget.exeсредство из командной строки. Дополнительные сведения о создании пакета NuGet см. в статье "Создание пакета с помощью интерфейса командной строки nuget.exe".Откройте файл SimpleMathProjection.nuspec , чтобы изменить свойства создания пакета и вставьте следующий код. Приведенный ниже фрагмент кода является примером спецификации NuGet для распространения SimpleMathComponent на несколько целевых платформ. Обратите внимание, что сборка проекции, SimpleMathProjection.dll, предусмотрена вместо SimpleMathComponent.winmd для целевого
lib\net6.0-windows10.0.19041.0\SimpleMathProjection.dll. Это новое поведение в .NET 6 и более поздних версиях, активируемое с помощью C#/WinRT. Сборка реализации,SimpleMathComponent.dll, должна быть также распространена и загружена в процессе выполнения.<?xml version="1.0" encoding="utf-8"?> <package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd"> <metadata> <id>SimpleMathComponent</id> <version>0.1.0-prerelease</version> <authors>Contoso Math Inc.</authors> <description>A simple component with basic math operations</description> <dependencies> <group targetFramework="net6.0-windows10.0.19041.0" /> <group targetFramework=".NETCoreApp3.0" /> <group targetFramework="UAP10.0" /> <group targetFramework=".NETFramework4.6" /> </dependencies> </metadata> <files> <!--Support .NET 6, .NET Core 3, UAP, .NET Framework 4.6, C++ --> <!--Architecture-neutral assemblies--> <file src="..\..\_build\AnyCPU\Release\SimpleMathProjection\bin\SimpleMathProjection.dll" target="lib\net6.0-windows10.0.19041.0\SimpleMathProjection.dll" /> <file src="..\..\_build\x64\Release\SimpleMathComponent\bin\SimpleMathComponent\SimpleMathComponent.winmd" target="lib\netcoreapp3.0\SimpleMathComponent.winmd" /> <file src="..\..\_build\x64\Release\SimpleMathComponent\bin\SimpleMathComponent\SimpleMathComponent.winmd" target="lib\uap10.0\SimpleMathComponent.winmd" /> <file src="..\..\_build\x64\Release\SimpleMathComponent\bin\SimpleMathComponent\SimpleMathComponent.winmd" target="lib\net46\SimpleMathComponent.winmd" /> <!--Architecture-specific implementation DLLs should be copied into RID-relative folders--> <file src="..\..\_build\x64\Release\SimpleMathComponent\bin\SimpleMathComponent\SimpleMathComponent.dll" target="runtimes\win10-x64\native\SimpleMathComponent.dll" /> <!--To support x86 and Arm64, build SimpleMathComponent for those other architectures and uncomment the entries below.--> <!--<file src="..\..\_build\Win32\Release\SimpleMathComponent\bin\SimpleMathComponent\SimpleMathComponent.dll" target="runtimes\win10-x86\native\SimpleMathComponent.dll" />--> <!--<file src="..\..\_build\arm64\Release\SimpleMathComponent\bin\SimpleMathComponent\SimpleMathComponent.dll" target="runtimes\win10-arm64\native\SimpleMathComponent.dll" />--> </files> </package>Замечание
SimpleMathComponent.dll, сборка реализации компонента зависит от архитектуры. Если вы поддерживаете другие платформы (например, x86 или Arm64), сначала необходимо создать SimpleMathComponent для нужных платформ и добавить эти файлы сборок в соответствующую папку , связанную с RID. Сборка проекции SimpleMathProjection.dll и компонент SimpleMathComponent.winmd являются нейтральными по архитектуре.
Сохраните и закройте только что измененные файлы.
Создание решения для создания проекции и пакета NuGet
Перед созданием решения обязательно проверьте параметры Configuration Manager в Visual Studio в разделе >Configuration Manager. В этом пошаговом руководстве задайте для Configuration значение Release и для Platform значение x64 для решения.
На этом этапе можно создать решение. Щелкните правой кнопкой мыши на узле в дереве решений и выберите Сборка решения. Сначала будет построен проект SimpleMathComponent , а затем проект SimpleMathProjection . Сборка компонента WinMD и реализация (SimpleMathComponent.winmd и SimpleMathComponent.dll), исходные файлы проекции и сборка проекции (SimpleMathProjection.dll), будут созданы в каталоге выходных данных _build. Вы также сможете просмотреть созданный пакет NuGet SimpleMathComponent0.1.0-prerelease.nupkg в папке \SimpleMathProjection\nuget .
Это важно
Если указанные выше файлы не создаются, создайте решение во второй раз. Вам также может потребоваться закрыть и повторно открыть решение перед повторной сборкой.
Возможно, вам потребуется закрыть и повторно открыть решение, чтобы компонент .nupkg стал видимым в Visual Studio, как показано (или просто выберите и затем отмените выбор Показать все файлы).
Ссылка на пакет NuGet в консольном приложении C# .NET 6
Чтобы использовать SimpleMathComponent из проекта .NET, Вы можете просто добавить в новый проект .NET ссылку на пакет NuGet SimpleMathComponent0.1.0-prerelease.nupkg пакет NuGet, созданный в предыдущем разделе. Ниже показано, как это сделать, создав простое консольное приложение в отдельном решении.
Выполните приведенные ниже действия, чтобы создать новое решение, содержащее проект консольного приложения C# (создание этого проекта в новом решении позволяет самостоятельно восстановить пакет SimpleMathComponent NuGet).
Это важно
Мы создадим этот проект консольного приложения
в папке , которую вы найдете в вашей скачанной или клонированной копии примера проекции C#/WinRT .- В новом экземпляре Visual Studio выберите File>New>Project.
- В диалоговом окне Создание нового проекта найдите шаблон проекта Консольное приложение. Выберите шаблон проекта C#, который называется просто Консольное приложение (без префиксов и суффиксов) и нажмите Далее. Если вы используете Visual Studio 2019, шаблон проекта Console Application.
- Назовите новый проект SampleConsoleApp, задайте его расположение в той же
\CsWinRT\src\Samples\NetProjectionSampleпапке, в которую находятся папки SimpleMathComponent и SimpleMathProjection , и нажмите кнопку "Далее". - На странице Additional information выберите .NET 8.0 (долгосрочная поддержка) и выберите Create.
В Обозреватель решений Дважды щелкните узел SampleConsoleApp, чтобы открыть файл проекта SampleConsoleApp.csproj и изменить свойства
TargetFrameworkиPlatform, чтобы они выглядели как показано в следующем списке. Добавьте элементPlatform, если его там нет.<PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net6.0-windows10.0.19041.0</TargetFramework> <Platform>x64</Platform> </PropertyGroup>С оставленным открытым файлом проекта SampleConsoleApp.csproj мы далее добавим в проект SampleConsoleApp ссылку на пакет NuGet SimpleMathComponent. Чтобы восстановить SimpleMathComponent NuGet при создании проекта, можно использовать свойство
RestoreSourcesс путем к папке nuget в решении компонента. Скопируйте следующую конфигурацию и вставьте ее в SampleConsoleApp.csproj (внутри элементаProject).<PropertyGroup> <RestoreSources> https://api.nuget.org/v3/index.json; ../SimpleMathProjection/nuget </RestoreSources> </PropertyGroup> <ItemGroup> <PackageReference Include="SimpleMathComponent" Version="0.1.0-prerelease" /> </ItemGroup>Это важно
Заданный путь для пакета
RestoreSources, показанного выше, имеет значение../SimpleMathProjection/nuget. Этот путь корректный, если вы следовали шагам, описанным в этом пошаговом руководстве, так что проекты SimpleMathComponent и SampleConsoleApp оба находятся в одной папке (NetProjectionSampleпапке в данном случае). Если вы сделали что-то другое, вам потребуется соответствующим образом настроить этот путь. Кроме того, вы можете добавить локальный источник пакетов NuGet в вашу проект.Измените файл Program.cs , чтобы использовать функциональные возможности, предоставляемые SimpleMathComponent.
var x = new SimpleMathComponent.SimpleMath(); Console.WriteLine("Adding 5.5 + 6.5 ..."); Console.WriteLine(x.add(5.5, 6.5).ToString());Сохраните и закройте файлы, которые вы только что редактировали, и создайте и запустите консольное приложение. Вы увидите приведенные ниже выходные данные.
Известные проблемы
- При создании проекта проекции может возникнуть ошибка: Error MSB3271 Существовало несоответствие между архитектурой процессора создаваемого проекта MSIL и архитектурой процессора x86 файла реализации ..\SimpleMathComponent.dll" для ".. \SimpleMathComponent.winmd". Это несоответствие может привести к сбоям среды выполнения. Попробуйте изменить целевую архитектуру процессора проекта с помощью Configuration Manager, чтобы выровнять архитектуры процессора между проектом и файлом реализации, или выбрать winmd-файл с файлом реализации с архитектурой процессора, которая соответствует целевой архитектуре процессора проекта. Чтобы обойти эту ошибку, добавьте следующее свойство в файл проекта библиотеки C#:
<PropertyGroup> <!-- Workaround for MSB3271 error on processor architecture mismatch --> <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch> </PropertyGroup>
Дополнительные рекомендации
Сборка проекции C# (или интероперабельности), которую мы показали, как создать в этом разделе, довольно простая — у нее нет зависимостей от других компонентов. Но чтобы создать проекцию C# для компонента C++/WinRT с ссылками на типы Windows App SDK, в проекте проекции необходимо добавить ссылку на пакет NuGet Windows App SDK. Если отсутствуют такие ссылки, вы увидите такие ошибки, как "Тип <T> не удалось найти".
Еще одна вещь, которую мы делаем в этом разделе, заключается в распространении проекции в виде пакета NuGet. Этот в настоящее время необходим.
Ресурсы
Windows developer