Technorati Tags: Team Foundation Server 2010,TFS API,TFS SDK 2010,TFS ALM
Download a working solution
Demo Solution Download
I have seen a lot of questions in the community lately on how to use the TFS API to get a list of Team Projects, Iterations & Area Paths in that project, get a list of queries, see the wiql and execute the query programmatically. I will show you the steps on just how to do this. PDTZG6PKJYNE
1. Connect to TFS Programmatically
I have a blog post that shows you from where to download the VS 2010 SP1 SDK and how to connect to TFS programmatically.
public
static TfsTeamProjectCollection ConnectToTfsProgrammatically() {
return TfsTeamProjectCollectionFactory.GetTeamProjectCollection(
new Uri("TfsUrl"));
}
2. Get All Team Projects
I will use the ‘WorkItemStore’ service to retrieve the team projects
// Get All Team Projects
public
static ProjectCollection GetAllTeamProjects() {
var tfs = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(
new Uri("TfsUrl"));
var wiStore = tfs.GetService<WorkItemStore>();
return wiStore.Projects;
}
Now that you have the ProjectCollection available, you can loop through and get details of all projects in that collection.
foreach (Project project in projCollections) {
lstTeamProjects.Items.Add(project.Name);
}
If you were just interested in one project and wanted to get details of only that one project you could use the ‘TryGetTeamProject(string)’ method, this is available with in the ‘VersionControlServer’ service
// Get project by name
public
static TeamProject GetProjectDetailsByName(string projectName) {
var tfs = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(
new Uri("TfsUrl"));
var vsStore = tfs.GetService<VersionControlServer>();
return vsStore.TryGetTeamProject(projectName);
}
3. Get All Iterations in the Team Project
Now that we have the Project object available, it is very easy to get all the iterations in that project. You need to be careful though, the iterations could have child nodes. The code snippet below lets you get the iterations and sub iterations (child nodes).
// Iterations
foreach (Node node in project.IterationRootNodes) {
lstIterations.Items.Add(node.Name);
foreach (Node item in node.ChildNodes) {
lstIterations.Items.Add(item.Name);
}
}
4. Get All Area Paths in the Team Project
It is very simple to get all area paths in the project. You need to be careful though, the area paths could have child nodes. The code snippet below lets you get the area paths and sub area paths (child nodes).
// Area Path
foreach (Node area in project.AreaRootNodes) {
lstAreaPath.Items.Add(area.Name);
foreach (Node item in area.ChildNodes) {
lstAreaPath.Items.Add(item.Name);
}
}
5. Get All Queries in the Team Project
It is very simple to get all queries in the project.
// Queries
foreach (StoredQuery qi in detailsOfTheSelectedProject.StoredQueries) {
lstQueries.Items.Add(qi.Name);
}
You could also get the Query Text, Query Scope, Query Guid from here.
// Queries
foreach (StoredQuery qi in project.StoredQueries) {
Debug.Write(
String.Format("Query Text: {0}{1}", qi.QueryText, Environment.NewLine));
Debug.Write(
String.Format("Query Scope: {0}{1}", qi.QueryScope, Environment.NewLine));
Debug.Write(
String.Format("Query Guid: {0}{1}", qi.QueryGuid, Environment.NewLine));
}
Or if you knew the GUID of the query, you could use the GUID to get the query
var query = project.Store.GetQueryDefinition(
new Guid("ed359a39-9aa2-4185-9121-da0a407f22e5"));
If you wanted to see the Access Control List associated to the query
var queryACL =
detailsOfTheSelectedProject.Store
.GetQueryDefinition(new Guid("ed359a39-9aa2-4185-9121-da0a407f22e5"))
.AccessControlList;
Just before moving a head, if you wanted to see if the query ‘Is Personal’ or team query. The property ‘IsPersonal’ would reveal this,
var queryIsPersonal = detailsOfTheSelectedProject.Store.GetQueryDefinition(new Guid("ed359a39-9aa2-4185-9121-da0a407f22e5")).IsPersonal;
6. Get the WIQL of the query
The queries use the ‘Work Item Query Language’ you can read more about the WIQL on msdn library. If you wanted to see the query text then there are two ways of doing this,
1. Using the TFS API
// Query Text
foreach (StoredQuery qi in project.StoredQueries) {
lstQueries.Items.Add(qi.QueryText);
}
2. Without the TFS API
- Create a new query in TFS and click on save
Save it on the location filesystem rather than on the server
Change the extension from *.wiq to *.txt
7. Execute the TFS Query Programmatically
Now that we have the query text we will convert it in to TFS query object,
// Convert any parameters before converting the string to Query object, other
// wise will raise exception
tbQueryDetails.Text =
project.Store.GetQueryDefinition(qi.QueryGuid)
.QueryText.Replace(
"@project",
String.Format("'{0}'", detailsOfTheSelectedProject.Name));
var query = new Query(wiStore, tbQueryDetails.Text);
Note that the query can either be a flat query or a linked query. if you try and execute a linked query using a flat query execution method you will get the following exception,
TF248021: You have specified a query string that is not valid when you use the query method for a flat list of work items. You cannot specify a parameterized query or a query string for linked work items with the query method you specified.
So, best to check the property ‘IsLinkedQuery’ and verify what type of query it is. The linked query will need to be executed using the ‘query.RunLinkedQuery’ method.
if (query.IsLinkQuery) {
var queryResults = query.RunLinkQuery();
foreach (WorkItemLinkInfo item in queryResults) {
lstWorkItems.Items.Add(
detailsOfTheSelectedProject.Store.GetWorkItem(item.TargetId).Id);
}
} else {
var queryResults = query.RunQuery();
foreach (WorkItem item in queryResults) {
lstWorkItems.Items.Add(item.Id);
}
}