CsWinRT
CsWinRT copied to clipboard
Changes made to a C++/WinRT component does not get proper C# projection generated with a WinUI 3 application
Describe the bug We are evaluating an architecture which we generate C# projection from a C++/WinRT component using a WinUI 3 Application (consumer) instead of a C# library (wrapper around C++/WinRT). The main reason of this approach is just to avoid an extra C# projection library in our project (diagram option 1), and just reuse our application to do the CS projection generation work (diagram option 2).

The issue happens after we attempt to modify the C++/WinRT component (i.e. refactoring a WinRT type) which causes the C# projection to not be re-generated and then an unhandled exception in runtime.
Sample project: https://github.com/RobsonPontin/WinUI3/tree/main/WinUI3_GenCsProjection
NOTE: I don't see such issue for option 1 on the diagram (C# library projection).
To Reproduce
- Using the sample project above, open solution, build the WinUI 3 application and start debugging it
- At this point everything is expected to be working and the app should start. Now click on the button to run the code-behind in the click event, and it should execute without issues.
- Now stop debugger and perform a minor refactoring of the C++/WinRT component. It can be renaming the
MyLuckyNumberproperty toMyLuckyNumber2in theMyWinRtClass.idl - Once the refactoring is done, try to build the solution, run the app and repeat step
2 - The application would cause an exception and complain about the property is invalid.
Expected behavior I would expect for any changes made to the C++/WinRT component to trigger a new update and new C# projection.
Version Info
- Visual Studio Enterprise 2022 v17.4.4
- Microsoft.Windows.CsWinRT: v2.0.1
- Microsoft.Windows.SDK.BuildTools: v10.0.22621.755
- Microsoft.WindowsAppSDK: v1.2.221116.1
- .NET: net6.0-windows10.0.19041.0
From my use so far I think I'm getting changes to the interface to propagate as expected. But certainly if I make changes to the code of my C++/WinRT project without changing the interface, the output directory for the C# project will not be updated unless I also force a build of it (touch a file / rebuild).
We decide to use Option 1 above since it works quite well without any issues, build time is excellent, and it isolates responsibilities in the architecture.
For Option 2 sometimes I can't even fix the interface updates after a full rebuild for some reason. I would have to do a full cleanup with VS closed, and then build from scratch again.
Hi! Can we prevent making *.nuget from projection project? If you have any samples on Option 2, please point me. (Just add project reference?) By now, I thought this is not recommended way but if it works, I prefer it than making NuGet package.
When we update *.idl and compile it, the template code under ...\WinUI3\WinUI3_GenCsProjection\WinRtComponent\Generated Files\sources\ always updated with new property name but it is not reflected to your modified source code under ...\WinUI3\WinUI3_GenCsProjection\WinRtComponent\. This specification is just a help for API definition.
Hi! Can we prevent making
*.nugetfrom projection project? If you have any samples on Option 2, please point me. (Just add project reference?) By now, I thought this is not recommended way but if it works, I prefer it than making NuGet package. When we update*.idland compile it, the template code under...\WinUI3\WinUI3_GenCsProjection\WinRtComponent\Generated Files\sources\always updated with new property name but it is not reflected to your modified source code under...\WinUI3\WinUI3_GenCsProjection\WinRtComponent\. This specification is just a help for API definition.
You should be able to prevent it by just removing the NuGet package gen logic from the project. For option 2 you would just need to add to your WinUI 3 C# App the following:
- Dependency on CsWinRT package
- The C++/WinRT dependencies
- The RootName of each of your C++/WinRT libs unde
CsWinRTIncludeswhich will be projected like I did here for the library.
Thank you for the information. I'm trying to check whether I can give SwapChainPanel (in C# WindowsAppSDK) to SetSwapChain(SwapChainPanel const& panel) in C++ (WRC) DirectX renderer. To do it, I have to expose many properties, events and methods at the projection part (seems too much overhead). If you know such examples, please point me.