使用命令行通过 TF.exe 传递/登录凭据从 Visual Studio Team Services 获取最新信息 [英] Get latest from Visual Studio Team Services using Command Line passing /login credentials with TF.exe

查看:16
本文介绍了使用命令行通过 TF.exe 传递/登录凭据从 Visual Studio Team Services 获取最新信息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有人成功地使用命令行并以编程方式传入凭据从 Visual Studio Team Services(以前称为 Visual Studio Online、Team Foundation Service)版本控制服务器获取最新源代码?

Has anyone had success getting latest source code from the Visual Studio Team Services (formerly Visual Studio Online, Team Foundation Service) Version Control Server using the command line and passing in credentials programmatically?

-我发现您无法在命令行中使用用于登录团队资源管理器或 VSO 网站的 Windows ID 凭据.您需要为 Team Services 中的用户配置文件创建备用凭据.

-I have discovered that you can't use the Windows ID credentials that you use to login to Team Explorer or the VSO website in the command line. You need to create Alternate Credentials for the user profile in Team Services.

-我发现如果您在 tf.exe 中省略/login,则会出现 Team Services 登录对话框并要求您输入您的 Windows ID 凭据(除非它们已缓存在您的 Team Explorer 或 Visual Studio 中(甚至可能是浏览器和 Windows 凭据缓存)

-I have found out that if you omit the /login in tf.exe, the Team Services login dialog appears and asks you to type in your Windows ID credentials (unless they are already cached in your Team Explorer or Visual Studio (or even possibly Browser and Windows Credential Caches)

-我发现备用凭证可以使用 Java 版本的 tf.exe - Team Explorer Everywhere 命令行客户端 (TEE CLC).TEE CLC 实际上使用您传入的/login 凭据并让您连接.C:Program Files (x86)Microsoft Visual Studio 12.0Common7IDE 中的 TF.EXE 似乎无法实现同样的事情,但在此构建环境中安装 JAVA 是违反政策的.所以 TEE CLC 不是一个可行的选择.

-I have found out that the alternate credential work Using the Java version of tf.exe - Team Explorer Everywhere Command Line Client (TEE CLC). TEE CLC actually uses the /login credentials that you pass in and lets you connect. The same thing does NOT seem to be possible with the TF.EXE in C:Program Files (x86)Microsoft Visual Studio 12.0Common7IDE BUT INSTALLING JAVA ON THIS BUILD ENVIRONMENT IS AGAINST POLICY. So the TEE CLC is NOT a viable option.

tf get $/MyProj /collection:https://myaccount.visualstudio.com/DefaultCollection /login:user:pass 

如果您缓存了 Windows ID 凭据,则上述命令将简单地忽略/login 凭据,或者它返回错误消息 TF30063:您无权访问 myaccount.visualstudio.com(这不是真的,因为凭据确实有效)使用 Java 客户端)

the above command simply ignores the /login credentials if you have the Windows ID credentials cached or it returns the error message TF30063: You are not authorized to access myaccount.visualstudio.com (which is not true, because the credentials DO work with the Java client)

是否有其他不需要安装 Java 的替代方案?

Are there any other alternatives that do not require installing Java?

推荐答案

我从 Microsoft 支持那里得到了答复:用于 VSO 的 AA Creds 目前不适用于 TF.EXE.TEE CLC 或使用对象模型代码是目前唯一的选择.我们正在考虑在未来这样做.

I got an answer from Microsoft Support: AA Creds for VSO do not work with TF.EXE at this time. TEE CLC or using object model code are the only alternatives currently. We are looking at doing this in the future.

对象模型代码引用 dll 中同名的 Microsoft.TeamFoundation.VersionControl.Client 命名空间.我最终编写了一个快速的 C# 控制台应用程序来下载最新的代码,而无需安装 Java.这种方法的另一个好处是它不需要创建一次性工作区.

Object Model Code refers to the Microsoft.TeamFoundation.VersionControl.Client Namespace in the dll by the same name. I ended up writing a quick C# console app to download the latest code without installing Java. An added benefit of this approach is that it does not require creating a throwaway Workspace.

如果您使用下面的代码创建一个名为 tfsget.exe 的可执行文件,则可以像这样从命令行调用它:

if you use the code below to create an executable called tfsget.exe it can be called from the command line like this:

tfsget https://myvso.visualstudio.com/DefaultCollection $/MyProj/Folder c:Projects login password

并且我添加了一个静默开关来禁止列出可以使用的每个文件,例如:

and I added a silent switch to suppress listing each file that can be used like:

tfsget https://myvso.visualstudio.com/DefaultCollection $/MyProj/Folder c:Projects login password silent

这是代码,希望这有助于直到 MS 更新 TF.exe

here's the code, hope this helps until MS updates TF.exe

using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;

namespace TfsGet
{
    class Program
    {
        static void Main(string[] args)
        {
            var tfsParams = TfsDownloadParams.Create(args);

            var tpc = new TfsTeamProjectCollection(new Uri(tfsParams.ServerUrl), tfsParams.Credentials);

            CheckAccess(tpc, tfsParams);

            Download(tpc, tfsParams);

        }

        private static void CheckAccess(TfsTeamProjectCollection tpc, TfsDownloadParams tfsParams)
        {
            try
            {
                tpc.Authenticate();
            }
            catch
            {
                Console.WriteLine("TFS Authentication Failed");
                Console.WriteLine("Server Url:{0}", tfsParams.ServerUrl);
                Console.WriteLine("Project Path:{0}", tfsParams.ServerProjectPath);
                Console.WriteLine("Target Path:{0}", tfsParams.TargetPath);
                Environment.Exit(1);
            }
        }

        static void Download(TfsTeamProjectCollection tpc, TfsDownloadParams tfsParams)
        {   
            var versionControl = tpc.GetService<VersionControlServer>();
            // Listen for the Source Control events.
            versionControl.NonFatalError += Program.OnNonFatalError;

            var files = versionControl.GetItems(tfsParams.ServerProjectPath, VersionSpec.Latest, RecursionType.Full);
            foreach (Item item in files.Items)
            {
                var localFilePath = GetLocalFilePath(tfsParams, item);

                switch (item.ItemType)
                {
                    case ItemType.Any:
                        throw new ArgumentOutOfRangeException("ItemType.Any - not sure what to do with this");
                    case ItemType.File:
                        if (!tfsParams.Silent) Console.WriteLine("Getting: '{0}'", localFilePath);
                        item.DownloadFile(localFilePath);
                        break;
                    case ItemType.Folder:
                        if (!tfsParams.Silent) Console.WriteLine("Creating Directory: {0}", localFilePath);
                        Directory.CreateDirectory(localFilePath);
                        break;
                }
            }
        }

        private static string GetLocalFilePath(TfsDownloadParams tfsParams, Item item)
        {
            var projectPath = tfsParams.ServerProjectPath;
            var pathExcludingLastFolder = projectPath.Substring(0, projectPath.LastIndexOf('/')+1);
            string relativePath = item.ServerItem.Replace(pathExcludingLastFolder, "");
            var localFilePath = Path.Combine(tfsParams.TargetPath, relativePath);
            return localFilePath;
        }

        internal static void OnNonFatalError(Object sender, ExceptionEventArgs e)
        {
            var message = e.Exception != null ? e.Exception.Message : e.Failure.Message;
            Console.Error.WriteLine("Exception: " + message);
        }
    }

    public class TfsDownloadParams
    {
        public string ServerUrl { get; set; }
        public string ServerProjectPath { get; set; }
        public string TargetPath { get; set; }
        public TfsClientCredentials Credentials { get; set; }
        public bool Silent { get; set; }

        public static TfsDownloadParams Create(IList<string> args)
        {
            if (args.Count < 5)
            {
                Console.WriteLine("Please supply 5 or 6 parameters: tfsServerUrl serverProjectPath targetPath userName password [silent]");
                Console.WriteLine("The optional 6th 'silent' parameter will suppress listing each file downloaded");
                Console.WriteLine(@"Ex: tfsget ""https://myvso.visualstudio.com/DefaultCollection"" ""$/MyProject/ProjectSubfolder"" ""c:Projects Folder"", user, password ");

                Environment.Exit(1);
            }

            var tfsServerUrl = args[0]; //"https://myvso.visualstudio.com/DefaultCollection";
            var serverProjectPath = args[1]; // "$/MyProject/Folder Path";
            var targetPath = args[2]; // @"c:Projects";
            var userName = args[3]; //"login";
            var password = args[4]; //"passsword";
            var silentFlag = args.Count >= 6 && (args[5].ToLower() == "silent"); //"silent";
            var tfsCredentials = GetTfsCredentials(userName, password);

            var tfsParams = new TfsDownloadParams
            {
                ServerUrl = tfsServerUrl,
                ServerProjectPath = serverProjectPath,
                TargetPath = targetPath,
                Credentials = tfsCredentials,
                Silent = silentFlag,
            };
            return tfsParams;
        }

        private static TfsClientCredentials GetTfsCredentials(string userName, string password)
        {
            var networkCreds= new NetworkCredential(userName, password);
            var basicCreds = new BasicAuthCredential(networkCreds);
            var tfsCreds = new TfsClientCredentials(basicCreds)
            {
                AllowInteractive = false
            };
            return tfsCreds;
        }
    }
}

这篇关于使用命令行通过 TF.exe 传递/登录凭据从 Visual Studio Team Services 获取最新信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆