首页 文章

如何在VSIX扩展中处理VSTS凭据

提问于
浏览
2

我有一个Visual Studio扩展,我们在内部用于项目,它需要做的一件事是将门票发布到VSTS . 以前我们使用现场TFS并且 Build 与门票的连接非常简单:

var vssCreds = new VssCredentials(true);    
projectCollection = new TfsTeamProjectCollection(url, vssCreds);
workItems = projectCollection.GetService<WorkItemStore>();
project = workItems.Projects["My Project"];
defaultType = project.WorkItemTypes["Bug"];

//...
var newItem = new WorkItem(defaultType)
{
    Title = title
};
newItem.Fields["Assigned To"].Value = assignTo;
newItem.Fields["Repro Steps"].Value = repoSteps;
var validationResult = newItem.Validate();
newItem.Save();

这很好用 . 但升级到VSTS后,我很难获得凭证部分 . 我更改了这一行:

projectCollection = new TfsTeamProjectCollection(url, vssCreds);

对此:

projectCollection = new TfsTeamProjectCollection(url, new VssClientCredentials());

这对我来说很好 . 但是,当我与团队中的其他人分享它时,它最初没有工作,然后开始工作一段时间 . 我猜测与VSTS交互导致他们的凭据被加载,以便它可以工作 . 但我至少有一个人似乎完全无法使其发挥作用 .

那么让它使用VSTS凭证(应该已经存在于VS中)的正确方法是什么?

我看到 VssClientCredentialshttps://msdn.microsoft.com/en-us/library/dn228355(v=vs.120).aspx)的这个重载:

public VssClientCredentials(
    IVssCredentialPrompt credentialPrompt
)

我怀疑这可能是有用的,但我可以't seem to find out if there'在某处内置 IVssCredentialPrompt 的实现,如果不是,如何实现它 .

2 回答

  • 0

    Computer\HKEY_CURRENT_USER\Software\Microsoft\VSCommon\14.0\ClientServices\TokenStorage\VisualStudio\VssApp 删除相关密钥,然后再次进行身份验证 .

    您还可以使用以下代码指定其他Kind(默认为vssApp)和Namespace(默认为VisualStudio):

    var c = new VssClientCredentials();
    c.Storage = new VssClientCredentialStorage(storageKind: "VssApp2", storageNamespace: "VisualStudio");
    projectCollection = new TfsTeamProjectCollection(url, c);
    
  • 1

    由于完全不清楚的原因,从这个答案到完全不同的问题:https://stackoverflow.com/a/40256731/1250301

    似乎产生一个新线程会导致在需要时出现登录提示并修复所有问题 . 所以,如果我这样做:

    Task.Run(() =>
    {
        var url = new Uri(_tfsUrl);
        var cred = new VssClientCredentials();
        projectCollection = new TfsTeamProjectCollection(url, cred);
        workItems = projectCollection.GetService<WorkItemStore>();
    }).Wait();
    
    project = workItems.Projects["Job Posting Data"];
    defaultType = project.WorkItemTypes["Bug"];
    taskType = project.WorkItemTypes["Task"];
    

    然后它工作 . 我不知道为什么它的工作原理,或者为什么这是必要的(起初我认为这可能是一个问题,因为我没有在UI线程中,所以我尝试了 Application.Current.Dispatcher.Invoke 哪个不起作用)但它似乎已经解决了问题 .

相关问题