Getting Changeset objects from associated work items

On internal mailing list, someone asked how to do this, and I thought it's worth sharing.  You can get a Changeset object using its artifact URI (aka link) via VersionControlServer.ArtifactProvider.  Here’s how that would look like, based on modifying code from James Manning’s blog post  Added/changed lines are hightlighted.

using System;
using System.Collections.Generic;

using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using Microsoft.TeamFoundation;
using Microsoft.TeamFoundation.VersionControl.Client;

class ChangesetsFromWorkItems
    static void Main(string[] args)
        if (args.Length < 2)
            Console.Error.Write("Usage: ChangesetsFromWorkItems <server> <workitemid> [workitemid...]");

        TeamFoundationServer server = TeamFoundationServerFactory.GetServer(args[0]);
        WorkItemStore wiStore = (WorkItemStore)server.GetService(typeof(WorkItemStore));
        VersionControlServer vcs = (VersionControlServer) server.GetService(typeof(VersionControlServer));

        int workItemId;
        for (int i = 1; i < args.Length; i++)
            if (!int.TryParse(args[i], out workItemId))
                Console.Error.WriteLine("ignoring unparseable argument {0}", args[i]);

            WorkItem workItem = wiStore.GetWorkItem(workItemId);
            List<Changeset> associatedChangesets = new List<Changeset>();
            foreach (Link link in workItem.Links)
                ExternalLink extLink = link as ExternalLink;
                if (extLink != null)
                    ArtifactId artifact = LinkingUtilities.DecodeUri(extLink.LinkedArtifactUri);
                    if (String.Equals(artifact.ArtifactType, "Changeset", StringComparison.Ordinal))
                        // Convert the artifact URI to Changeset object.
                        associatedChangesets.Add(vcs.ArtifactProvider.GetChangeset(new Uri(extLink.LinkedArtifactUri);

            // Do something with the changesets.  Changes property is an array, each Change
            // has an Item object, each Item object has a path, download method, etc.

Comments (9)

  1. After traveling most of June, and then some in July it&amp;rsquo;s been hard catching back up but almost…

  2. Andy Pham says:

    I was tried your snip code above and get this error when I created new WorkItemStore Object.

    WorkItemStore wiStore = (WorkItemStore)server.GetService(typeof(WorkItemStore));

    Unhandled Exception: Microsoft.TeamFoundation.TeamFoundationServerUnauthorizedException: TF30063: You are not authorized to access server

    Do you have any idea what it causes? I’m using TFS 2008

  3. Buck Hodges says:

    Andy, are you doing this in a web service?  If so, be sure to set WorkItemTrackingCacheRoot in the web.config file.  See for more info.


  4. Manoj says:

    Hi Buck,

    i am new to TFS and its API. I have a requirement in my project where i need to call TFS webservices from java code.. basically I want to get data related to projects, workitems from TFS to my java application to display. I have searched over weba lot and couldn’t find anything except that TeamPrice has built some tool for java to talk to TFS but they havn’t exposed any API or something.

    I would really appreciate if you can point me to some direction where I can get related material or some sample code.



  5. Buck Hodges says:

    Manoj, I see that Brian has followed up with you on this same question you posted on his blog.


  6. FWIW, on a 64-bit system with VS2008, I had to set the target CPU to x86. SecurityExceptions were thrown when trying to load the TFS assemblies with AnyCPU set.

  7. Ravi Khambhati says:

    Tried your code but extLink is always null.

    ExternalLink extLink = link as ExternalLink;

  8. Buck Hodges says:

    Ravi, I admit I haven't tried this code in a very long time. Which version of the TFS client object model are you using? In the debugger, what link types do you have on the work item for a work item that has a changeset link? This code is looking for version control changesets, and this could have changed since this was written.

Skip to main content