Click here to Skip to main content
15,890,438 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
I need a way to download a source code from Visual Studio Team Services, basically I need a solution zipped, just as you can download it manually when I am on VSTS site.

What I have tried:

I've been through VSTS API reference: Projects | REST API Reference for Visual Studio Team Services and Team Foundation Server[^] but unfortunately I am failing to find what I need.

Workaround:

1. Issue a POST and retrieve items batch that will return a list of all files from Main branch
Thanks.
2. Iterate through list and download files one by one

but I'd really thought there will be an option to download a zip of files in folder or in a branch.
Posted
Updated 23-Mar-17 4:13am
v3
Comments
Member 14092117 17-Dec-18 4:55am    
can you provide the solution for "How to upload project folder to VSTS programatically" means on check in it should be reflect in VSTS repository

1 solution

I finally managed to solve this using .NET Client Libraries for VSTS

I use these 2 packages: Microsoft.TeamFoundationServer.Client and Microsoft.VisualStudio.Services.Client, they as one could guess are wrappers around the VSTS REST API functionalities.

In order to retrieve zipped folder content from TFVC I am using method:
C#
Microsoft.TeamFoundation.SourceControl.WebApi.TfvcHttpClient.GetItemsBatchZipAsync(TfvcItemRequestData itemRequestData, Guid project)


Here is a complete code example:

C#
using System;
using System.IO;
using Microsoft.TeamFoundation.Core.WebApi;
using Microsoft.TeamFoundation.SourceControl.WebApi;
using Microsoft.VisualStudio.Services.Common;

namespace BuildAndDeploy.GetSourceTest
{
    class Program
    {
        static void Main(string[] args)
        {
            var path = "$/myproject/Main";
            var personalAccessToken = "***************************";
            var uri = new Uri("https://myproject.visualstudio.com");

            var credentials = new VssBasicCredential("", personalAccessToken);

            // You can use hard coded ProjectId or there is probably some better way to not always call this, but at the moment it's fine like this
            Guid projectGuid = GetProjectId(uri, credentials);

            using (var client = new TfvcHttpClient(uri, credentials))
            {
                var itemRequestData = Create(path);

                Stream item = client.GetItemsBatchZipAsync(itemRequestData, projectGuid).Result;

                SaveZippedContent(@"C:\Output\main.zip", item);
            }
        }

        private static Guid GetProjectId(Uri uri, VssBasicCredential credentials)
        {
            using (var client = new ProjectHttpClient(uri, credentials))
            {
                return client.GetProject("MoveDesk").Result.Id;
            }
        }

        private static TfvcItemRequestData Create(string folderPath)
        {
            return new TfvcItemRequestData
            {
                IncludeContentMetadata = true,
                IncludeLinks = true,
                ItemDescriptors =
                    new[]
                    {
                        new TfvcItemDescriptor
                        {
                            Path = folderPath,
                            RecursionLevel = VersionControlRecursionType.Full
                        }
                    }
            };
        }

        private static void SaveZippedContent(string saveToPath, Stream content)
        {
            var buffer = new byte[1024];

            try
            {
                using (var output = new FileStream(saveToPath, FileMode.Create))
                {
                    int readBytes;
                    while ((readBytes = content.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        output.Write(buffer, 0, readBytes);
                    }
                }
            }
            finally
            {
                content.Dispose();
            }
        }
    }
}
 
Share this answer
 
Comments
alsamflux 16-Jan-18 12:55pm    
Getting a WebException on the read operation "The request was aborted: The request was canceled." I'm using larger buffers, and getting further.
Vihar Jadhav 4-Feb-21 9:21am    
System.AggregateException
HResult=0x80131500
Message=One or more errors occurred. (The SSL connection could not be established, see inner exception.)
Source=System.Private.CoreLib
StackTrace:
at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
at System.Threading.Tasks.Task`1.get_Result()
at ConsoleApp4.Program.GetProjectId(Uri uri, VssBasicCredential credentials) in \ConsoleApp4\Program.cs:line 28
at ConsoleApp4.Program.Main(String[] args) in \repos\ConsoleApp4\Program.cs:line 19

This exception was originally thrown at this call stack:
[External Code]

Inner Exception 1:
HttpRequestException: The SSL connection could not be established, see inner exception.

Inner Exception 2:
IOException: The handshake failed due to an unexpected packet format.
Vihar Jadhav 4-Feb-21 9:22am    
Throw an above error.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900