Agil

Programmatically Retrieve Files from TFS

Posted on

If you use Team Foundation Server (TFS) for version control, you can do a lot of customization using Microsoft’s API. For example, you can search for specific types of bugs, build your own custom check-in policies, and more. Try this link for some ideas on what you can do. You could be a hero and improve your team’s process; maybe this kind of project will be your ticket into management! Assuming you use TFS for Continuous Integration, Agile tasks, etc. (And also assuming you are interested in that management thing :-))

FYI, I previously posted a blog article on using Power Shell to query TFS, in case you don’t need as much capability as provided by writing code. For this post, I will explain some code that:

  1. Lists all the projects in your TFS repository
  2. Lists all the files for your selected project
  3. Retrieves the contents for your selected file, without requiring a check-out!
My code opens the TFS repository, gets the projects, then gets the files for the selected project. I can retrieve the selcted file contents without a check-out.
My code opens the TFS repository, gets the projects, then gets the files for the selected project. I can retrieve the selcted file contents without a check-out.

I actually use TFS at work to perform analysis on our project, specifically to map database object usage within our massive project. The project I describe in this post was part of my proof-of-concept. Programatically accessing TFS is nice because 1) I don’t need to check-out all the code and 2) I can inspect each file’s check-in date on each file and avoid parsing it if I hasn’t changed since last time, 3) my web-based UI does not need to open any local files, which would be a problem.

If interested, this article should be a big help for you. Because most of the other blog posts seem to deal with obsolete versions of TFS. My version works with Visual Studio 2013, and I hope Microsoft doesn’t make any additional breaking changes when the new Visual Studio comes out!

You may also find this helpful because the Microsoft documentation isn’t that good. I’m doing some pretty basic stuff, but it took me almost two days of research to figure-out how to do it. It was particularly hard to discover how to get file contents without performing a check-out.

Get the API

At home, I already have the API (I didn’t specifically download it), but at work, I needed to perform a special download from here: http://www.microsoft.com/en-gb/download/details.aspx?id=40776. To check if you need to download, see if you have this file (and others in the same folder):

  • C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\ReferenceAssemblies\v2.0\Microsoft.TeamFoundation.Client.dll

If you have the Team Foundation dlls in that folder, you probably don’t need to download. If you download my code sample, you can see all the other dlls you need for this project.

Explain the Code!

The code for this project is pretty short, just 71 lines (including all my ‘using-statements, try-catch blocks, etc.). Basically, I just have code for three button-click events.

Code to Get the Project List

Fetching the project list is easy, just open a TeamProjectCollectionServer, use it to get a VersionControlServer, then use that object to get a list of all projects, which I have bound to my grid.

private void btnGetProjects_Click(object sender, RoutedEventArgs e) {
    try {
        //Use the URL provided by user
        Uri tfsUri = new Uri(txtRepositoryURL.Text);
        TfsTeamProjectCollection server = TfsTeamProjectCollectionFactory
                                        .GetTeamProjectCollection(tfsUri);
        VersionControlServer myVersion = server.GetService(
                    typeof(VersionControlServer)) as VersionControlServer;
        TeamProject[] allProjects = myVersion.GetAllTeamProjects(true);

        //We have the list of projects, display in the grid
        grdProjectList.ItemsSource = allProjects;
    } catch (Exception ex) {
        MessageBox.Show(ex.Message);
    }
}

Now Get the List of Files for the Selected Project

Getting the files is easy; use the version control server from above to perform a GetItems operation on the project which user has selected in the grid and display the results in the grid.

TeamProject selectedPrj = grdProjectList.SelectedItem as TeamProject;
ItemSet items = myVersion.GetItems(selectedPrj.ServerItem, RecursionType.Full);
grdFileList.ItemsSource = items.Items;

Finally, Get the File Contents

Basically, we’re going to perform a DownloadFile operation on the selected file and open it with a stream. Again, using the VersionControlServer from the first step.

Item theItem = grdFileList.SelectedItem as Item;
using (StreamReader sr = new StreamReader(theItem.DownloadFile())) {
    txtContent.Text = sr.ReadToEnd();
}

Summary

This is just a demo, you can do a lot more with the TFS API. It made life a lot easier for my current project, for reasons referenced above. Get the code here.