Skip to content
Closed

Infra #1629

Show file tree
Hide file tree
Changes from all 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
58 changes: 58 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: Release NuGet

on:
release:
types: [published]

jobs:
publish:
permissions:
id-token: write
contents: write
runs-on: windows-2025-vs2026
steps:
- uses: actions/checkout@v6

- name: Build and pack
shell: pwsh
run: |
$version = "${{ github.event.release.tag_name }}" -replace '^v', ''
$VSDevCmd = & "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere" -latest -find Common7\tools\VSDevCmd.bat
echo "Using VSDevCmd: ${VSDevCmd}"
cmd /c "${VSDevCmd}" "&" nuget.exe restore cppwinrt.sln
cmd /c "${VSDevCmd}" "&" build_vsix.cmd Release "${version}"
if (!(Test-Path "*.nupkg")) {
echo "::error::Output nuget package not found!"
exit 1
}
if (!(Test-Path "vsix\Dev17\bin\Release\Standalone\Microsoft.Windows.CppWinRT.Dev17.vsix")) {
echo "::error::Output vsix package not found!"
exit 1
}

- name: NuGet login
uses: NuGet/login@v1
id: login
with:
user: YexuanXiao

- name: NuGet push
run: |
$version = "${{ github.event.release.tag_name }}" -replace '^v', ''
$packageName = "YexuanXiao.CppWinRTPlus.${version}.nupkg"
dotnet nuget push $packageName --api-key ${{steps.login.outputs.NUGET_API_KEY}} --source https://api.nuget.org/v3/index.json

- name: Upload to Release
shell: pwsh
run: |
$headers = @{
"Authorization" = "Bearer ${{ secrets.GITHUB_TOKEN }}"
"Content-Type" = "application/octet-stream"
}
$version = "${{ github.event.release.tag_name }}" -replace '^v', ''
$packageName = "YexuanXiao.CppWinRTPlus.${version}.nupkg"
$url = "https://uploads.github.com/repos/${{ github.repository }}/releases/${{ github.event.release.id }}/assets?name=${packageName}"
Invoke-RestMethod -Uri $url -Method POST -Headers $headers -InFile $packageName
$vsixName = "Microsoft.Windows.CppWinRT.Dev17.${version}.vsix"
$url = "https://uploads.github.com/repos/${{ github.repository }}/releases/${{ github.event.release.id }}/assets?name=${vsixName}"
Invoke-RestMethod -Uri $url -Method POST -Headers $headers -InFile "vsix\Dev17\bin\Release\Standalone\Microsoft.Windows.CppWinRT.Dev17.vsix"
1 change: 1 addition & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
MIT License

Copyright (c) Microsoft Corporation.
Copyright (c) 2026 YexuanXiao and The C++/WinRT Plus Project.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,35 @@
# C++/WinRT Plus

[![CI Tests](https://github.com/YexuanXiao/cppwinrtplus/actions/workflows/ci.yml/badge.svg)](https://github.com/YexuanXiao/cppwinrtplus/actions/workflows/ci.yml)

C++/WinRT Plus is a community-driven evolution of the original C++/WinRT project. This independent initiative is neither affiliated with nor sponsored by Microsoft. Our mission is to address long-standing issues in C++/WinRT and deliver meaningful improvements to the developer experience. While the project introduces some breaking changes, we provide a simple and smooth migration path. You can continue using it just as you would with C++/WinRT.

We're deeply grateful to the original authors of C++/WinRT for their groundbreaking work, which gave the C++ community first-class access to the Windows Runtime.

With development on the original project slowing, we believe it's time for the community to take the lead. C++/WinRT Plus builds on that strong foundation—preserving what works while addressing the issues that matter most to daily users. Join us in shaping the future of Windows Runtime development in C++.

## How to use

You can install the package directly via NuGet with the ID YexuanXiao.CppWinRTPlus.

## Roadmap

The current plans for C++/WinRT Plus can be viewed in the issue list. C++/WinRT Plus currently has many ambitious improvements, so your help is greatly needed!

## Changelog

Since the C++/WinRT mainline has accepted our module implementation, C++/WinRT Plus is now rebased onto the C++/WinRT 3.0 mainline to maintain compatibility.

All the changes listed here only show the differences from the C++/WinRT mainline, and once the C++/WinRT Plus commits are merged upstream, they will be removed.

2026/09/17:

1. C++/WinRT Plus can now work with our VSIX extension to provide visualization for WinRT types in third-party NuGet packages (such as WindowsAppSDK).
2. Fixed the issue where XamlMetadataProvider.cpp still requires the pch.h even when it is disabled.
3. Optimized the performance of winrt::to_string using C++23's new resize_and_overwrite function.

2026/03/24: Support using lambdas with explicit object parameter as delegates to resolve the issue where the captured lifetime may be shorter than the lifetime of the coroutine frame.

# The C++/WinRT language projection

C++/WinRT is an entirely standard C++ language projection for Windows Runtime (WinRT) APIs, implemented as a header-file-based library, and designed to provide you with first-class access to the modern Windows API. With C++/WinRT, you can author and consume Windows Runtime APIs using any standards-compliant C++17 compiler.
Expand Down
16 changes: 8 additions & 8 deletions nuget/Microsoft.Windows.CppWinRT.nuspec
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
<metadata minClientVersion="2.5">
<id>Microsoft.Windows.CppWinRT</id>
<id>YexuanXiao.CppWinRTPlus</id>
<version>$target_version$</version>
<title>C++/WinRT Build Support</title>
<authors>Microsoft</authors>
<owners>Microsoft</owners>
<title>C++/WinRT Plus Build Support</title>
<authors>YexuanXiao</authors>
<owners>YexuanXiao</owners>
<readme>readme.md</readme>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>C++/WinRT is a standard C++ language projection for the Windows Runtime implemented solely in header files. It allows you to both author and consume Windows Runtime APIs using any standards-compliant C++ compiler. C++/WinRT is designed to provide C++ developers with first-class access to the modern Windows API.</description>
<description>C++/WinRT Plus is a standard C++ language projection for the Windows Runtime implemented solely in header files. It allows you to both author and consume Windows Runtime APIs using any standards-compliant C++ compiler. C++/WinRT Plus is designed to provide C++ developers with first-class access to the modern Windows API.</description>
<releaseNotes></releaseNotes>
<tags>native C++ WinRT nativepackage</tags>
<copyright>© Microsoft Corporation. All rights reserved.</copyright>
<copyright>Copyright (c) Microsoft Corporation. All rights reserved. Copyright (c) 2026 C++/WinRT Plus Project. All rights reserved.</copyright>
<license type="file">LICENSE</license>
<readme>readme.md</readme>
<projectUrl>https://github.com/Microsoft/cppwinrt</projectUrl>
<projectUrl>https://github.com/YexuanXiao/cppwinrtplus</projectUrl>
<iconUrl>https://aka.ms/cppwinrt.ico</iconUrl>
</metadata>
<files>
Expand Down
155 changes: 129 additions & 26 deletions nuget/readme.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,20 @@
# Microsoft.Windows.CppWinRT NuGet Package
# YexuanXiao.CppWinRTPlus NuGet Package

Please read the [repository](https://github.com/YexuanXiao/cppwinrtplus)'s README.md for usage instructions.

## Changelog

Since the C++/WinRT mainline has accepted our module implementation, C++/WinRT Plus is now rebased onto the C++/WinRT 3.0 mainline to maintain compatibility.

All the changes listed here only show the differences from the C++/WinRT mainline, and once the C++/WinRT Plus commits are merged upstream, they will be removed.

2026/09/17:

1. C++/WinRT Plus can now work with our VSIX extension to provide visualization for WinRT types in third-party NuGet packages (such as WindowsAppSDK).
2. Fixed the issue where XamlMetadataProvider.cpp still requires the pch.h even when it is disabled.
3. Optimized the performance of winrt::to_string using C++23's new resize_and_overwrite function.

2026/03/24: Support using lambdas with explicit object parameter as delegates to resolve the issue where the captured lifetime may be shorter than the lifetime of the coroutine frame.

## Overview

Expand All @@ -7,11 +23,12 @@ Please visit [Microsoft.Windows.CppWinRT](https://www.nuget.org/packages/Microso
To add build support for C++/WinRT vcxproj projects, add a reference to the Microsoft.Windows.CppWinRT NuGet package. This customizes your project's build rules to automatically generate C++/WinRT projection headers, enabling you to both consume and produce Windows Runtime classes.

C++/WinRT detects Windows metadata required by the project, from:

* Platform winmd files in the SDK (both MSI and NuGet)
* NuGet package references containing winmd files
* Other project references producing winmd files
* Raw winmd file references
* Interface definition language (IDL) files in the project
* Interface definition language (IDL) files in the project

For any winmd file discovered above, C++/WinRT creates reference (consuming) projection headers. Client code can simply #include these headers, which are created in the generated files directory (see below).

Expand All @@ -20,6 +37,7 @@ For any IDL file contained in the project, C++/WinRT creates component (producin
## Details

C++/WinRT configures build rules for the following tools:

* C++ compiler
* C++/WinRT compiler
* MdMerge utility
Expand All @@ -30,25 +48,28 @@ It sets the following project properties and item metadata:

| Property | Value | Description |
|-|-|-|
| [PreferredToolArchitecture](https://docs.microsoft.com/en-us/cpp/build/msbuild-visual-cpp-overview?view=vs-2017) | x64 | Enables the compiler to use more memory |
| [PreferredToolArchitecture](https://learn.microsoft.com/en-us/cpp/build/reference/msbuild-visual-cpp-overview?view=msvc-180) | x64 | Enables the compiler to use more memory |
| CanReferenceWinRT | true | Enables native project references (e.g., to WinMD files) |
| GeneratedFilesDir | *$(IntDir)Generated Files\ | Sets the folder for C++/WinRT generated source files |
| XamlLanguage | CppWinRT | Directs the Xaml compiler to generate C++/WinRT code |
| ClCompile.CompileAsWinRT | *false | Enables ISO C++ compilation (disables C++/CX) |
| ClCompile.LanguageStandard | *stdcpp17 | Enables C++17 language features |
| ClCompile.LanguageStandard | *stdcpp20 | Enables C++20 language features |
| ClCompile.AdditionalOptions | /bigobj | Enables support for large object files |
| ClCompile.AdditionalIncludeDirectories | GeneratedFilesDir | Adds $(GeneratedFilesDir) to the C++ include dirs |
| Link.AdditionalDependencies | WindowsApp.lib | Umbrella library for Windows Runtime imports |
| Midl.AdditionalOptions | /reference ... | Enables faster compilation with winmd references (versus idl imports) |
| Midl.EnableWindowsRuntime | true | Enables Windows Runtime semantics |
| Midl.MetadataFileName | Unmerged\%(Filename).winmd | Generates unmerged metadata in a temporary location |
| Midl.GenerateClientFiles, GenerateServerFiles, GenerateStublessProxies, GenerateTypeLibrary, HeaderFileName, DllDataFileName, InterfaceIdentifierFileName, ProxyFileName, TypeLibraryName | *nul, *None, *false | Disable unnecessary output |
\*If not already set
| Midl.GenerateClientFiles, GenerateServerFiles, GenerateStublessProxies, GenerateTypeLibrary, HeaderFileName, DllDataFileName, InterfaceIdentifierFileName, ProxyFileName, TypeLibraryName | \*nul, \*None, \*false | Disable unnecessary output |

\*If not already set

## Generated Files

The generated files directory created by C++/WinRT contains two subfolders:
* sources: runtime class skeleton implementations
* winrt: reference projection headers

* sources: runtime class skeleton implementations
* winrt: reference projection headers

## Customizing

Expand All @@ -58,28 +79,120 @@ C++/WinRT behavior can be customized with these project properties:
|-|-|-|
| CppWinRTLibs | *true \| false | Enables the Link item metadata settings above |
| CppWinRTModernIDL | *true \| false | Enables the Midl item metadata settings above |
| CppWinRTVerbosity | low \| *normal \| high | Sets the [importance](https://docs.microsoft.com/en-us/visualstudio/msbuild/message-task?view=vs-2017) of C++/WinRT build messages (see below) |
| CppWinRTVerbosity | low \| *normal \| high | Sets the [importance](https://learn.microsoft.com/en-us/visualstudio/msbuild/message-task?view=visualstudio) of C++/WinRT build messages (see below) |
| CppWinRTNamespaceMergeDepth | *1 | Sets the depth of namespace merging (Xaml apps require 1) |
| CppWinRTRootNamespaceAutoMerge | true \| *false | Sets the namespace merge depth to be the length of the root namespace |
| CppWinRTMergeNoValidate | true \| *false | Disables mdmerge validation |
| CppWinRTUsePrefixes | *true \| false | Uses a dotted prefix namespace convention (versus a nested folder convention) |
| CppWinRTUseModules | true \| *false | Generate C++ modules (ixx) for each namespaces |
| CppWinRTPath | ...\cppwinrt.exe | NuGet package-relative path to cppwinrt.exe, for custom build rule invocation |
| CppWinRTParameters | "" | Custom cppwinrt.exe command-line parameters (be sure to append to existing) |
| CppWinRTFastAbi | true \| *false | Enables Fast ABI feature for both consuming and producing projections |
| CppWinRTProjectLanguage | C++/CX \| *C++/WinRT | Selects the C++ dialect for the project. C++/WinRT provides full projection support, C++/CX permits consuming projection headers. |
| CppWinRTOptimized | true \| *false | Enables component projection [optimization features](https://kennykerr.ca/2019/06/07/cppwinrt-optimizing-components/) |
| CppWinRTGenerateWindowsMetadata | true \| *false | Indicates whether this project produces Windows Metadata |
| CppWinRTEnableDefaultPrivateFalse | true \| *false | Indicates whether this project uses C++/WinRT optimized default for copying binaries to the output directory |
| CppWinRTBuildModule | true \| *false | Generates per-namespace C++20 module interface units (.ixx) alongside projection headers |
| CppWinRTModuleInclude | namespace list | Semicolon-delimited namespaces to include in module generation (default: all) |
| CppWinRTModuleExclude | namespace list | Semicolon-delimited namespaces to exclude from module generation |

\*Default value

To customize common C++/WinRT project properties:
To customize common C++/WinRT project properties:

* right-click the project node
* expand the Common Properties item
* select the C++/WinRT property page

## Exclude what you don't want

You can prevent unnecessary namespaces from being generated, such as, by adding a CppWinRT.config file to the solution directory. Since some modules are very large, this can effectively reduce compilation time.

The format of the configuration file is:

```xml
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<include>
<prefix>Windows.Foundation</prefix>
</include>
<exclude>
<prefix>Windows.UI.Xaml</prefix>
<prefix>Windows.ApplicationModel.Store</prefix>
</exclude>
</configuration>
```

It is equivalent to passing `-config <path\` to cppwinrt.exe, which combines the `-include` and `-exclude` options.

Note that namespace exclusion occurs at a very early stage of the build process, so a clean build needs to be performed for it to take effect.

It's suggest excluding Windows.UI.Xaml and Windows.ApplicationModel.Store, as the latter depends on the former. By excluding Windows.UI.Xaml, the BMI size can be reduced by one-third.

## Using C++ modules

When writing a module, you should ensure that any third-party library includes are placed before `export module`. All module tutorials will teach this.

When consuming a module, you need to ensure that all third-party includes are placed before `import`. For details on how to consume XAML modules, refer to the explanation below.

## Make XAML modular

XAML components written with C++/WinRT typically have two files: `Class.xaml.h` and `Class.xaml.cpp`. To make them modular, rewrite `Class.xaml.h` as follows:

```cpp
#pragma once

#include "Class.g.h"

namespace winrt::Project::implementation
{
// Implementation code
}

namespace winrt::Project::factory_implementation
{
// Implementation code
}
```

Then, rewrite `ClassName.xaml.cpp` as follows:

```cpp
#define WINRT_CONSUME_MODULE

// Due to current limitations in the XAML Compiler implementation, you need to import all XAML dependencies before including ClassName.xaml.h
import Microsoft.UI.Xaml.Markup;

// Here, you need to import all dependencies of the Class's interface

#include "Class.xaml.h"
#if __has_include("Detail.g.cpp")
#include "Detail.g.cpp"
#endif

namespace winrt::Project::implementation
{
// Implementation code
}
```

Additionally, you can disbale pch for `Class.xaml.cpp`.

Note that `App.xaml.h` has a special form. You also need to add the following right before `#include "App.xaml.h"`:

```cpp
#define COM_NO_WINDOWS_H
#define __unknwn_h__
#define __RPC_H__
#define __RPCNDR_H__
#define _INC_WINAPIFAMILY
#define _INC_WINDOWS
#define _INC_SDKDDKVER

#define _FUNCTIONAL_
#define _VECTOR_
#define _MAP_
#define _MUTEX_
```

You can refer to [this example](https://github.com/YexuanXiao/Authenticator/tree/module) to modularize your project.

## InitializeComponent

In older versions of C++/WinRT, Xaml objects called InitializeComponent from constructors. This can lead to memory corruption if InitializeComponent throws an exception.
Expand Down Expand Up @@ -135,17 +248,6 @@ void DerivedPage::InitializeComponent()
}
```

## C++20 Modules

C++/WinRT supports C++20 named modules as an alternative to `#include`-based consumption. Instead of `#include <winrt/Windows.Foundation.h>`, you can write `import winrt.Windows.Foundation;`.

See the [C++/WinRT C++20 Modules Guide](https://github.com/microsoft/cppwinrt/blob/master/nuget/modules.md) for the full guide (also shipped alongside this file as `modules.md`).

| ProjectReference metadata | Description |
|-|-|
| CppWinRTConsumeModule | true \| *false | When set on a ProjectReference, consumes pre-built platform module IFCs from the referenced project |
\*Default value

## Troubleshooting

The msbuild verbosity level maps to msbuild message importance as follows:
Expand All @@ -156,7 +258,8 @@ The msbuild verbosity level maps to msbuild message importance as follows:
| m[inimal] | high |
| n[ormal] | normal+ |
| d[etailed], diag[nostic] | low+ |
For example, if the verbosity is set to minimal, then only messages with high importance are generated. However, if the verbosity is set to diagnostic, then all messages are generated.

For example, if the verbosity is set to minimal, then only messages with high importance are generated. However, if the verbosity is set to diagnostic, then all messages are generated.

The default importance of C++/WinRT build messages is 'normal', but this can be overridden with the CppWinRTVerbosity property to enable throttling of C++/WinRT messages independent of the overall verbosity level.

Expand Down