CsWin32: "An item with the same key has already been added" with metadata 10.0.19041.202-preview

Actual behavior

After adding reference to “Microsoft.Windows.SDK.Win32Metadata” Version “10.0.19041.202-preview” the SourceGenerator fails:

CSC : warning CS8785: Generator 'SourceGenerator' failed to generate source. It will not contribute to the output and compilation errors may occur as a result.
Exception was of type 'ArgumentException' with message 'An item with the same key has already been added. Key: JsCreateContext'

Expected behavior

Adding this reference <PackageReference Include="Microsoft.Windows.SDK.Win32Metadata" Version="10.0.19041.202-preview" /> should not cause this warning.

Repro steps

  1. NativeMethods.txt content:
CredUIPromptForWindowsCredentialsW
  1. NativeMethods.json content (if present): –

  2. Any of your own code that should be shared?

From csproj:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net5.0-windows</TargetFramework>
    <UseWPF>true</UseWPF>
    <IncludePackageReferencesDuringMarkupCompilation>true</IncludePackageReferencesDuringMarkupCompilation>
    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
    <LangVersion>9</LangVersion>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Windows.CsWin32" Version="0.1.422-beta">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
    <PackageReference Include="Microsoft.Windows.SDK.Win32Metadata" Version="10.0.19041.202-preview" />
  </ItemGroup>

  <ItemGroup>
    <Resource Include="NativeMethods.txt" />
  </ItemGroup>

</Project>


Context

  • CsWin32 version: 0.1.422-beta
  • Win32Metadata version (if explicitly set by project): 10.0.19041.202-preview
  • Target Framework: net5.0-windows
  • LangVersion (if explicitly set by project): 9

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 19 (18 by maintainers)

Most upvoted comments

We’re in the middle of refactoring the namespaces. This is the first update where C#/Win32 is surfacing them so there is some dirty laundry here. From Andrew, he no longer can generate everything in one namespace for various technical reasons, which is driving this change, so I’m not sure an opt-out would be possible. Andrew?

We need to move common types like the ones you mentioned (HANDLE, HWND, string types, etc.) up to a central namespace like Windows.Win32.Foundation (to align with the WinRT namespaces) or possibly the root at Windows.Win32. So the hope would be you add Windows.Win32 and/or Windows.Win32.Foundation as table stakes, and then add the individual namespaces you need which should be mostly self-contained. If lack of this is causing pain, we can prioritize that work.

Please do file namespace issues in the win32metadata repo. We’re actively refactoring things. If you want to help contribute even further, see https://github.com/microsoft/win32metadata/blob/master/CONTRIBUTING.md#Namespaces for how to file your feedback as PRs.

What’s really unfortunate in both the current release and current preview of VS is that the normal fix to add a using directive is not offered for generated types.

Ya, I discovered this yesterday as well. Most unfortunate. I filed a feedback ticket to ask that they fix that: https://developercommunity.visualstudio.com/t/C-Add-using-refactoring-not-offered-f/1428570 I think that ticket is “internal” but I’ve asked the powers that be to make it public so folks can vote it up.

Is the learning path always going to be a namespace guessing game until Roslyn starts offering automatic fixes?

There is a better way: set your caret on the unbound identifier and press <kbd>Ctrl</kbd>+<kbd>T</kbd>, which activates Go To All. That will jump to the generated symbol so you can see what namespace it’s defined in.

Finally, in the metadata repo and team discussions we are looking for ways to align APIs into fewer namespaces to reduce the pain.

There is a newer preview release available in the feed at the bottom of the readme. At the end of today the new fixes should get pushed to there to ensure it works and then later pushed to nuget.org.