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

[Bug]: Cannot get INuGetProjectService from the service broker in Visual Studio 17 #11367

Closed
reduckted opened this issue Nov 9, 2021 · 7 comments
Assignees
Labels
Functionality:SDK The NuGet client packages published to nuget.org Priority:1 High priority issues that must be resolved in the current sprint. Product:VS.Client Type:Bug

Comments

@reduckted
Copy link

reduckted commented Nov 9, 2021

NuGet Product Used

MSBuild.exe

Product Version

Visual Studio 17.0.0

Worked before?

No response

Impact

I'm unable to use this version

Repro Steps & Context

An exception is thrown in Visual Studio 2017 2022 when trying to get an INuGetProjectService from the Visual Studio service broker. This code:

var serviceBrokerContainer = await ServiceProvider.GetGlobalServiceAsync<SVsBrokeredServiceContainer, IBrokeredServiceContainer>();
var serviceBroker = serviceBrokerContainer.GetFullAccessServiceBroker();

// This next line throws the exception.
var projectService = await serviceBroker.GetProxyAsync<INuGetProjectService>(NuGetServices.NuGetProjectServiceV1);

Throws this error in Visual Studio 17.0.0:

Activating the "Microsoft.VisualStudio.NuGet.NuGetProjectService (1.0)" service failed.
Unable to cast object of type 'NuGet.VisualStudio.Implementation.Extensibility.NuGetProjectService' to type 'NuGet.VisualStudio.Contracts.INuGetProjectService'.

The package references I'm using are:

<PackageReference Include="Microsoft.VisualStudio.SDK">
  <Version>17.0.31902.203</Version>
</PackageReference>
<PackageReference Include="NuGet.Protocol">
  <Version>6.0.0</Version>
</PackageReference>
<PackageReference Include="NuGet.VisualStudio">
  <Version>6.0.0</Version>
</PackageReference>
<PackageReference Include="NuGet.VisualStudio.Contracts">
  <Version>6.0.0</Version>
</PackageReference>

I'm also seeing a warning about the version of Microsoft.ServiceHub.Framework not being found. Could this be related? It seems like the NuGetProjectService returned from the service broker is implementing the INuGetProjectService interface from a different assembly to the one I am expecting.

Using this project file:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="NuGet.VisualStudio.Contracts" Version="6.0.0" />
  </ItemGroup>
</Project>

Restoring packages gives this warning:

NU1603 NuGet.VisualStudio.Contracts 6.0.0 depends on Microsoft.ServiceHub.Framework (>= 2.7.327-preview) but Microsoft.ServiceHub.Framework 2.7.327-preview was not found. An approximate best match of Microsoft.ServiceHub.Framework 2.7.339 was resolved.

Microsoft.ServiceHub.Framework 2.7.327-preview is not listed on NuGet.

Verbose Logs

No response

@zivkan
Copy link
Member

zivkan commented Nov 9, 2021

NuGet follows Visual Studio's version, minus 11.0. Therefore NuGet.VisualStudio.Contracts package version 6.0 tracks Visual Studio 6.0 + 11.0 = 17.0. Note this is dev17, not Visual Studio 2017, which is dev15.

If you're targeting Visual Studio 2017, which corresponds to NuGet 4.x, you should that version of the NuGet.VisualStudio package. NuGet.VisualStudio.Contracts was added in dev16 (VS 2019), so it's expected not to work in dev15.

The only API that INuGetProjectService currently has is GetInstalledPackagesAsync. Earlier versions of VS only supports our non-async (blocking) IVsPackageInstallerServices.GetInstalledPackages

@zivkan zivkan closed this as completed Nov 9, 2021
@zivkan zivkan added Functionality:SDK The NuGet client packages published to nuget.org Product:VS.Client Resolution:ByDesign This issue appears to be ByDesign and removed Triage:Untriaged labels Nov 9, 2021
@reduckted
Copy link
Author

reduckted commented Nov 9, 2021

🤦‍♂️ Sorry, I got my version numbers confused. I meant Visual Studio 2022 (v17.0.0).

@zivkan can you reopen this, please?

@zivkan
Copy link
Member

zivkan commented Nov 10, 2021

@reduckted we have a tool we use to test our VS APIs, available here: https://github.com/NuGet/Entropy/tree/main/IVsTestingExtension

Can you try it out and see if you still have the problem? It works for me, I was using it today in fact.

My best guess is that your vsix contains your own copy of NuGet.VisualStudio.Contracts.dll, and so VS is loading both copies of the dll. Even when two assemblies are the same assembly version, a type created in path1\some.dll can't be typecast to the same type in path2\some.dll. NuGet tells VS to create binding redirects though, and we don't have a problem with this testing extension, so I don't have any ideas what the issue could be.

@zivkan zivkan reopened this Nov 10, 2021
@reduckted
Copy link
Author

My best guess is that your vsix contains your own copy of NuGet.VisualStudio.Contracts.dll

You were correct! The NuGet assemblies were being included in the VSIX. However, when I exclude the NuGet files from the VSIX, I get a different error:

System.IO.FileNotFoundException: 'Could not load file or assembly 'NuGet.VisualStudio.Contracts, Version=6.0.0.280, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.'

I tried the Entropy extension and it worked from the latest commit (488ac98). But that version is using 5.10.0 of the NuGet packages. If I update those two packages (NuGet.VisualStudio and NuGet.VisualStudio.Contracts) to version 6.0.0, then I get the original error about being unable to cast the service to the required type.

Could the binding redirects not be including the latest version of the NuGet packages? The only binding redirects for NuGet assemblies that I could find in the Visual Studio installation directory were in vsn.exe.config, and they list this:

<!-- NuGet -->
<dependentAssembly>
  <assemblyIdentity name="NuGet.VisualStudio" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
  <bindingRedirect oldVersion="0.0.0.0-6.0.0.275" newVersion="6.0.0.275"/>
  <codeBase version="6.0.0.275" href="CommonExtensions\Microsoft\NuGet\NuGet.VisualStudio.dll"/>
</dependentAssembly>
<dependentAssembly>
  <assemblyIdentity name="NuGet.VisualStudio.Contracts" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
  <bindingRedirect oldVersion="0.0.0.0-6.0.0.275" newVersion="6.0.0.275"/>
  <codeBase version="6.0.0.275" href="CommonExtensions\Microsoft\NuGet\NuGet.VisualStudio.Contracts.dll"/>
</dependentAssembly>

That has an upper bound of 6.0.0.275, but the version in the NuGet.VisualStudio.Contracts.6.0.0 package is 6.0.0.280.

@zivkan
Copy link
Member

zivkan commented Nov 10, 2021

Yes, you're right. We screwed up. NuGet inserts into both Visual Studio and the .NET SDK, but NuGet has a mono-repo with both our VS and .NET SDK assets being created from the same build. Because reasons, we had to insert a higher build number of NuGet into the .NET SDK than we did into VS, which is normally the other way around. The packages we published to nuget.org was the highest of the two, but this breaks VS extension developers using NuGet.VisualStudio.Contracts.

Interestingly NuGet.VisualStudio should not be affected because that assembly version is always 1.0.0.0. When I created NuGet.VisualStudio.Contracts.dll, I debated whether or not we should do the same, but decided not to because N.VS contained mostly COM embeddable interfaces, whereas N.VS.C would not.

The bar to make servicing changes is high, so I'm not sure if we'll be able to insert a higher build of NuGet into dev17.0 to fix this, but I'll ask around. I'll also try to make sure this can't happen again in dev17.1 or later.

NuGet's contracts have not changed between dev16.11 (Nuget 5.11) and dev17.0 (NuGet 6.0), so it's safe from an API perspective to use that version for your extension development, as a workaround. I just hope there aren't package version problems using the 17.0 VS SDK with NuGet.VisualStudio.Contracts 5.11.0, since it will have some dependencies from the 16.x VS SDK.

@reduckted
Copy link
Author

NuGet's contracts have not changed between dev16.11 (Nuget 5.11) and dev17.0 (NuGet 6.0), so it's safe from an API perspective to use that version for your extension development, as a workaround.

Awesome, I'll stick with 5.11 for now. Thanks for your help, @zivkan 😄

@nkolev92 nkolev92 added Priority:1 High priority issues that must be resolved in the current sprint. and removed Resolution:ByDesign This issue appears to be ByDesign labels Nov 11, 2021
@nkolev92 nkolev92 added this to the Sprint 2021-11 milestone Nov 11, 2021
@zivkan
Copy link
Member

zivkan commented Nov 30, 2021

Visual Studio 17.0.2 was released today, and it should no longer have a problem with NuGet.VisualStudio package version 6.0.0.

@zivkan zivkan closed this as completed Nov 30, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Functionality:SDK The NuGet client packages published to nuget.org Priority:1 High priority issues that must be resolved in the current sprint. Product:VS.Client Type:Bug
Projects
None yet
Development

No branches or pull requests

3 participants