Recevez les plus récents des services d'équipe Visual Studio à l'aide des informations d'identification de transmission / de connexion de ligne de commande avec TF.EXE

StackOverflow https://stackoverflow.com//questions/21005274

Question

Quelqu'un a-t-il eu du succès de recevoir le dernier code source des services d'équipe Visual Studio (anciennement Visual Studio Online, Service de la Fondation de l'équipe) Serveur de contrôle de la version à l'aide de la ligne de commande et de transmettre des informations d'identification par programme?

-J'ai découvert que vous ne pouvez pas utiliser les informations d'identification de l'ID Windows que vous utilisez pour vous connecter à Equipe Explorer ou au site Web de la VSO dans la ligne de commande. Vous devez créer des informations d'identification alternatives pour le profil d'utilisateur dans les services d'équipe.

-J'ai découvert que si vous omettez la boîte de connexion / connexion dans Tf.exe, la boîte de dialogue de connexion des services à l'équipe apparaît et vous demande de saisir vos informations d'identification de Windows ID (à moins qu'ils ne soient déjà mis en cache dans votre explorateur d'équipe ou votre studio Visual ( ou même éventuellement des caches de transmission de navigateurs et Windows)

-J'ai découvert que les travaux d'identification alternative utilisant la version Java de Tf.exe - Equipe Explorer partout Client de ligne de commande (TEE CLC). Tee CLC utilise effectivement les informations d'identification / connexion que vous transmettez et vous permet de vous connecter. La même chose ne semble pas être possible avec le TF.EXE dans C: \ Fichiers du programme (X86) \ Microsoft Visual Studio 12.0 \ Common7 \ Ide \ mais l'installation de Java sur cet environnement de construction est contre la politique. Donc, la tee CLC n'est pas une option viable.

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

La commande ci-dessus ignore simplement les informations d'identification / connexion si vous avez les informations d'identification de l'ID Windows Cached ou renvoie le message d'erreur TF30063: vous n'êtes pas autorisé à accéder à myAccount.visualstudio.com (ce qui n'est pas vrai, car les informations d'identification fonctionnent. avec le client Java)

Y a-t-il d'autres alternatives qui ne nécessitent pas d'installer Java?

Était-ce utile?

La solution

J'ai une réponse de Microsoft Support: Les crédits AA pour VSO ne fonctionnent pas avec TF.EXE pour le moment.TEE CLC ou utiliser le code de modèle d'objet sont les seules alternatives actuellement.Nous cherchons à faire cela à l'avenir.

Le code de modèle d'objet fait référence à la microsoft.teamfoundation.versioncontrol.client Espace de noms dans la DLL par le même nom.J'ai fini par écrire une application de console de C # rapide pour télécharger le dernier code sans installer Java.Un avantage supplémentaire de cette approche est qu'il ne nécessite pas de créer un espace de travail perméable.

Si vous utilisez le code ci-dessous pour créer un exécutable appelé tfsget.exe, on peut appeler à partir de la ligne de commande comme celle-ci:

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

Et j'ai ajouté un interrupteur silencieux pour supprimer la liste de chaque fichier pouvant être utilisé comme:

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

Voici le code, j'espère que cela vous aide jusqu'à ce que MS met à jour 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;
        }
    }
}

Autres conseils

Voici un extrait en utilisant. Bibliothèques NET TFS & POWERSHELL L'intégration qui a fonctionné pour nous - tf.exe ne joue pas bien avec VSOautorisation.Curieux si quelqu'un d'autre a du succès en utilisant cet itinéraire.Nous utilisons ADFS , le processus PowerShell est donc exécuté en tant qu'utilisateur que nous souhaitons s'authentifier.

tf obtenir le dernier espace de travail.ps1

$path = "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\ReferenceAssemblies\v2.0" 
Add-Type -Path "$path\Microsoft.TeamFoundation.Client.dll"
Add-Type -Path "$path\Microsoft.TeamFoundation.VersionControl.Client.dll"
Add-Type -Path "$path\Microsoft.TeamFoundation.VersionControl.Common.dll"

$collection = "https://mycorp.visualstudio.com/defaultcollection"
$tpc = [Microsoft.TeamFoundation.Client.TfsTeamProjectCollectionFactory]::GetTeamProjectCollection($collection)
$vc = $tpc.GetService([Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer])

# retrieve workspace by path 
$projectPath = "$/MyApp/MyBranch"
$workspacePath = "C:\Projects\MyApp\MyBranch"
$workspace = $vc.GetWorkspace($workspacePath)


# get full download every time (tf get /force /recursive)
function DownloadAllFiles([Microsoft.TeamFoundation.VersionControl.Client.Workspace] $workspace, [string] $projectPath) {     
    $recursionType = [Microsoft.TeamFoundation.VersionControl.Client.RecursionType]::Full
    $versionSpec = [Microsoft.TeamFoundation.VersionControl.Client.LatestVersionSpec]::Instance
    $itemSpec = new-object Microsoft.TeamFoundation.VersionControl.Client.ItemSpec($projectPath,$recursionType)
    $getRequest = New-Object Microsoft.TeamFoundation.VersionControl.Client.GetRequest($projectPath,$recursionType,$versionSpec)
    $getOptions = [Microsoft.TeamFoundation.VersionControl.Client.GetOptions]::GetAll -bor [Microsoft.TeamFoundation.VersionControl.Client.GetOptions]::Overwrite 
    $workpaceStatus = $workspace.Get($getRequest, $getOptions)
    write-output $workpaceStatus 
}

# get delta download - changes only (retrieves all mapped items)
function DownloadWorkspaceUpdates([Microsoft.TeamFoundation.VersionControl.Client.Workspace] $workspace) {
    $workpaceStatus = $workspace.Get()
    write-output $workpaceStatus 
}

# get delta download - changes only (retrieves specific mapped items)
function DownloadWorkspaceUpdates([Microsoft.TeamFoundation.VersionControl.Client.Workspace] $workspace, [string] $projectPath) {
    $recursionType = [Microsoft.TeamFoundation.VersionControl.Client.RecursionType]::Full
    $versionSpec = [Microsoft.TeamFoundation.VersionControl.Client.LatestVersionSpec]::Instance
    $itemSpec = new-object Microsoft.TeamFoundation.VersionControl.Client.ItemSpec($projectPath,$recursionType)
    $getRequest = New-Object Microsoft.TeamFoundation.VersionControl.Client.GetRequest($projectPath,$recursionType,$versionSpec)
    $getOptions = [Microsoft.TeamFoundation.VersionControl.Client.GetOptions]::Overwrite 
    $workpaceStatus = $workspace.Get($getRequest, $getOptions)
    write-output $workpaceStatus 
}

# force latest download (slower)
DownloadAllFiles -workspace $workspace -projectPath $projectPath

# download deltas (fast), all mappings
DownloadWorkspaceUpdates -workspace $workspace

# download deltas (fast), specific mapping
DownloadWorkspaceUpdates -workspace $workspace -projectPath $projectPath

Ceci pourrait facilement être étendu pour prendre en charge TfsClientCredentials ( i.e. ALTERNATE ACCÈS DEVENTIONS ).Je préfère l'approche PowerShell car elle ne nécessite pas de compilation ni d'extra extra de copier autour de vous.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top