Skip to content

C# language projection for the Windows Runtime

License

Notifications You must be signed in to change notification settings

dut3062796s/CsWinRT

 
 

Repository files navigation

Build status

The C#/WinRT Language Projection

See also:

C#/WinRT provides Windows Runtime (WinRT) projection support for the C# language. A "projection" is an adapter that enables programming the WinRT APIs in a natural and familiar way for the target language. For example, the C#/WinRT projection hides the details of interop between C# and WinRT interfaces, and provides mappings of many WinRT types to appropriate .NET equivalents, such as strings, URIs, common value types, and generic collections.

WinRT APIs are defined in *.winmd format, and C#/WinRT includes tooling that generates .NET Standard 2.0 C# code that can be compiled into interop assemblies, similar to how C++/WinRT generates headers for the C++ language projection. This means that neither the C# compiler nor the .NET Runtime require built-in knowledge of WinRT any longer.

C#/WinRT is part of the xlang family of projects that help developers create APIs that can run on multiple platforms and be used with a variety of languages. The mission of C#/WinRT is not to support cross-platform execution directly, but to support the cross-platform goals of .NET Core.

Motivation

.NET Core is the focus for the .NET platform. It is an open-source, cross-platform runtime that can be used to build device, cloud, and IoT applications. Previous versions of .NET Framework and .NET Core have built-in knowledge of WinRT which is a Windows-specific technology. By lifting this projection support out of the compiler and runtime, we are supporting efforts to make .NET more efficient for its .NET 5 release. More information about .NET can be found at https://docs.microsoft.com/en-us/dotnet/core/

WinUI3.0 is the effort to lift official native Microsoft UI controls and features out of the operating system, so app developers can use the latest controls and visuals on any in-market version of the OS. C#/WinRT is needed to support the changes required for lifting the XAML APIs out of Windows.UI.XAML and into Microsoft.UI.XAML.

However, C#/WinRT is a general effort and is intended to support other scenarios and versions of the .NET runtime, compatible down to .NET Standard 2.0.

Usage

The C#/WinRT NuGet Package provides distinct support for both WinRT component projects and application projects.

Component Project

A component project adds a NuGet reference to C#/WinRT to invoke cswinrt.exe at build time, generate projection sources, and compile these into an interop assembly. For an example of this, see the UnitTest targets. Command line options can be displayed by running cswinrt -?. The interop assembly is then typically distributed as a NuGet package itself.

Application Project

An application project adds NuGet references to both the component interop assembly produced above, and to C#/WinRT to include the winrt.runtime assembly. If a third party WinRT component is distributed without an official interop assembly, an application project may add a reference to C#/WinRT to generate its own private component interop assembly. There are versioning concerns related to this scenario, so the preferred solution is for the third party to publish an interop assembly directly.

Sample

The following msbuild project fragment demonstrates a simple invocation of cswinrt to generate projection sources for types in the Contoso namespace. These sources are then included in the project build.

  <Target Name="GenerateProjection">
    <PropertyGroup>
      <CsWinRTParams>
# This sample demonstrates using a response file for cswinrt execution.
# Run "cswinrt -h" to see all command line options.
-verbose
# Include Windows SDK metadata to satisfy references to 
# Windows types from project-specific metadata.
-in 10.0.18362.0
# Don't project referenced Windows types, as these are 
# provided by the Windows interop assembly.
-exclude Windows 
# Reference project-specific winmd files, defined elsewhere,
# such as from a NuGet package.
-in @(ContosoWinMDs->'"%(FullPath)"', ' ')
# Include project-specific namespaces/types in the projection
-include Contoso 
# Write projection sources to the "Generated Files" folder,
# which should be excluded from checkin (e.g., .gitignored).
-out "$(IntermediateOutputPath)/Generated Files"
      </CsWinRTParams>
    </PropertyGroup>
    <WriteLinesToFile
        File="$(CsWinRTResponseFile)" Lines="$(CsWinRTParams)"
        Overwrite="true" WriteOnlyWhenDifferent="true" />
    <Message Text="$(CsWinRTCommand)" Importance="$(CsWinRTVerbosity)" />
    <Exec Command="$(CsWinRTCommand)" />
  </Target>

  <Target Name="IncludeProjection" BeforeTargets="CoreCompile" DependsOnTargets="GenerateProjection">
    <ItemGroup>
      <Compile Include="$(IntermediateOutputPath)/Generated Files/*.cs" Exclude="@(Compile)" />
    </ItemGroup>
  </Target>

Building

C#/WinRT currently depends on a private prerelease WinUI 3 NuGet, which should be made public around //build. C#/WinRT also uses the .NET 5 preview SDK. This is public, but there are some related configuration steps. The build.cmd script takes care of all this, and is the simplest way to get started building C#/WinRT.

The build script is intended to be executed from a Visual Studio Developer command prompt. It installs prerequisites such as nuget and the .NET 5 SDK, configures the environment to use .NET 5 (creating a global.json if necessary), builds the compiler, and builds and executes the unit tests.

After a successful command-line build, the cswinrt.sln can be launched from the same command prompt, to inherit the necessary environment. By default, the UnitTest and WinUIProjection projections are only generated for Release configurations, where cswinrt.exe can execute in seconds. For Debug configurations, projection generation must be turned on with the project property GenerateTestProjection.

Structure

The C#/WinRT compiler and unit tests are all contained within the Visual Studio 2019 solution file, \cswinrt\cswinrt.sln.

/cswinrt

The /cswinrt folder contains the sources and cswinrt.vcxproj project file for building the C#/WinRT compiler, cswinrt.exe. The projection's base library is contained in /cswinrt/strings/WinRT.cs, which is processed by /strings.props to generate string literals contained in the compiler.

The compiler uses the WinMD NuGet package for parsing ECMA-335 metadata files. The WinMD github repo includes a winmd.natvis script for debugging metadata parsing. A symlink can be used to install the script:

for /f "tokens=2*" %i in ('reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" /v Personal ^| findstr Personal') do @for /f "tokens=2" %k in ('"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere" -latest ^| findstr catalog_productLineVersion') do @echo %j\Visual Studio %k\Visualizers| for /f "delims=" %l in ('more') do @md "%l" 2>nul & mklink "%l\winmd.natvis" "c:\git\winmd\vs\winmd.natvis"

The C#/WinRT project also contains a cswinrt.natvis script for debugging the C# projection writing, which can also be installed with a symlink:

for /f "tokens=2*" %i in ('reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" /v Personal ^| findstr Personal') do @for /f "tokens=2" %k in ('"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere" -latest ^| findstr catalog_productLineVersion') do @echo %j\Visual Studio %k\Visualizers| for /f "delims=" %l in ('more') do @md "%l" 2>nul & mklink "%l\cswinrt.natvis" "c:\git\cswinrt\cswinrt\cswinrt.natvis"

See also Deploying .natvis files.

/WinRT.Runtime

The /WinRT.Runtime folder contains the WinRT.Runtime project for building the C#/WinRT runtime assembly, winrt.runtime.dll. There are two versions of this assembly, providing an abstraction layer over both .NET Standard 2.0 and .NET 5 runtimes. While all code generated by cswinrt.exe is compatible with .NET Standard 2.0, there are runtime differences which must be addressed. The primary difference is that the .NET 5 winrt.runtime.dll provides Xaml reference tracking support, which is necessary for WinUI 3 applications to manage memory correctly. Future performance enhancements, such as function pointer support, may also be limited to the .NET 5 winrt.runtime.dll.

/nuget

The /nuget folder contains source files for producing a C#/WinRT NuGet package, which is regularly built, signed, and published to nuget.org by Microsoft. The C#/WinRT NuGet package contains the cswinrt.exe compiler, and both versions of the winrt.runtime.dll.

/UnitTest

The /UnitTest folder contains unit tests for validating the projection generated for the TestComponentCSharp project (below), for the TestWinRT\TestComponent project (below), and for foundational parts of the Windows SDK. All pull requests should ensure that this project executes without errors.

/TestWinRT

C#/WinRT makes use of the standalone TestWinRT repository for general language projection test coverage. This repo should be cloned into the root of the C#/WinRT repo, via get_testwinrt.cmd, so that the cswinrt.sln can resolve its reference to TestComponent.vcxproj. The resulting TestComponent.dll and TestComponent.winmd files are consumed by the UnitTest project above.

/TestComponentCSharp

The /TestComponentCSharp folder contains an implementation of a WinRT test component, defined in class.idl and used by the UnitTest project. To complement the general TestComponent above, the TestComponentCSharp tests scenarios specific to the C#/WinRT language projection.

/WinUI

The /WinUI folder contains several related projects for generating and building a complete Windows SDK and WinUI projection, along with an end-to-end sample app that uses the generated projection. The projection is built out of /winuiprojection, which is consumed by both the sample app under /winuidesktopsample, and a simple test project under /winuitest.

Contributing

This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.

When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.

About

C# language projection for the Windows Runtime

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C# 78.4%
  • C++ 21.2%
  • Other 0.4%