Welcome to the first of many posts about the Team Foundation Server API. These posts will explore the various namespaces and classes available to programmatically integrate with the components of Team Foundation Server including build, source control, reporting, testing, and work item tracking.
Most examples in this series are written as C# console applications for simplicity but these concepts can be used in Windows Forms, WPF, WCF, ASP.NET, or any other technology or language that can use .NET assemblies.
The example projects will be attached to each post for you to download.
Assumptions
This series of posts assumes that you are familiar with both Visual Studio Team System 2008 and Team Foundation Server 2008 from a user’s and/or administrator’s perspective.
Prerequisites
The first step is to make sure you have all of the prerequisites to follow the examples we go through.
- Visual Studio 2008 Professional or Visual Studio Team System 2008
- Some posts may require a specific edition, but I’ll point that out at the time.
- You can download a 90-day trial of Visual Studio Team System 2008 Team Suite.
- Visual Studio 2008 Team Explorer
- You can install this from the TFC directory of the Visual Studio Team System 2008 or Team Foundation Server 2008 installation media.
- Alternatively, you can download Visual Studio 2008 Team Explorer from Microsoft Downloads.
- Access to a non-production Team Foundation Server 2008
- Some posts may demonstrate APIs which create, modify, or delete data so you should not use them against a production instance of Team Foundation Server without testing them first and fully understanding what they do.
- You can download Visual Studio Team System 2008 Team Foundation Server VPC Image (Trial) from Microsoft Downloads.
- Alternatively, you can download Visual Studio Team System 2008 Team Foundation Server and Team Suite VPC Image (Trial)which contains both Team Foundation Server 2008 and Visual Studio Team System 2008 Team Suite.
- Team Foundation Server 2008 Service Pack 1
- Visual Studio 2008 Service Pack 1
- Visual Studio 2008 SDK
Registered Servers
The first API we’re going to look at is Microsoft.TeamFoundation.Client.RegisteredServers which provides access to the list of Team Foundation Servers that are registered on the client machine. This is the API that is used to populate the Add/Remove Team Foundation Server dialog in Visual Studio:

Since this is our first time using the API we’ll go through this example in more detail than we will for later examples.
- Create a new C# Console Application.
- Add a GAC reference to Microsoft.TeamFoundation.Client version 9.0.0.0.

- Add a using statement to import the Microsoft.TeamFoundation.Client namespace:
using Microsoft.TeamFoundation.Client; - Add the following code, which will simply print the name of each registered server, to the Main method:
foreach (string registeredServerName in RegisteredServers.GetServerNames()) { Console.WriteLine(registeredServerName); } Console.ReadLine();
Rather than retrieving just the server name we can retrieve a TeamFoundationServer object (which we’ll discuss in more detail later in this post) representing the server by calling the GetServers method. This example produces the same output as the previous one:
foreach (TeamFoundationServer registeredServer in RegisteredServers.GetServers()) { Console.WriteLine(registeredServer.Name); }
We can also use the RegisteredServers class to add servers to or remove servers from the list of registered servers as shown in this example:
if (args.Length != 1) { Console.Error.WriteLine("USAGE: AddRegisteredServer.exe <teamFoundationServerUrl>"); return; } string teamFoundationServerUrl = args[0]; TeamFoundationServer teamFoundationServer = TeamFoundationServerFactory.GetServer( teamFoundationServerUrl); RegisteredServers.AddServer(teamFoundationServer);
The AddServer method only accepts a TeamFoundationServer object and not a string so we use the TeamFoundationServerFactory (which we’ll discuss in more detail later in this post) to retrieve one.
TeamFoundationServer vs TeamFoundationServerFactory
The TeamFoundationServer class is one of the most important in the API as it represents a connection to a Team Foundation Server. There are two ways of creating a TeamFoundationServer object:
- Directly creating an instance of the class passing the URL of the Team Foundation Server (or just the hostname) to the constructor:
TeamFoundationServer teamFoundationServer;teamFoundationServer = new TeamFoundationServer("http://T1W102826-TFS2K8:8080");
- Passing the URL or hostname to the static GetServer method on the TeamFoundationServerFactory class:
TeamFoundationServer teamFoundationServer;teamFoundationServer = TeamFoundationServerFactory.GetServer("http://T1W102826-TFS2K8:8080");
So which should you use? The best practice is to use the TeamFoundationServerFactory because it caches the TeamFoundationServer objects based on their URI. This improves performance by reusing connections and avoiding having to re-authenticate (which is particularly important to avoid unnecessary authentication prompts if the user isn’t authenticated automatically). Regardless of whether you request the server by name or by URI, it will be cached based on the case-insensitive URI, but ideally you should use either the name or the URI consistently.
Authenticating
When you call an API that requires authentication it calls the EnsureAuthenticated method on the TeamFoundationServer object to check if the user is already authenticated and start the authentication process if they’re not.
Initially the API tries to authenticate the user using their Windows credentials and throws a TeamFoundationServerUnauthorizedException if this fails. There are three possible ways to avoid this:
- Pass a credential object to the TeamFoundationServer class constructor.
- Pass a credential and credential provider object to the TeamFoundationServer class constructor.
- Pass a credential provider object to the TeamFoundationServerFactor.GetServer method.
If the TeamFoundationServer object has a credential object this will be used instead of the user’s Windows credentials to initially authenticate the user. But if this fails a TeamFoundationServerUnauthorizedException will still be thrown unless a credential provider object has been specified.
If a credential provider has been specified then its GetCredentials method will be called to provide the fallback credentials to use. If authentication using these fallback credentials succeeds then the API calls the credential provider’s NotifyCredentialsAuthenticated method. The API ships a single credential provider, UICredentialsProvider, that displays the standard login dialog and returns a credential based on what is entered:

This example passes a UICredentialsProvider to the TeamFoundationServerFactory.GetServer method. If authentication can be completed automatically using the user’s Windows credentials then it will be, otherwise the user will be prompted to enter their credentials:
TeamFoundationServer teamFoundationServer;
teamFoundationServer = TeamFoundationServerFactory.GetServer(
"http://T1W102826-TFS2K8:8080",
new UICredentialsProvider()
);
teamFoundationServer.EnsureAuthenticated();
Once the user has been authenticated you can retrieve their details through the AuthenticatedUserName, AuthenticatedUserDisplayName, AuthenticatedUserIdentity, or Credentials properties on the TeamFoundationServer object:
Console.WriteLine("{0} = {1}", "AuthenticatedUserName", teamFoundationServer.AuthenticatedUserName); Console.WriteLine("{0} = {1}", "AuthenticatedUserDisplayName", teamFoundationServer.AuthenticatedUserDisplayName);
Conclusion
In this (lengthy) post we’ve looked at how to reference the Team Foundation Server API, work with registered servers, access TeamFoundationServer objects, and authenticate to Team Foundation Server. Stay tuned for the next post where we look at how to access the various components of Team Foundation Server.
Nice article
I’m allready looking forward for the next series.
grtz D
Great article! When is the next post? I’m writing a TFS API right now and could use some pointers.