Reputation: 21
I want to download a folder from TFS using the TeamFoundation .NET libraries. I'm able to download files individually, but it takes too long. Is there a way to download an entire directory as a ZIP or something similar?
Here is the code I'm currently using.
var client = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(GetToken));
//Connect to TFS server.
var tfs = new TfsConfigurationServer(new Uri("tfs server url"), new NetworkCredential("username", "password", "domain"));
tfs.EnsureAuthenticated();
//Get the default collection id.
var collectionId = new Guid(tfs.CatalogNode.QueryChildren(new[] { CatalogResourceTypes.ProjectCollection }, false, CatalogQueryOptions.None).First().Resource.Properties["InstanceId"]);
//Get the default collection.
var collection = tfs.GetTeamProjectCollection(collectionId);
//Download files.
var server = collection.GetService<VersionControlServer>();
var items = server.GetItems(application.branch_directory + "/" + environment.name, VersionSpec.Latest, RecursionType.Full, DeletedState.NonDeleted, ItemType.Any, true).Items;
foreach (var item in items)
{
var target = Path.Combine(Path.Combine(applicationDirectory, "$"), item.ServerItem.Substring(2));
if (item.ItemType == ItemType.Folder && !Directory.Exists(target))
{
Directory.CreateDirectory(target);
}
else if (item.ItemType == ItemType.File)
{
item.DownloadFile(target);
}
}
Upvotes: 1
Views: 3166
Reputation: 1099
@kernowcode These worked for me:
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Framework.Client;
using Microsoft.TeamFoundation.Framework.Common;
using Microsoft.TeamFoundation.SourceControl.WebApi;
but that is the easy part. Finding the DLL's / packages is another story. I used these but the versions/paths may be wrong on different on your machine
<Reference Include="Microsoft.TeamFoundation.Client">
<HintPath>c:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\TestTools\TeamExplorerClient\Microsoft.TeamFoundation.Client.dll</HintPath>
</Reference>
<Reference Include="Microsoft.TeamFoundation.Common">
<HintPath>c:\Program Files\Common Files\microsoft shared\Team Foundation Server\15.0\Microsoft.TeamFoundation.Common.dll</HintPath>
</Reference>
<Reference Include="Microsoft.TeamFoundation.SourceControl.WebApi, Version=c:, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>c:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer\Microsoft.TeamFoundation.SourceControl.WebApi.dll</HintPath>
</Reference>
<Reference Include="Microsoft.VisualStudio.Services.Common">
<HintPath>c:\Program Files\Common Files\microsoft shared\Team Foundation Server\15.0\Microsoft.VisualStudio.Services.Common.dll</HintPath>
</Reference>
<Reference Include="Microsoft.VisualStudio.Services.WebApi">
<HintPath>c:\Program Files\Common Files\microsoft shared\Team Foundation Server\15.0\Microsoft.VisualStudio.Services.WebApi.dll</HintPath>
</Reference>
Upvotes: 0
Reputation: 21
I found a solution that uses the TeamFoundation .NET libraries.
//Connect to TFS server.
var tfs = new TfsConfigurationServer(new Uri("tfs server"), new VssCredentials(new Microsoft.VisualStudio.Services.Common.WindowsCredential(new NetworkCredential("username", "password", "domain"))));
tfs.EnsureAuthenticated();
//Get the default collection id.
var collectionId = new Guid(tfs.CatalogNode.QueryChildren(new[] { CatalogResourceTypes.ProjectCollection }, false, CatalogQueryOptions.None).First().Resource.Properties["InstanceId"]);
//Get the default collection.
var collection = tfs.GetTeamProjectCollection(collectionId);
//Download files.
var server = collection.GetClient<TfvcHttpClient>();
var zip = Path.GetTempFileName();
var stream = File.Create(zip);
var item = server.GetItemZipAsync(application.branch_directory + "/" + environment.name).Result;
item.CopyTo(stream);
stream.Close();
try
{
ZipFile.ExtractToDirectory(zip, applicationDirectory);
}
catch
{
throw new Exception("Unable to unzip the file: " + zip);
}
Upvotes: 1
Reputation: 51183
You could use Rest API--Get a specific version to do this, and use httpclient to call Rest API.
You can indicate which version to get when you get a file, zip a folder, or get item metadata.
This format should be used for certain files (like web.config) that are not accessible by using the path as part of the URL due to the default ASP .NET protection. The response is a stream (application/octet-stream) that contains the contents of the file.
http://fabrikam-fiber-inc.visualstudio.com/defaultcollection/_apis/tfvc/items?path=$/fabrikam-fiber-tfvc/website/website/web.config&api-version={version}
You need to zip files when you use the path as query parameter.
To get an entire folder, you can zip it and download it with the Rest Api with following format:
[Get] https://xxx/defaultcollection/_apis/tfvc/items?path=<Folder Path>&api-version=1.0
And add following in the request header: Accept: application/zip
A code sample for your reference: How to stream zip file from TFS api
Upvotes: 1