Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 获取VisualStudio在VSIX项目中存储的Nuget凭据_C#_Visual Studio_Nuget_Visual Studio Extensions_Vsix - Fatal编程技术网

C# 获取VisualStudio在VSIX项目中存储的Nuget凭据

C# 获取VisualStudio在VSIX项目中存储的Nuget凭据,c#,visual-studio,nuget,visual-studio-extensions,vsix,C#,Visual Studio,Nuget,Visual Studio Extensions,Vsix,我正在开发一个VisualStudio扩展(VSIX项目),它需要管理给定项目的Nuget包 我已经在使用IVsPackageInstaller服务,但这是有限的,我需要更多功能(例如获取给定软件包的最新版本号) 我搜索了,但没有找到任何关于如何以编程方式与VisualStudio包管理器交互的信息,所以我决定直接使用NuGetAPI 我使用WebRequest类向NuGetAPI发送HTTP请求(因为我们不能在VSIX项目中使用HttpClient),但我遇到了一个问题:请求将发送到需要身份验

我正在开发一个VisualStudio扩展(VSIX项目),它需要管理给定项目的Nuget包

我已经在使用
IVsPackageInstaller
服务,但这是有限的,我需要更多功能(例如获取给定软件包的最新版本号)

我搜索了,但没有找到任何关于如何以编程方式与VisualStudio包管理器交互的信息,所以我决定直接使用NuGetAPI

我使用
WebRequest
类向NuGetAPI发送HTTP请求(因为我们不能在VSIX项目中使用
HttpClient
),但我遇到了一个问题:请求将发送到需要身份验证的私有Nuget提要!(托管在Azure DevOps上)

我曾经检查发送到Azure DevOps服务器的HTTP请求。我看到一个POST请求转到
https://app.vssps.visualstudio.com/_apis/Token/SessionTokens
带有响应令牌,但这不是我要找的令牌

传递给Nuget API的令牌是一个
Basic
令牌,它来自我不知道在哪里。我在捕获的HTTP响应中找不到该令牌

我还可以看到,对我们的Azure DevOps服务器的一些响应包含一些类似这样的标题(我更改了GUID)

我可以在
%userprofile%\AppData\Local\.IdentityService\AccountStore.json
文件中找到这个GUID,这里肯定发生了一些事情。同一文件夹中的
SessionTokens.json
文件看起来也很有趣,但它是加密的

我还尝试在注册表中挖掘,看看是否可以在中指定的路径中找到感兴趣的信息,但似乎VS2017不再在那里存储令牌

我还加载了
privateregistry.bin
文件(也称为
visualstudio设置存储
)并到处搜索,但找不到任何东西

因此,我不想尝试对VisualStudio进行反向工程,而是想直接访问它的凭据提供程序。我试图访问几个服务和类

var componentModel = await ServiceProvider.GetGlobalServiceAsync(typeof(SComponentModel)) as IComponentModel;
var credentialProvider = componentModel.GetService<IVsCredentialProvider>();
var credentialServiceProvider = componentModel.GetService<ICredentialServiceProvider>();
var defaultCredentialServiceProvider = new DefaultVSCredentialServiceProvider();
var componentModel=wait ServiceProvider.GetGlobalServiceAsync(typeof(scoComponentModel))作为IComponentModel;
var credentialProvider=componentModel.GetService();
var-credentialServiceProvider=componentModel.GetService();
var defaultCredentialServiceProvider=新的DefaultVSCredentialServiceProvider();
但它们都不起作用(返回null或Exception)

我在Github的项目中漫游,但找不到我的答案

还有许多Nuget软件包,如
Nuget.PackageManagement.VisualStudio
Microsoft.VisualStudio.Services.Release.Client
Microsoft.VisualStudio.Services.ExtensionManagement.WebApi
Microsoft.VisualStudio.Services.InteractiveClient
仅举几个例子,但老实说,我不知道我要找的是不是有

那么如何访问VisualStudio使用的Nuget凭据呢

我采用任何允许我访问所有reading Nuget功能的解决方案,例如以编程方式使用Visual Studio包管理,或解密此
SessionTokens.json
文件,或访问Visual Studio凭据提供程序

答案越不老套越好

此时,您可能已经猜到了,我不想将
用户名
密码
存储在我自己的某个地方。我需要创建一个用户友好的VS扩展,这就是为什么我要检索和使用用户已经保存在VisualStudio中的凭据

非常感谢您能解决此问题。

NuGet Client SDK 非常感谢你

这是一个链接,但它们也给出了一个很好的提示:

这些博客文章是在3.4.3版本的NuGet client SDK软件包发布后不久撰写的。更新版本的软件包可能与博客文章中的信息不兼容

好吧,那我想我们就用Dave的博客吧

您应该安装两个软件包:和

下面是获取软件包最新版本的示例代码:

using NuGet.Configuration;
using NuGet.Protocol;
using NuGet.Protocol.Core.Types;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace MyProject
{
    public class NugetHelper
    {
        public async Task<string> GetLatestVersionNumberFromNugetFeedAsync(NugetPackage package)
        {
            try
            {
                Logger logger = new Logger(); //Just a class implementing the Nuget.Common.ILogger interface
                List<Lazy<INuGetResourceProvider>> providers = new List<Lazy<INuGetResourceProvider>>();
                providers.AddRange(Repository.Provider.GetCoreV3());  // Add v3 API support
                PackageSource packageSource = new PackageSource(package.Source.ToString());
                SourceRepository sourceRepository = new SourceRepository(packageSource, providers);
                PackageMetadataResource packageMetadataResource = await sourceRepository.GetResourceAsync<PackageMetadataResource>();
                var searchMetadata = await packageMetadataResource.GetMetadataAsync(package.Name, false, false, new SourceCacheContext(), logger, new CancellationToken());
                var versionNumber = searchMetadata.FirstOrDefault().Identity.Version.OriginalVersion;
                return versionNumber;
            }
            catch (Exception ex)
            {
                return null;
            }
        }
    }

    public class NugetPackage
    {
        public string Name { get; set; }
        public string Version { get; set; }
        public string MinimumVersion { get; set; }
        public Uri Source { get; set; }
    }
}

但是这不起作用,所以如果有人知道如何访问Visual Studio凭据提供程序,我很高兴知道答案。

为什么不使用nuget客户端API?这就是VisualStudio所使用的。哇,非常感谢,老实说,我有点惊讶关于这一点的唯一文档是2016年的一篇非官方博客文章。这解决了我的裸体问题,但我很固执,当我面对问题时,我喜欢理解。开发人员是否可以使用服务提供商正式访问VS存储的凭据?如果是,我们怎么办?谢谢你的回答现在所有的东西都是开源的,有一些缺点。现在官方发布的是一个灰色地带,文档也大大减少了。作为开发人员,我们现在依靠自己。。。许多VS软件包现在都在使用MEF,因此我认为您可以向MEF索要在NuGet.PackageManagement.VisualStudio中定义的ICredentialServiceProvider接口。如果您想更深入,只需分析这是如何实现的。Visual Studio代码库很大,祝您好运:-)就是这样,我尝试了
componentModel.GetService()
,但它没有给我任何实际的凭据提供程序。是的,它是巨大的,我迷失在所有的代码中,这就是为什么我希望你有神奇的答案。但是谢谢,您通过指向
NuGet.Client
帮助了我很多。有了这些代码,我完全不知道我应该用什么东西。你应该提供一个小的复制样本太好了,谢谢你在这里分享你的解决方案,你可以。这对阅读此帖子的其他社区成员有益,我们可以关闭此帖子,谢谢。它解决了我的问题,但实际上并没有完全回答我的问题。我开始创建一个示例项目,但我现在没有太多时间。我也是sti
using NuGet.Configuration;
using NuGet.Protocol;
using NuGet.Protocol.Core.Types;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace MyProject
{
    public class NugetHelper
    {
        public async Task<string> GetLatestVersionNumberFromNugetFeedAsync(NugetPackage package)
        {
            try
            {
                Logger logger = new Logger(); //Just a class implementing the Nuget.Common.ILogger interface
                List<Lazy<INuGetResourceProvider>> providers = new List<Lazy<INuGetResourceProvider>>();
                providers.AddRange(Repository.Provider.GetCoreV3());  // Add v3 API support
                PackageSource packageSource = new PackageSource(package.Source.ToString());
                SourceRepository sourceRepository = new SourceRepository(packageSource, providers);
                PackageMetadataResource packageMetadataResource = await sourceRepository.GetResourceAsync<PackageMetadataResource>();
                var searchMetadata = await packageMetadataResource.GetMetadataAsync(package.Name, false, false, new SourceCacheContext(), logger, new CancellationToken());
                var versionNumber = searchMetadata.FirstOrDefault().Identity.Version.OriginalVersion;
                return versionNumber;
            }
            catch (Exception ex)
            {
                return null;
            }
        }
    }

    public class NugetPackage
    {
        public string Name { get; set; }
        public string Version { get; set; }
        public string MinimumVersion { get; set; }
        public Uri Source { get; set; }
    }
}
var componentModel = await ServiceProvider.GetGlobalServiceAsync(typeof(SComponentModel)) as IComponentModel;
componentModel.GetService<ICredentialServiceProvider>()