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

Support consumption of arbitrary winmds produced with win32metadata tooling #356

Closed
mikebattista opened this issue Aug 11, 2021 · 8 comments
Assignees
Labels
enhancement New feature or request

Comments

@mikebattista
Copy link
Contributor

Is your feature request related to a problem? Please describe.
As part of microsoft/win32metadata#66, we are making it possible for others to produce winmds for C APIs outside of the Windows SDK. We'll need to update C#/Win32 to support consumption of those winmds.

Describe the solution you'd like
C#/Win32 recognizes win32metadata-compliant winmd files in the project and generates P/Invoke bindings from them just as it does for Windows.Win32.winmd.

@mikebattista mikebattista added the enhancement New feature or request label Aug 11, 2021
@AArnott AArnott self-assigned this Aug 18, 2021
@CarePackage17
Copy link

Now that WDK metadata can be consumed, is it possible to use custom winmd files as well?

@AArnott
Copy link
Member

AArnott commented Jun 7, 2023

It should be, yes. It's not a particularly well tested area yet, but we're interested in folks leveraging this and I'd be interested in any bugs you file in trying it out.

Ultimately your project file will need a ProjectionMetadataWinmd msbuild item that refers to your custom winmd. If you want you can do this in a nuget package the way the two existing metadata inputs do so that folks can just add a package reference to your package and cswin32 will automatically consume it.

@riverar
Copy link

riverar commented Jun 19, 2023

It appears the current directory for ProjectionMetadataWinmd is \Program Files\Microsoft Visual Studio\2022\Professional\MSBuild\Current\Bin\Roslyn so be sure to preface your Include= with $(MSBuildProjectDirectory) or other anchor point.

Example:

<ItemGroup>
  <ProjectionMetadataWinmd Include="$(MSBuildProjectDirectory)\path\to\your.winmd" />
</ItemGroup>

@riverar
Copy link

riverar commented Jun 20, 2023

One other nit: Appears Roslyn, Visual Studio, or something in-between leaks a file handle somewhere. Even after closing the project/solution, you can't move/delete the winmd.

@AArnott
Copy link
Member

AArnott commented Jun 20, 2023

Thanks for the feedback, @riverar.

We hold onto the metadata for perf reasons. I'm afraid there's no good event to signal a source generator that state has been closed to give us a good hint that we should release handles. But by holding onto it, repeat compilations (which happen constantly in an IDE) or many projects in a build at the command line are made much faster.

I have a fix for the qualifying path to winmd issue.

@riverar
Copy link

riverar commented Jun 20, 2023

Are source generators meant to hang around even after project/solution closure? Or is this a case of a missing file handle close in Dispose/Finalizer?

@AArnott
Copy link
Member

AArnott commented Jun 20, 2023

I don't think the roslyn compiler process ever unloads source generators. And typically (in VS or command line) the compiler runs in a vbcscompiler.exe process that outlives any particular build specifically to speed up subsequent builds.

CsWin32 could drop file handles after a compilation, but again, we intentionally do not because it greatly speeds up subsequent builds. And for most folks, the metadata doesn't change between builds (yours is the first case I've heard where that wasn't true, in fact) so optimizing perf is the right trade-off.
Why does your metadata change frequently? If it is likely to continue this way for a long time, and especially if other customers might hit this as well, we may be able to add an option that you can set to force CsWin32 to unload its caches and close its metadata file handles after compilations are done.

@riverar
Copy link

riverar commented Jun 20, 2023

Makes sense, sounds like I need to file a bug on Roslyn to expose a lifecycle event. Don't think it's fair to blame CsWin32 for this one.

My scenario was simply trying to reorganize some files/directories. After adding <ProjectionMetadataWinmd Include="$(MSBuildProjectDirectory)\path\to\your.winmd" /> I was doomed and couldn't move it to a better location until I killed vbcscompiler.exe manually after closing VS.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants