Add cswin32 mode to generate [GeneratedComInterface] and [LibraryImport] code#1474
Merged
Add cswin32 mode to generate [GeneratedComInterface] and [LibraryImport] code#1474
Conversation
…, codegen that leverages source generators
Sergio0694
reviewed
Oct 6, 2025
8e3d136 to
28f8d3d
Compare
…work previously with interop between CsWin32 and C#/WinRT.
28f8d3d to
e339f4d
Compare
…rosoft/CsWin32 into user/jevansaks/comgenerators
AArnott
reviewed
Oct 9, 2025
Member
AArnott
left a comment
There was a problem hiding this comment.
First batch of comments, focusing on the infra rather than Cswin32 changes.
src/Microsoft.Windows.CsWin32/Microsoft.Windows.CsWin32.targets
Outdated
Show resolved
Hide resolved
src/Microsoft.Windows.CsWin32/Microsoft.Windows.CsWin32.targets
Outdated
Show resolved
Hide resolved
src/Microsoft.Windows.CsWin32/build/Microsoft.Windows.CsWin32.props
Outdated
Show resolved
Hide resolved
src/Microsoft.Windows.CsWin32/build/Microsoft.Windows.CsWin32.props
Outdated
Show resolved
Hide resolved
src/Microsoft.Windows.CsWin32/build/Microsoft.Windows.CsWin32.props
Outdated
Show resolved
Hide resolved
AArnott
reviewed
Oct 10, 2025
Member
AArnott
left a comment
There was a problem hiding this comment.
All done with the tests and infra... next time I'll review CsWin32 itself. :)
test/GenerationSandbox.BuildTask.Tests/GenerationSandbox.BuildTask.Tests.csproj
Outdated
Show resolved
Hide resolved
test/GenerationSandbox.BuildTask.Tests/GenerationSandbox.BuildTask.Tests.csproj
Outdated
Show resolved
Hide resolved
src/Microsoft.Windows.CsWin32.BuildTasks/CsWin32CodeGeneratorTask.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.Windows.CsWin32.BuildTasks/CsWin32CodeGeneratorTask.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.Windows.CsWin32.BuildTasks/Microsoft.Windows.CsWin32.BuildTasks.csproj
Outdated
Show resolved
Hide resolved
src/Microsoft.Windows.CsWin32.BuildTasks/Microsoft.Windows.CsWin32.BuildTasks.csproj
Outdated
Show resolved
Hide resolved
fa5c412 to
7735acb
Compare
This was referenced Oct 20, 2025
Bump Microsoft.Windows.CsWin32 from 0.3.213 to 0.3.217
nefarius/Nefarius.Utilities.WindowsVersion#21
Merged
Bump Microsoft.Windows.CsWin32 from 0.3.213 to 0.3.228
progressonderwijs/ProgressOnderwijsUtils#1192
Closed
Closed
craigktreasure
pushed a commit
to craigktreasure/StartMenuCleaner
that referenced
this pull request
Oct 25, 2025
Updated [Microsoft.Windows.CsWin32](https://github.com/microsoft/CsWin32) from 0.3.205 to 0.3.228. <details> <summary>Release notes</summary> _Sourced from [Microsoft.Windows.CsWin32's releases](https://github.com/microsoft/CsWin32/releases)._ ## 0.3.228 ## What's Changed * BuildTask mode should not generate types from InternalsVisibleTo referenced assemblies by @jevansaks in microsoft/CsWin32#1492 * CsWin32 build task fixes for NET8/CSharp12 by @jevansaks in microsoft/CsWin32#1498 * Fix platform case sensitivity issue with CsWin32Generator tool by @jevansaks in microsoft/CsWin32#1499 * Update documentation for CsWin32RunAsBuildTask mode by @jevansaks in microsoft/CsWin32#1497 * ArrayPool can be larger than requested resulting in freeing uninitialized GCHandles by @jlaanstra in microsoft/CsWin32#1405 * Fix analyzer test break in devdiv AzDO account by @AArnott in microsoft/CsWin32#1504 ## New Contributors * @jlaanstra made their first contribution in microsoft/CsWin32#1405 **Full Changelog**: microsoft/CsWin32@v0.3.217...v0.3.228 https://www.nuget.org/packages/Microsoft.Windows.CsWin32/0.3.228 ## 0.3.217 ## What's Changed * Add cswin32 mode to generate [GeneratedComInterface] and [LibraryImport] code by @jevansaks in microsoft/CsWin32#1474 * Handle UnauthorizedAccessException in new ComTests by @jevansaks in microsoft/CsWin32#1486 * Project byte* parameters as Span<byte> by @jevansaks in microsoft/CsWin32#1488 * Fix nuspec to refer to only signed files and drop apphost.exe from the nuget by @jevansaks in microsoft/CsWin32#1489 **Full Changelog**: microsoft/CsWin32@v0.3.213...v0.3.217 ## 0.3.213 ## What's Changed * Retarget to roslyn for VS 2022 Update 14 by @AArnott in microsoft/CsWin32#1466 * .NET targeting projects should reference `Microsoft.Windows.SDK.NET.Ref` instead by @AArnott in microsoft/CsWin32#1471 * Update win32metadata version to 65.0.8-preview by @jevansaks in microsoft/CsWin32#1469 * Update dependency Microsoft.Build.NoTargets to 3.7.134 by @renovate[bot] in microsoft/CsWin32#1461 **Full Changelog**: microsoft/CsWin32@v0.3.205...v0.3.213 Commits viewable in [compare view](microsoft/CsWin32@v0.3.205...v0.3.228). </details> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This was referenced Oct 27, 2025
Closed
This was referenced Oct 28, 2025
This was referenced Oct 29, 2025
Bump Microsoft.Windows.CsWin32 from 0.3.213 to 0.3.235
progressonderwijs/ProgressOnderwijsUtils#1195
Closed
Closed
Bump Microsoft.Windows.CsWin32 from 0.3.213 to 0.3.236
progressonderwijs/ProgressOnderwijsUtils#1196
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
CsWin32 is built as a source generator, which has the limitation that its generated code cannot be seen by other source generators. This means types that cswin32 generates (e.g. HRESULT) can't be used in things like P/Invoke source generation and cswin32 itself can't generate code that uses attributes which trigger other source generators.
This is especially problematic for trying to use cswin32 in Native AOT because we cannot use runtime marshaling, and so all of the ComImport-generated code that cswin32 produces does not work. Thus far, anyone wanting to use cswin32 in NAOT has to set
allowMarshaling:falseand use cswin32 in blittable mode, which is not very friendly.This change does 2 things:
[LibraryImport]instead of[DllImport]and[GeneratedComInterface]instead of[ComImport].The build task & CsWin32Generator.exe tool
The build task is a simple ToolTask wrapper which takes its properties and passes them along to the CsWin32Generator tool. The build task is netstandard2.0-targeted to minimize dependencies and enable it to work in msbuild and dotnet environments.
The CsWin32Generator is a net9 AnyCPU dotnet tool, since we know that anyone using cswin32 must have dotnet SDK on their machine and AnyCPU is much easier to package and run in the existing pipeline.
Because CsWin32Generator runs against net9, I updated the core CsWin32 itself to be multi-targeted so that the existing source generator is still netstandard but in the exe tool it runs net9. I also did this because for a while I was going to compile the tool as AOT but that proved to be more trouble than it was worth.
Updates to cswin32 itself.
The main idea of the change is that when running as a build task, we change our generated code to produce
[GeneratedComInterface]instead of[ComImport]. Of course, it's not that simple since the source generators have different limitations/behaviors (some documented, others not).The "allowMarshaling:true" mode which is the default, is the default for the build task. Conceptually we are using marshaling via source generators instead of the runtime. You can also set "allowMarshaling:false" to produce a fully blittable projection, but the point of this change is to enable the friendly marshaling mode in AOT.
Lots of changes needed to bridge the gaps.
[GeneratedComInterface]IDispatch to derive from. We generate one with placeholder vtable entries when needed.[GeneratedComInterface]makes you be super explicit. In this change I have added an enum marshaler and a C#/WinRT type marshaler that are generated per-type when needed by the code generator and they are passed in[MarshalUsing(…)]attributes.objectthey would beunsafe IUnknown*). Thankfully cswin32 has a way to request that unmanaged versions of types get emitted even when allowMarshaling=true.[MarshalAs(Interface)] object.fixedblocks instead (the friendly methods can still haveout).get_Foo&put_Foomethods. GeneratedComInterface does not. We turn off property generation in sourcegenerators mode.Testing
I've written an extensive set of unit tests which run the cswin32generator tool, and using CSharpCompilation and CSharpGeneratorDriver, compile the generated code and verify that it has no warnings/diagnostics.
These new tests generate the entire Win32Metadata surface area using this new mode and it compiles. All the interesting cases I have turned into smaller test cases that take less time to run.