Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update embedded samples to 1.4.1 #1052

Merged
merged 6 commits into from
Nov 23, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 29 additions & 28 deletions docs/embedded.md
Original file line number Diff line number Diff line change
@@ -1,38 +1,33 @@
# Embedded C#/WinRT Support

## Overview

**Note**: Embedded support is currently **in preview**.

Embedded support is a C#/WinRT feature that allows you to compile the c# projection for the component, within the library/app itself.
**Note**: Embedded support is currently **in preview** in C#/WinRT v1.4.1.

This is done by setting the build property `CsWinRTEmbedded` to `true` in the app or library's project file.
## Overview

Enabling embedded support compiles the sources for WinRT.Runtime with the project.
For any types from the component which you want to embed in your project, they must be specified using `CsWinRTIncludes`.
Embedded support is a C#/WinRT feature that allows you to compile C# runtime (WinRT.Runtime) and projection sources into your library or app's output. This is done by setting the build property `CsWinRTEmbedded` to `true` in the app or library's project file. You must specify the types in your component or app which you want to embed using the `CsWinRTIncludes` property.
angelazhangmsft marked this conversation as resolved.
Show resolved Hide resolved
The specified types will be projected and embedded into the project's *.dll*.
This means projects using embedded support no longer have a dependency on a projection for the component, `WinRT.Runtime.dll` or `Microsoft.Windows.SDK.NET.dll` in the case of the Windows SDK projection.

For an example, you can look at the [sample](https://github.com/microsoft/CsWinRT/tree/master/src/Samples/TestEmbedded).
This means that projects using embedded support no longer have a dependency on the projection assembly for the component, `WinRT.Runtime.dll`, or `Microsoft.Windows.SDK.NET.dll` in the case of dependencies on the Windows SDK projection.

Embedded support introduces new features to the C#/WinRT toolchain:
Embedded support introduces new features and benefits to the C#/WinRT toolchain:
* Decreased component/app size: The developer only needs to include the minimum necessary parts of the Windows SDK required by their component or app, reducing the size of the output .dll significantly.
* Downlevel support: App developers on .NET 5+ can target Windows 7 (`net5.0-windows`) and light-up on Windows 10
(and Windows 11) when consuming an embedded .NET 5+ library.
* Removes the need for multi-targeting: Library authors can support all .NET Standard 2.0 app consumers, including .NET 5+, without the need for multi-targeting. App consumers are able to target any .NET Standard 2.0 compatible TFM (e.g. `netcoreapp3.1`, `net48`, and `net5.0-windows`).

It is important to remember that embedded support constrains the scope of Windows Runtime types to your binary.
It is important to remember that embedded support constrains the scope of Windows Runtime types to your binary (e.g., usage of WinRT types must be self-contained).

For an example, you can look at the [sample](https://github.com/microsoft/CsWinRT/tree/master/src/Samples/TestEmbedded).

## Scenarios

This feature allows C# apps and libraries to target `net5.0` (and above), .NET Framework 4.6.1+, `netcoreapp3.1`, and `netstandard2.0` while also using the Windows SDK.
Moreover, a library can target `netstandard2.0` and be able to run on NetFX, Net Core and Net 5.
This feature allows C# apps and libraries to target `net5.0` (and above), .NET Framework 4.6.1+, `netcoreapp3.1`, and `netstandard2.0` while also using Windows SDK types.
Moreover, a library can target `netstandard2.0` and be able to run on .NET Framework, .NET Core, and .NET 5 or later.

Note: the `netstandard2.0` generated projection is not optimized for .NET 5 and won't be as performant.
Note: the `netstandard2.0` generated projection is not optimized for .NET 5 and will not be as performant.

## Usage

Using embedded support allows you to target non-Windows specific TFMs and older versions of .NET.
Using embedded support allows you to target TFMs that are not tied to a specific Windows SDK version, as well as older versions of .NET.
You will need to set a few properties:
* `CsWinRTEmbedded` - must be set to `true` to include the sources
* `CsWinRTIncludes` - Specify the types to be projected; error `CS0246` will highlight any missing namespaces
Expand All @@ -48,7 +43,7 @@ Targeting `netstandard2.0` requires adding the following two package references:

Here is an example project file for a library cross-targeting and embedding a C#/WinRT generated projection.

```csproj
```xml
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
Expand Down Expand Up @@ -86,18 +81,24 @@ Here is an example project file for a library cross-targeting and embedding a C#
</Project>
```

You will need to enable Windows Desktop Compatible for all your referenced C++/WinRT components -- either via the properties or in the `.vcxproj` file.
**Note**: You will need to enable Windows Desktop Compatible for all your referenced C++/WinRT components, either via the project properties dialog or manually in the `.vcxproj` file.

## Common issues and troubleshooting

If you try to use an embedded projection of a native (C++/WinRT) component, via ProjectReference, then you may encounter a runtime error `CLASS_NOT_REGISTERED`.
- If you try to use an embedded projection of a native (C++/WinRT) component via ProjectReference, you may encounter a runtime error `CLASS_NOT_REGISTERED`.
You can fix this by unloading the native component project in Visual Studio, and adding the following:

```vcxproj
<PropertyGroup Label="Configuration">
<DesktopCompatible>true</DesktopCompatible>
</PropertyGroup>
```
```vcxproj
<PropertyGroup Label="Configuration">
<DesktopCompatible>true</DesktopCompatible>
</PropertyGroup>
```

Alternatively, you can right-click the C++ project in Visual Studio, select **Properties** > **General** > **Project Defaults**,
and set Windows Desktop Compatible to Yes for all configurations/platforms.

If you find any other issues using embedded support, please [file an issue](https://github.com/microsoft/CsWinRT/issues/new/choose)!

Alternatively, you can right-click the C++ project in Visual Studio, select Properties > General > Project Defaults,
and set Windows Desktop Compatible to Yes for all configurations/platforms.
## Resources

If you find any other issues using embedded support, please [file an issue]()!
- [Embedded sample](https://github.com/microsoft/CsWinRT/tree/master/src/Samples/TestEmbedded)
4 changes: 4 additions & 0 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
The [C#/WinRT NuGet package](https://www.nuget.org/packages/Microsoft.Windows.CsWinRT/) provides tooling for the following scenarios:

- [Generate and distribute an interop assembly](#generate-and-distribute-an-interop-assembly)
- [Embedded support for WinRT types](#embedded-support-for-winrt-types)
- [Author and consume a C#/WinRT component](#author-and-consume-a-cwinrt-component) (in preview)

For more information on using the NuGet package, refer to the [NuGet documentation](../nuget/readme.md). Command line options can be displayed by running `cswinrt -?`.
Expand Down Expand Up @@ -47,6 +48,9 @@ Application developers on .NET 5+ can reference C#/WinRT interop assemblies by a
src="images/Diagram_AddProjection.jpg"
width="70%" height="50%">

## Embedded support for WinRT types

Starting with C#/WinRT version 1.4.1, support is included for embedding Windows SDK projection and runtime sources for both .NET 5+ and .NET Standard 2.0 into your library or app's output. This is useful in scenarios where usage of Windows SDK types is self-contained. Embedded support removes dependencies on WinRT.Runtime.dll and Microsoft.Windows.SDK.NET.dll which reduces the library or app output size. It also allows library developers to provide downlevel support and removes the need for multi-targeting. See the [embedded docs](https://github.com/microsoft/CsWinRT/blob/master/docs/embedded.md) for more details.

## Author and consume a C#/WinRT component

Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0-windows</TargetFramework>
<Platforms>x64;x86;ARM64</Platforms>
</PropertyGroup>


<PropertyGroup>
<LangVersion>9</LangVersion>
<CsWinRTEmbedded>true</CsWinRTEmbedded>
<CsWinRTWindowsMetadata>sdk</CsWinRTWindowsMetadata>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Windows.CsWinRT" Version="1.4.0-prerelease.211109.3" />
<PackageReference Include="Microsoft.Windows.CsWinRT" Version="1.4.1" />
</ItemGroup>

<ItemGroup>
Expand Down Expand Up @@ -49,6 +48,4 @@
Windows.Foundation.AsyncOperationWithProgressCompletedHandler;
</CsWinRTIncludes>
</PropertyGroup>


</Project>
6 changes: 2 additions & 4 deletions src/Samples/TestEmbedded/Net5App/Net5App.csproj
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<Platforms>x64;x86</Platforms>
<Platforms>x64;x86;ARM64</Platforms>
<TargetFramework>net5.0-windows</TargetFramework>
<CsWinRTWindowsMetadata>sdk</CsWinRTWindowsMetadata>
</PropertyGroup>

<!-- CsWinRT reference needed for the target that blocks NETSDK1130 for the C++/WinRT components
(transitive project reference asset) -->
<ItemGroup>
<PackageReference Include="Microsoft.Windows.CsWinRT" Version="1.4.0-prerelease.211109.3" IncludeAssets="build"/>
<PackageReference Include="Microsoft.Windows.CsWinRT" Version="1.4.1" IncludeAssets="build" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\TestEmbeddedLibrary\TestEmbeddedLibrary.csproj" />
</ItemGroup>

</Project>
4 changes: 1 addition & 3 deletions src/Samples/TestEmbedded/NetCore3App/NetCore3App.csproj
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<Platforms>x64;x86</Platforms>
<Platforms>x64;x86;ARM64</Platforms>
<LangVersion>9</LangVersion>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\TestEmbeddedLibrary\TestEmbeddedLibrary.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net47</TargetFramework>
<Platforms>x64;x86;ARM64</Platforms>
</PropertyGroup>

<PropertyGroup>
Expand All @@ -12,12 +12,11 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Windows.CsWinRT" Version="1.4.0-prerelease.211109.3" />
<PackageReference Include="Microsoft.Windows.CsWinRT" Version="1.4.1" />
<PackageReference Include="System.Memory" Version="4.5.4" />
<PackageReference Include="System.Runtime.Extensions" Version="4.3.1" />
</ItemGroup>


<ItemGroup>
<ProjectReference Include="..\C++ Components\Alpha\Alpha.vcxproj" />
<ProjectReference Include="..\C++ Components\Beta\Beta.vcxproj" />
Expand Down Expand Up @@ -46,6 +45,4 @@
Windows.Foundation.AsyncOperationWithProgressCompletedHandler;
</CsWinRTIncludes>
</PropertyGroup>


</Project>
27 changes: 20 additions & 7 deletions src/Samples/TestEmbedded/README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,29 @@
# Structure
# C#/WinRT Embedded Sample

This sample is composed of C++/WinRT components, a C#/WinRT projection that uses embedded support
(WinRT and Windows SDK), and apps of various flavors that use the embedded projection.
These samples demonstrate how to use [C#/WinRT Embedded Support](../../../docs/embedded.md).

Looking at the C#/WinRT projection, `TestEmbeddedLibrary`, we see it targets several different frameworks,
## Structure

This sample is composed of a few projects to demonstrate C#/WinRT embedded support:

- C++/WinRT component projects: *Alpha*, *Beta*, *Gamma*
- *TestEmbeddedLibrary*: a C# library project using C#/WinRT embedded support to embed the WinRT.Runtime and Windows SDK sources into the projection/library output.
- C#/.NET apps of various flavors that use the embedded projection (either by referencing *TestEmbeddedLibrary*, or by referencing the C++/WinRT components and generating the projection directly in the app project):
- *Net5App*: References *TestEmbeddedLibrary* to consume the embedded projection.
- *Net5App.Bootstrap*: References *Alpha*, *Beta*, and *Gamma* and creates an embeddded projection in the app itself.
- *NetCore3App*: References *TestEmbeddedLibrary* to consume the embedded projection.
- *NetFrameworkApp*: References *Alpha*, *Beta*, and *Gamma* and creates an embeddded projection in the app itself.

Looking at the C#/WinRT embedded projection, `TestEmbeddedLibrary`, we see it targets several different frameworks,
demonstrating support for the latest Windows SDK on all platforms.

```xml
<TargetFrameworks>net6.0-windows;net5.0-windows;netstandard2.0;net48</TargetFrameworks>
```

Of the apps, `Net5App` and `NetCore3App` use the same C#/WinRT projection to make use of Windows 10 APIs
like `Windows.Devices.Geolocation` via the embedded WinRT support provided by C#/WinRT.
Of the apps, `Net5App` and `NetCore3App` reference the same C#/WinRT embedded projection (*TestEmbeddedLibrary*) to make use of WinRT APIs
like `Windows.Devices.Geolocation`. The other two apps, `Net5App.Bootstrap` and `NetFrameworkApp`, demonstrate how an app can generate and embed the projection itself using a package reference to C#/WinRT.

## Build and run the sample

The other two, `Net5App.Bootstrap` and `NetFrameworkApp` demonstrate how an app can generate and embed the projection itself.
Open `TestEmbedded.sln` in Visual Studio. Select one of the application projects described above as the startup project in Visual Studio. Then build and run the application.
Loading