Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
I det här avsnittet går vi igenom hur du använder C#/WinRT- för att generera en C# .NET-projektion (eller interop)-sammansättning från en C++/WinRT Windows Runtime-komponent och distribuera den som ett NuGet-paket för .NET-program.
I .NET 6 och senare stöds inte längre förbrukning av WinMD-filer (Windows-metadata) (se inbyggt stöd för WinRT tas bort från .NET). I stället kan C#/WinRT-verktyget användas för att generera en projektionssammansättning för alla WinMD-filer, vilket sedan möjliggör förbrukning av WinRT-komponenter från .NET-program. En projektionssammansättning kallas även för en interop-sammansättning. Den här genomgången visar hur du gör följande:
- Använd C#/WinRT-paketet för att generera en C#-projektion från en C++/WinRT-komponent.
 - Distribuera komponenten, tillsammans med projektionssammansättningen, som ett NuGet-paket.
 - Använd NuGet-paketet från ett .NET-konsolprogram.
 
Förutsättningar
Den här genomgången och motsvarande exempel kräver följande verktyg och komponenter:
- Visual Studio 2022 (eller Visual Studio 2019) med arbetsbelastning för utveckling av Universal Windows Platform installerad. I Installationsinformation>Universal Windows Platform-utvecklingkontrollerar du alternativet C++ (v14x) Universal Windows Platform-verktyg.
 - .NET 6.0 SDK eller senare.
 
Endast Visual Studio 2019. C++/WinRT VSIX-tillägget, som ger dig C++/WinRT-projektmallar i Visual Studio. Projektmallarna är inbyggda i Visual Studio 2022.
Vi kommer att använda Visual Studio 2022 och .NET 6 i den här genomgången.
Viktigt!
Du måste också ladda ned eller klona exempelkoden för det här avsnittet från C#/WinRT-projektionsexempel på GitHub. Besök CsWinRToch klicka på den gröna koden för att få URL:en för git clone. Läs filen README.md för exemplet.
Skapa en enkel C++/WinRT Windows Runtime-komponent
Om du vill följa den här genomgången måste du först ha en C++/WinRT Windows Runtime-komponent (WRC) från vilken du vill generera C#-projektionssammansättningen.
Den här genomgången använder SimpleMathComponent WRC från C#/WinRT-projektionsexemplet på GitHub, som du redan har laddat ned eller klonat. SimpleMathComponent skapades från Windows Runtime Component (C++/WinRT) Visual Studio-projektmall (som medföljer Visual Studio 2022 eller med C++/WinRT VSIX-tillägg).
Öppna projektet SimpleMathComponent i Visual Studio genom att öppna filen \CsWinRT\src\Samples\NetProjectionSample\CppWinRTComponentProjectionSample.sln som du hittar i nedladdningen eller klonen av lagringsplatsen.
Koden i det här projektet innehåller funktioner för de grundläggande matematiska åtgärder som visas i rubrikfilen nedan.
// 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);
    };
}
Du kan bekräfta att egenskapen Windows Desktop Compatible är inställd på Ja för komponentprojektet SimpleMathComponent C++/WinRT Windows Runtime. Det gör du genom att i projektegenskaperna för SimpleMathComponent, under Configuration Properties>General>Project Defaultsanger du egenskapen Windows Desktop Compatible till Ja. Det säkerställer att rätt runtime-binärfiler läses in för användning av .NET-skrivbordsappar.
              
              
            
Mer detaljerade steg om hur du skapar en C++/WinRT-komponent och genererar en WinMD-fil finns i Windows Runtime-komponenter med C++/WinRT-.
Anmärkning
Om du implementerar IInspectable::GetRuntimeClassName i komponenten måste den returnera ett giltigt WinRT-klassnamn. Eftersom C#/WinRT använder klassnamnsträngen för interop, kommer ett felaktigt körningsklassnamn att orsaka en InvalidCastException.
Lägga till ett projektionsprojekt i komponentlösningen
Först, med CppWinRTComponentProjectionSample-lösningen fortfarande öppen i Visual Studio, tar du bort SimpleMathProjection-projektet från lösningen. Ta sedan bort mappen SimpleMathProjection från filsystemet (eller byt namn på den om du vill). Dessa steg är nödvändiga så att du kan följa den här genomgången steg för steg.
Lägg till ett nytt C#-biblioteksprojekt i din lösning.
- I Solution Explorerhögerklickar du på lösningsnoden och klickar på Lägg till>Nytt projekt.
 - I dialogrutan Lägg till ett nytt projekt skriver du klassbibliotek i sökrutan. Välj C# i språklistan och välj sedan Windows i plattformslistan. Välj C#-projektmallen som heter helt enkelt klassbiblioteket (utan prefix eller suffix) och klicka på Nästa.
 - Ge det nya projektet namnet SimpleMathProjection. Platsen bör redan vara inställd på samma 
\CsWinRT\src\Samples\NetProjectionSamplemapp som mappen SimpleMathComponent finns i. men bekräfta det. Klicka sedan på Nästa. - På sidan Ytterligare information väljer du .NET 6.0 (långsiktigt stöd)och väljer sedan Skapa.
 
Ta bort stub-filen Class1.cs från projektet.
Använd stegen nedan för att installera C#/WinRT NuGet-paketet.
- I Solution Explorerhögerklickar du på projektet SimpleMathProjection och väljer Hantera NuGet-paket.
 - På fliken Bläddra skriver eller klistrar du in Microsoft.Windows.CsWinRT i sökrutan, i sökresultatet väljer du objektet med den senaste versionen och klickar sedan på Installera för att installera paketet i SimpleMathProjection-projektet.
 
Lägg till i SimpleMathProjection en projektreferens till projektet SimpleMathComponent. I Solution Explorerhögerklickar du på noden Beroenden under projektnoden SimpleMathProjection, väljer Lägg till projektreferensoch väljer SimpleMathComponent projekt >OK.
Försök inte att skapa projektet än. Vi kommer att göra det i ett senare steg.
Hittills bör Solution Explorer- se ut ungefär så här (versionsnumren skiljer sig åt).
              
              
            
Bygg projekt utanför källan
För CppWinRTComponentProjectionSample lösning i C#/WinRT-projektionsexempel (som du laddade ned eller klonade från GitHub och nu har öppnat) konfigureras byggutdataplatsen med Directory.Build.props-filen för att skapa av källan. Det innebär att filer från kompileringsutdata genereras utanför källmappen. Vi rekommenderar att du skapar från källan när du använder C#/WinRT-verktyget. Det förhindrar att C#-kompilatorn oavsiktligt plockar upp alla *.cs filer under projektrotkatalogen, vilket kan orsaka duplicerade typfel (till exempel vid kompilering för flera konfigurationer och/eller plattformar).
Även om detta redan har konfigurerats för CppWinRTComponentProjectionSample lösning följer du stegen nedan för att få öva på att göra konfigurationen själv.
Så här konfigurerar du din lösning för att bygga ut från källan:
Med CppWinRTComponentProjectionSample lösning fortfarande öppen högerklickar du på lösningsnoden och väljer Lägg till>nytt objekt. Välj XML-fil objekt och ge det namnet Directory.Build.props (utan ett
.xmltillägg). Klicka på Ja för att skriva över den befintliga filen.Ersätt innehållet i Directory.Build.props med konfigurationen nedan.
<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>Spara och stäng filen Directory.Build.props.
Redigera projektfilen för att köra C#/WinRT
Innan du kan anropa verktyget cswinrt.exe för att generera projektionssammansättningen måste du först redigera projektfilen för att ange några projektegenskaper.
I Solution Explorerdubbelklickar du på noden SimpleMathProjection för att öppna projektfilen i redigeraren.
Uppdatera
TargetFramework-elementet för att rikta in dig på en specifik Windows SDK-version. Detta lägger till sammansättningsberoenden som krävs för stöd för interop och projektion. Det här exemplet är avsett för Windows SDK-versionen net6.0-windows10.0.19041.0 (även kallat Windows 10, version 2004). AngePlatform-elementet till AnyCPU- så att den resulterande projektionssammansättningen kan refereras från valfri apparkitektur. Om du vill tillåta att refererande program stöder tidigare Windows SDK-versioner kan du också ange egenskapenTargetPlatformMinimumVersion.<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>Anmärkning
För den här genomgången och den relaterade exempelkoden skapas lösningen för x64 och Release. Observera att SimpleMathProjection-projektet är konfigurerat för att bygga för AnyCPU för alla lösningsarkitekturkonfigurationer.
Lägg till ett andra
PropertyGroupelement (omedelbart efter det första) som anger flera C#/WinRT-egenskaper.<PropertyGroup> <CsWinRTIncludes>SimpleMathComponent</CsWinRTIncludes> <CsWinRTGeneratedFilesDir>$(OutDir)</CsWinRTGeneratedFilesDir> </PropertyGroup>Här följer lite information om inställningarna i det här exemplet:
- Egenskapen 
CsWinRTIncludesanger vilka namnområden som ska projiceras. - Egenskapen 
CsWinRTGeneratedFilesDiranger utdatakatalogen där projektionskällfilerna genereras. Den här egenskapen är inställd påOutDir, som definieras i Directory.Build.props från avsnittet ovan. 
- Egenskapen 
 Spara och stäng filen SimpleMathProjection.csproj och klicka för att Läs in projekt om det behövs.
Skapa ett NuGet-paket med projektionen
Om du vill distribuera projektionssammansättningen för .NET-programutvecklare kan du automatiskt skapa ett NuGet-paket när du skapar lösningen genom att lägga till ytterligare projektegenskaper. För .NET-mål måste NuGet-paketet innehålla projektionssammansättningen och implementeringssammansättningen från komponenten.
Följ stegen nedan om du vill lägga till en NuGet-specifikationsfil (
.nuspec) i SimpleMathProjection--projektet.- I Solution Explorerhögerklickar du på noden SimpleMathProjection, väljer Lägg till>ny mappoch ger mappen namnet nuget.
 - Högerklicka på mappen nuget, välj Lägg till>nytt objekt, välj XML-filoch ge den namnet SimpleMathProjection.nuspec.
 
I Solution Explorerdubbelklickar du på noden SimpleMathProjection för att öppna projektfilen i redigeraren. Lägg till följande egenskapsgrupp i den nu öppna SimpleMathProjection.csproj (omedelbart efter de två befintliga
PropertyGroupelementen) för att automatiskt generera paketet. Dessa egenskaper angerNuspecFileoch katalogen som ska generera NuGet-paketet.<PropertyGroup> <GeneratedNugetDir>.\nuget\</GeneratedNugetDir> <NuspecFile>$(GeneratedNugetDir)SimpleMathProjection.nuspec</NuspecFile> <OutputPath>$(GeneratedNugetDir)</OutputPath> <GeneratePackageOnBuild>true</GeneratePackageOnBuild> </PropertyGroup>Anmärkning
Om du föredrar att generera ett paket separat kan du också välja att köra verktyget
nuget.exefrån kommandoraden. Mer information om hur du skapar ett NuGet-paket finns i Skapa ett paket med hjälp av nuget.exe CLI-.Öppna filen SimpleMathProjection.nuspec för att redigera egenskaperna för att skapa paketet och klistra in följande kod. Kodfragmentet nedan är ett exempel på NuGet-specifikation för att distribuera SimpleMathComponent till flera målramverk. Observera att projekteringsmonteringen SimpleMathProjection.dllspecificeras istället för SimpleMathComponent.winmd för målet
lib\net6.0-windows10.0.19041.0\SimpleMathProjection.dll. Det här beteendet är nytt i .NET 6 och senare och aktiveras av C#/WinRT. Implementeringssammansättningen,SimpleMathComponent.dll, måste också distribueras och läses in vid körning.<?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>Anmärkning
SimpleMathComponent.dllär implementeringssammansättningen för komponenten arkitekturspecifik. Om du stöder andra plattformar (till exempel x86 eller Arm64) måste du först skapa SimpleMathComponent- för önskade plattformar och lägga till dessa sammansättningsfiler i lämplig RID-relativ mapp. Projektionssammansättningen SimpleMathProjection.dll och komponenten SimpleMathComponent.winmd är båda arkitekturneutrala.
Spara och stäng filerna som du nyss redigerade.
Skapa lösningen för att generera projektionen och NuGet-paketet
Innan du skapar lösningen kontrollerar du inställningarna för Configuration Manager i Visual Studio under Build>Configuration Manager. I den här genomgången anger du Configuration till Release och Platform till x64- för lösningen.
Nu kan du skapa lösningen. Högerklicka på lösningsnoden och välj Build Solution. Detta skapar först projektet SimpleMathComponent och sedan projektet SimpleMathProjection. Komponenten WinMD och implementeringssammansättningen (SimpleMathComponent.winmd och SimpleMathComponent.dll), projektionskällans filer och projektionssammansättningen (SimpleMathProjection.dll), genereras alla under katalogen _build utdata. Du kan också se det genererade NuGet-paketet SimpleMathComponent0.1.0-prerelease.nupkgunder mappen \SimpleMathProjection\nuget.
Viktigt!
Om någon av filerna som nämns ovan inte genereras skapar du lösningen en andra gång. Du kan också behöva stänga och öppna lösningen igen innan du återskapar den.
Du kan behöva stänga och öppna lösningen igen för att .nupkg ska visas i Visual Studio enligt bilden (eller bara välja och avmarkera Visa alla filer).
              
              
            
Referera till NuGet-paketet i ett C# .NET 6-konsolprogram
Om du vill använda SimpleMathComponent- från ett .NET-projekt kan du helt enkelt lägga till en referens till det SimpleMathComponent0.1.0-prerelease.nupkg NuGet-paketet som vi skapade i föregående avsnitt. Följande steg visar hur du gör det genom att skapa en enkel konsolapp i en separat lösning.
Använd stegen nedan för att skapa en ny lösning som innehåller ett C# Console App-projekt (om du skapar projektet i en ny lösning kan du återställa SimpleMathComponent- NuGet-paketet separat).
Viktigt!
Vi kommer att skapa det nya Console App-projektet i mappen
\CsWinRT\src\Samples\NetProjectionSample, som du hittar i det nedladdade eller klonade exemplet på C#/WinRT-projektion.- I en ny instans av Visual Studio väljer du File>New>Project.
 - I dialogrutan Skapa ett nytt projekt söker du efter projektmallen Console App. Välj C#-projektmallen som bara heter Console App (utan prefix eller suffix) och klicka på Nästa. Om du använder Visual Studio 2019 är projektmallen Konsolprogram.
 - Ge det nya projektet namnet SampleConsoleApp, ange platsen till samma 
\CsWinRT\src\Samples\NetProjectionSamplemapp som mapparna SimpleMathComponent och SimpleMathProjection ligger i, och klicka på Nästa. - På sidan Ytterligare information väljer du .NET 6.0 (långsiktigt stöd)och väljer sedan Skapa.
 
I Solution Explorerdubbelklickar du på noden SampleConsoleApp för att öppna SampleConsoleApp.csproj-projektfilen och redigera egenskaperna
TargetFrameworkochPlatformså att de ser ut som i följande lista. Lägg till elementetPlatformom det inte finns där.<PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net6.0-windows10.0.19041.0</TargetFramework> <Platform>x64</Platform> </PropertyGroup>Med SampleConsoleApp.csproj projektfilen fortfarande öppen, lägger vi nästa till i SampleConsoleApp projektet en referens till SimpleMathComponent NuGet-paketet. Om du vill återställa SimpleMathComponent NuGet när du skapar projektet kan du använda egenskapen
RestoreSourcesmed sökvägen till mappen nuget i komponentlösningen. Kopiera följande konfiguration och klistra in den i SampleConsoleApp.csproj (inuti elementetProject).<PropertyGroup> <RestoreSources> https://api.nuget.org/v3/index.json; ../SimpleMathProjection/nuget </RestoreSources> </PropertyGroup> <ItemGroup> <PackageReference Include="SimpleMathComponent" Version="0.1.0-prerelease" /> </ItemGroup>Viktigt!
Den
RestoreSourcessökvägen för paketet SimpleMathComponent som visas ovan är inställd på../SimpleMathProjection/nuget. Den sökvägen är korrekt förutsatt att du har följt stegen i den här genomgången, så att SimpleMathComponent- och SampleConsoleApp projekt båda finns i samma mapp (mappenNetProjectionSamplei det här fallet). Om du har gjort något annorlunda, måste du justera sökvägen därefter. Du kan också lägga till ett lokalt NuGet-paketflöde till din lösning.Redigera Program.cs-filen för att använda funktionerna som tillhandahålls av SimpleMathComponent.
var x = new SimpleMathComponent.SimpleMath(); Console.WriteLine("Adding 5.5 + 6.5 ..."); Console.WriteLine(x.add(5.5, 6.5).ToString());Spara och stäng de filer som du precis redigerade och skapa och kör konsolappen. Du ska kunna se resultatet nedan.
              
            
Kända problemområden
- När du skapar projektionsprojekt kan du se ett fel som: Fel MSB3271 Det uppstod ett matchningsfel mellan processorarkitekturen för projektet som skapades "MSIL" och processorarkitekturen x86 för implementeringsfilen "..\SimpleMathComponent.dll" för ".. \SimpleMathComponent.winmd". Det här matchningsfelet kan orsaka körningsfel. Överväg att ändra projektets målarkitektur för processorn via Configuration Manager för att justera processorarkitekturerna mellan projektet och implementeringsfilen, eller välj en winmd-fil med en implementeringsfil som har en processorarkitektur som matchar projektets målprocessorarkitektur. Du kan undvika det här felet genom att lägga till följande egenskap i C#-biblioteksprojektfilen: 
<PropertyGroup> <!-- Workaround for MSB3271 error on processor architecture mismatch --> <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch> </PropertyGroup> 
Ytterligare överväganden
Den C#-projektion (eller interop)-sammansättning som vi visade hur du skapar i det här avsnittet är ganska enkel – den har inte beroenden för andra komponenter. Men för att generera en C#-projektion för en C++/WinRT-komponent som har referenser till Windows App SDK-typer måste du i projektionsprojekt lägga till en referens till Windows App SDK NuGet-paketet. Om sådana referenser saknas visas fel som "Type <T> could not found" (Typ <T> kunde inte hittas).
En annan sak som vi gör i det här avsnittet är att distribuera projektionen som ett NuGet-paket. Den är för närvarande nödvändig.
Resurser
Windows developer