C#/WinRT Authoring Preview and Updates

Windows

Windows
The C#/WinRT team is excited to announce our
Please, Log in or Register to view URLs content!
, which includes a preview of C#/WinRT authoring with the latest
Please, Log in or Register to view URLs content!
, as well as updates to the
Please, Log in or Register to view URLs content!
with the
Please, Log in or Register to view URLs content!
. Since our
Please, Log in or Register to view URLs content!
on C#/WinRT v1.0, we have some new features to show off! The latest
Please, Log in or Register to view URLs content!
, which is version 1.1.2-prerelease.210208.6, includes a preview of C#/WinRT authoring. This allows component authors to create and package their own C# .NET 5 Windows Runtime components that can be consumed in native applications. In this blog post, we walkthrough the latest C#/WinRT authoring support. C#/WinRT has also made a few additions and bug-fixes to the runtime and Windows projections as part of the .NET 5.0 SDK February update. These updates to the SDK align with
Please, Log in or Register to view URLs content!
, which was released last month. We have added
Please, Log in or Register to view URLs content!
, which is a feature that provides platform compatibility assistance in Visual Studio for .NET 5 developers calling platform-specific APIs. To keep up to date with the latest updates on C#/WinRT, visit the
Please, Log in or Register to view URLs content!
and our
Please, Log in or Register to view URLs content!
page.

Preview of C#/WinRT Authoring​

C# .NET 5 component authors can now create their own Windows Runtime types and package them as Windows Runtime components. You can implement runtime classes in a C# library project, generate its WinMD metadata file, and distribute the WinRT component as a NuGet package. C#/WinRT provides hosting support which loads the .NET runtime, so that your C# authored component can be consumed from non-.NET languages such as C++ and Rust. This preview of authoring also supports project references to your component with a few project modifications, with more details on how to configure this in these
Please, Log in or Register to view URLs content!
. Authoring and consuming components with WinUI3 is not fully supported, but look out for WinUI 3 support in next month’s release! In the following sections, we’ll dive deeper into authoring a simple WinRT component and consuming it as a package reference. We recommend that you upgrade to the latest .NET 5.0 SDK update while using C#/WinRT authoring. Here is a more
Please, Log in or Register to view URLs content!
for authoring, as well as the related
Please, Log in or Register to view URLs content!
. For more details on C#/WinRT authoring and hosting support, refer to
Please, Log in or Register to view URLs content!
.

Authoring your WinRT component​

To author your C# runtime component, first create a new C# project in Visual Studio using the Class Library template. I named my project “AuthoringDemo”. Depending on your Visual Studio version, the project template may allow you to choose to target .NET 5, or it may be created using the netcoreapp3.1 target framework moniker. In either case, update the TargetFramework property in the project file to target .NET 5 with a specific Windows API version—here we use the latest Windows version, net5.0-windows10.0.19041.0.
<PropertyGroup>
<TargetFramework>net5.0-windows10.0.19041.0</TargetFramework>
<Platforms>x64</Platforms>
</PropertyGroup>
Next, add a NuGet reference to the latest C#/WinRT package. Right-click on your project, select Manage NuGet packages, search for Microsoft.Windows.CsWinRT and install the latest package, which is version 1.1.2-prerelease.210208.6 as of this writing. You will need to add the following C#/WinRT properties to the project file.
<!-- CsWinRT Properties -->
<PropertyGroup>
<CsWinRTComponent>true</CsWinRTComponent>
<CsWinRTWindowsMetadata>10.0.19041.0</CsWinRTWindowsMetadata>
</PropertyGroup>
The CsWinRTComponent property tells C#/WinRT that the .NET 5 component will follow the
Please, Log in or Register to view URLs content!
, and generates a WinMD file for the component so it can be hosted by other languages that support WinRT. For more details on C#/WinRT project properties, refer to our
Please, Log in or Register to view URLs content!
. You can implement your WinRT component using class (.cs) files in your C# library project. You can expose any WinRT types in your component, including
Please, Log in or Register to view URLs content!
. In general, make sure your component follows the relevant
Please, Log in or Register to view URLs content!
guidelines. Here I renamed the file to “Example.cs” and created a simple WinRT component.
// Example.cs
namespace AuthoringDemo
{
public sealed class Example
{
public int SampleProperty { get; set; }

public static string SayHello()
{
return "Hello from your C# WinRT component";
}
}
}

C#/WinRT also provides
Please, Log in or Register to view URLs content!
error messages to ensure your authored WinRT components are valid. For existing UWP .NET Native managed components, the metadata for C# WinRT components is generated by the
Please, Log in or Register to view URLs content!
. The Windows Runtime has more constraints on code than C#, so this tool was equipped with diagnostic messages to prevent you from writing runtime errors. In C#/WinRT we have added a source generator with diagnostics, alerting you to similar errors in your code at build-time before a WinMD file is generated. Below is an example of one of these diagnostics—since currently all authored runtime classes must be marked sealed, you will see the following error if you forget to do so.

"Error CsWinRT1005: Exporting unsealed types is not supported. Please mark type Example as sealed."​

Build and package your WinRT component

To generate a NuGet package for your component, add the GeneratePackageOnBuild property to your project file. I’ve also specified a custom output folder named “nuget” for my package to be generated to. Alternatively, you can right-click on the AuthoringDemo project and select Pack.
<PropertyGroup>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<PackageOutputPath>.\nuget</PackageOutputPath>
</PropertyGroup>
When the package is built, C#/WinRT automatically configures the hosting and component assemblies to allow for consumption from native apps. However, if you prefer not to rely on automatic packaging,
Please, Log in or Register to view URLs content!
provide more details on generating a custom NuGet package. Now build the AuthoringDemo project. You should be able to see the generated WinMD file under the Generated Files folder, as well as in your build output directory. Since we configured the project to generate a package on build, you can also see that “AuthoringDemo.1.0.0.nupkg” has been successfully created below.
generatedfilesoutput.png

Consume your WinRT component from a native application

To consume your component, first create a new native WinRT application. Here we added a new Windows Console Application (C++/WinRT) project to the solution named “CppConsoleApp”. From this project, add a NuGet package reference to the component, AuthoringDemo.1.0.0.nupkg. You may need to configure your package sources—to do this, click on the Settings gear in NuGet Package Manager, and add a package source to the appropriate path.
nugetpackagemanager.png
Here’s an example of what the package sources look like after adding the appropriate NuGet path. Make sure to select Update and then OK.
sources.png
After configuring your package sources, you should now be able to search for and install the “AuthoringDemo” package.
installnuget.png
Next, you will need to add two files to the CppConsoleApp project to be able to host your component: WinRT.Host.runtimeconfig.json and CppConsoleApp.exe.manifest. For more details on the steps below and managed component hosting, see the
Please, Log in or Register to view URLs content!
. To add the runtimeconfig and manifest files, right-click on the CppConsoleApp project and choose Add -> New Item, and use the Text File template. Here are the contents of WinRT.Host.runtimeconfig.json. Note for the “tfm” entry, a custom self-contained .NET 5 installation can be referenced using the DOTNET_ROOT environment variable.
{
"runtimeOptions": {
"tfm": "net5.0",
"rollForward": "LatestMinor",
"framework": {
"name": "Microsoft.NETCore.App",
"version": "5.0.0"
}
}
}
For the manifest file, since the application is not MSIX-packaged you need to include activatable class registrations for your runtime classes. Note that WinRT.Host.dll produced by C#/WinRT is used as the host DLL, and not the actual managed component DLL. Here are the contents of CppConsoleApp.exe.manifest:
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="CppConsoleApp"/>
<file name="WinRT.Host.dll">
<activatableClass
name="AuthoringDemo.Example"
threadingModel="both"
xmlns="urn:schemas-microsoft-com:winrt.v1" />
</file>
</assembly>
You will need to add both the WinRT.Host.runtimeconfig.json and CppConsoleApp.exe.manifest files to the application output. To do this in Visual Studio, select each of these files in your Solution Explorer, and in the Content field select True from the drop-down menu, like below.
deploycontent-1.png
Next in the pch.h under Header Files, add the following line of code to include your component:
#include <winrt/AuthoringDemo.h>
Finally, in main.cpp under Source Files, I added the following code to use the authored component.
#include "pch.h"
#include "iostream"

using namespace winrt;
using namespace Windows::Foundation;
using namespace std;

int main()
{
init_apartment();

AuthoringDemo::Example ex;
ex.SampleProperty(42);
wcout << ex.SampleProperty() << endl;
wcout << ex.SayHello().c_str() << endl;
}
Now when you run the console application, you will see this in the output!
runconsoleapp.png
Thanks for following along with this walkthrough of C#/WinRT authoring—in the upcoming weeks we will continue improving the project support and end-to-end authoring experience, so stay tuned! The team is also working to provide more complete support for authoring and consuming components using WinUI 3. For more details on authoring and consuming C# WinRT components, see
Please, Log in or Register to view URLs content!
and our
Please, Log in or Register to view URLs content!
.

.NET 5.0 SDK Updates - SupportedOSPlatform attributes

In addition to the latest C#/WinRT authoring preview, the team has also made a couple updates for the
Please, Log in or Register to view URLs content!
February update with C#/WinRT version 1.1.1. This includes several bug-fixes to the runtime and Windows SDK projections provided by C#/WinRT—a full list can be found
Please, Log in or Register to view URLs content!
. One C#/WinRT feature that we have added as part of the February update is
Please, Log in or Register to view URLs content!
. With the integration of these attribute checks in Visual Studio, you now get a
Please, Log in or Register to view URLs content!
when calling platform-specific APIs that are not supported on the platform versions your project supports. Let’s check out an example of what this looks like.
using System;
using Windows.Devices.Display;
using Windows.Devices.Enumeration;
namespace Net5ConsoleApp
{
class Program
{
static async System.Threading.Tasks.Task Main(string[] args)
{
var deviceInformations = await DeviceInformation.FindAllAsync(DisplayMonitor.GetDeviceSelector());
foreach (DeviceInformation device in deviceInformations)
{
DisplayMonitor displayMonitor = await DisplayMonitor.FromInterfaceIdAsync(device.Id);
// Print some info about the display monitor
Console.WriteLine("DisplayName: " + displayMonitor.DisplayName);
Console.WriteLine("ConnectionKind: " + displayMonitor.ConnectionKind);
// Warning CA1416: This call site is reachable on: 'Windows' 10.0.17763.0 and later.
// 'DisplayMonitor.IsDolbyVisionSupportedInHdrMode.get' is only supported on: 'Windows' 10.0.19041.0 and later.
Console.WriteLine("IsDolbyVisionSupported: " + displayMonitor.IsDolbyVisionSupportedInHdrMode);
}
}
}
}
The program above is part of a .NET 5 console application, with the following properties set in the project file:
<TargetFramework>net5.0-windows10.0.19041.0</TargetFramework>
<SupportedOSPlatformVersion>10.0.17763.0</SupportedOSPlatformVersion>
The program uses the
Please, Log in or Register to view URLs content!
in the WinRT APIs to print some information about display monitor devices that are connected to the system, such as the display name, connection kind, and whether it supports Dolby Vision in HDR mode, which is a new API addition in 19041. This is an example of what the output looks like—since I am running the application on a Windows OS version greater than 19041, there are no runtime errors.
displaymonitoroutput.png
Notice in the code above that the following warning message appears when accessing the last property, IsDolbyVisionSupportedInHdrMode.
“Warning CA1416: This call site is reachable on: 'Windows' 10.0.17763.0 and later. 'DisplayMonitor.IsDolbyVisionSupportedInHdrMode.get' is only supported on: 'Windows' 10.0.19041.0 and later.”

This is because the application supports a lower OS platform version of 10.0.17763.0, while the property IsDolbyVisionSupportedInHdrMode is only available in 10.0.19041.0 or greater. Users running the application on a lower Windows version such as 10.0.17763.0 would get a runtime error without guarding this property call. We do realize that this warning message leads developers to use version checks instead of presence checks, which may be undesirable for WinRT APIs. Because different Windows devices may support different APIs, our guidance is to always do presence checks for light up scenarios instead of explicit version checks. The recommendation for writing
Please, Log in or Register to view URLs content!
is to surround the property call with a presence check using one of the
Please, Log in or Register to view URLs content!
methods. This ensures that users running the application on an OS version lower than 10.0.19041.0 will not get any runtime errors. While the CA1416 warning persists, Visual Studio gives you the option to suppress it directly in the source file with a #pragma warning as shown below. Another option is to configure the severity of the warnings.
if (ApiInformation.IsPropertyPresent("Windows.Devices.Display.DisplayMonitor", "IsDolbyVisionSupportedInHdrMode"))
{
#pragma warning disable CA1416 // Validate platform compatibility
Console.WriteLine("IsDolbyVisionSupported: " + displayMonitor.IsDolbyVisionSupportedInHdrMode);
#pragma warning restore CA1416 // Validate platform compatibility
}
As you can see, this feature helps ensure that developers call platform-specific Windows APIs appropriately when supporting earlier Windows OS versions by adding a warning message.

Closing​

We encourage developers to try out C#/WinRT authoring and submit feedback to our
Please, Log in or Register to view URLs content!
as we continue to improve the project support for a more streamlined end-to-end authoring experience. We are working on support for more authoring scenarios such as integration with WinUI 3 desktop applications and authoring out-of-process components for use in packaged applications. C#/WinRT also continues to make bug-fixes for the .NET 5.0 SDK as part of their monthly updates. To stay up to date on the latest fixes, file any issues, and for any questions or feedback, visit the
Please, Log in or Register to view URLs content!
. Angela Zhang – C#/WinRT PM

Please, Log in or Register to view URLs content!
 

Users who are viewing this thread

Top