Buck Hodges

Visual Studio Online, Team Foundation Server, MSDN

March, 2012

  • Buck Hodges

    Team Foundation Version Control client API example for TFS 2010 and newer


    Update 8/19/15: Extending Version Control is another good source of examples to get you started, as is Extending Work Item Tracking if you are looking for Work Item Tracking API examples.

    Update 8/14/15: With VS/TFS 2015, we’ve begun making the client object model available as a redistributable NuGet package.

    Over six years ago, I posted a sample on how to use the version control API.  The API changed in TFS 2010, but I hadn’t updated the sample.  Here is a version that works with 2010 and newer and is a little less aggressive on clean up in the finally block.

    This is a really simple example that uses the version control API.  It shows how to create a workspace, pend changes, check in those changes, and hook up some important event listeners.  This sample doesn't do anything useful, but it should get you going.

    You have to supply a Team Project as an argument.

    The only real difference in this version is that it uses the TeamFoundationServer constructor (in beta 3, you were forced to use the factory class).

    You'll need to add references to the following TFS assemblies to compile this example.


    Code Snippet
    1. using System;
    2. using System.Collections.Generic;
    3. using System.Diagnostics;
    4. using System.IO;
    5. using System.Text;
    6. using Microsoft.TeamFoundation.Client;
    7. using Microsoft.TeamFoundation.VersionControl.Client;
    9. namespace BasicSccExample
    10. {
    11.     class Example
    12.     {
    13.         static void Main(string[] args)
    14.         {
    15.             // Verify that we have the arguments we require.
    16.             if (args.Length < 2)
    17.             {
    18.                 String appName = Path.GetFileName(Process.GetCurrentProcess().MainModule.FileName);
    19.                 Console.Error.WriteLine("Usage: {0} collectionURL teamProjectPath", appName);
    20.                 Console.Error.WriteLine("Example: {0} http://tfsserver:8080/tfs/DefaultCollection $/MyProject", appName);
    21.                 Environment.Exit(1);
    22.             }
    24.             // Get a reference to our Team Foundation Server.
    25.             TfsTeamProjectCollection tpc = new TfsTeamProjectCollection(new Uri(args[0]));
    27.             // Get a reference to Version Control.
    28.             VersionControlServer versionControl = tpc.GetService<VersionControlServer>();
    30.             // Listen for the Source Control events.
    31.             versionControl.NonFatalError += Example.OnNonFatalError;
    32.             versionControl.Getting += Example.OnGetting;
    33.             versionControl.BeforeCheckinPendingChange += Example.OnBeforeCheckinPendingChange;
    34.             versionControl.NewPendingChange += Example.OnNewPendingChange;
    36.             // Create a workspace.
    37.             Workspace workspace = versionControl.CreateWorkspace("BasicSccExample", versionControl.AuthorizedUser);
    39.             String topDir = null;
    41.             try
    42.             {
    43.                 String localDir = @"c:\temp\BasicSccExample";
    44.                 Console.WriteLine("\r\n--- Create a mapping: {0} -> {1}", args[1], localDir);
    45.                 workspace.Map(args[1], localDir);
    47.                 Console.WriteLine("\r\n--- Get the files from the repository.\r\n");
    48.                 workspace.Get();
    50.                 Console.WriteLine("\r\n--- Create a file.");
    51.                 topDir = Path.Combine(workspace.Folders[0].LocalItem, "sub");
    52.                 Directory.CreateDirectory(topDir);
    53.                 String fileName = Path.Combine(topDir, "basic.cs");
    54.                 using (StreamWriter sw = new StreamWriter(fileName))
    55.                 {
    56.                     sw.WriteLine("revision 1 of basic.cs");
    57.                 }
    59.                 Console.WriteLine("\r\n--- Now add everything.\r\n");
    60.                 workspace.PendAdd(topDir, true);
    62.                 Console.WriteLine("\r\n--- Show our pending changes.\r\n");
    63.                 PendingChange[] pendingChanges = workspace.GetPendingChanges();
    64.                 Console.WriteLine("  Your current pending changes:");
    65.                 foreach (PendingChange pendingChange in pendingChanges)
    66.                 {
    67.                     Console.WriteLine("    path: " + pendingChange.LocalItem +
    68.                                       ", change: " + PendingChange.GetLocalizedStringForChangeType(pendingChange.ChangeType));
    69.                 }
    71.                 Console.WriteLine("\r\n--- Checkin the items we added.\r\n");
    72.                 int changesetNumber = workspace.CheckIn(pendingChanges, "Sample changes");
    73.                 Console.WriteLine("  Checked in changeset " + changesetNumber);
    75.                 Console.WriteLine("\r\n--- Checkout and modify the file.\r\n");
    76.                 workspace.PendEdit(fileName);
    77.                 using (StreamWriter sw = new StreamWriter(fileName))
    78.                 {
    79.                     sw.WriteLine("revision 2 of basic.cs");
    80.                 }
    82.                 Console.WriteLine("\r\n--- Get the pending change and check in the new revision.\r\n");
    83.                 pendingChanges = workspace.GetPendingChanges();
    84.                 changesetNumber = workspace.CheckIn(pendingChanges, "Modified basic.cs");
    85.                 Console.WriteLine("  Checked in changeset " + changesetNumber);
    86.             }
    87.             finally
    88.             {
    89.                 if (topDir != null)
    90.                 {
    91.                     Console.WriteLine("\r\n--- Delete all of the items under the test project.\r\n");
    92.                     workspace.PendDelete(topDir, RecursionType.Full);
    93.                     PendingChange[] pendingChanges = workspace.GetPendingChanges();
    94.                     if (pendingChanges.Length > 0)
    95.                     {
    96.                         workspace.CheckIn(pendingChanges, "Clean up!");
    97.                     }
    99.                     Console.WriteLine("\r\n--- Delete the workspace.");
    100.                     workspace.Delete();
    101.                 }
    102.             }
    103.         }
    105.         internal static void OnNonFatalError(Object sender, ExceptionEventArgs e)
    106.         {
    107.             if (e.Exception != null)
    108.             {
    109.                 Console.Error.WriteLine("  Non-fatal exception: " + e.Exception.Message);
    110.             }
    111.             else
    112.             {
    113.                 Console.Error.WriteLine("  Non-fatal failure: " + e.Failure.Message);
    114.             }
    115.         }
    117.         internal static void OnGetting(Object sender, GettingEventArgs e)
    118.         {
    119.             Console.WriteLine("  Getting: " + e.TargetLocalItem + ", status: " + e.Status);
    120.         }
    122.         internal static void OnBeforeCheckinPendingChange(Object sender, ProcessingChangeEventArgs e)
    123.         {
    124.             Console.WriteLine("  Checking in " + e.PendingChange.LocalItem);
    125.         }
    127.         internal static void OnNewPendingChange(Object sender, PendingChangeEventArgs e)
    128.         {
    129.             Console.WriteLine("  Pending " + PendingChange.GetLocalizedStringForChangeType(e.PendingChange.ChangeType) +
    130.                               " on " + e.PendingChange.LocalItem);
    131.         }
    132.     }
    133. }
  • Buck Hodges

    Permission error with creating a team project from VS 2010 on TFS 2012


    You must use the Visual Studio Team Explorer 2012 (included in all Visual Studio editions or may be separately downloaded) to create a team project on a TFS 2012 server.  If you use VS 2010, you will get an error about not having permission.  The error message is very misleading, because it’s not a problem with your permissions.

    Microsoft Visual Studio
    TF30172: You do not have permission to create a new team project.
    OK   Help  

  • Buck Hodges

    Updating a team project to use new features after upgrading to TFS 11 Beta


    [UPDATE 3/12/12] Aaron pointed out Ewald's recent detailed blog post that walks through adding optional metadata beyond the MSDN article: http://blogs.msdn.com/b/visualstudioalm/archive/2012/03/06/get-your-agile-project-fixed-after-an-upgrade-from-tfs2010-to-tfs11-beta.aspx.

    Team Foundation Server 11 Beta can be used to upgrade your existing TFS 2010 or 2008 server and used in production.  We’ll be supporting upgrade from TFS 11 Beta to RC (you’ll very likely need to go from Beta to RC to RTM in order to follow the supported path).  As Jason said in his beta blog post, TFS 11 beta is “go-live,” which means you can use it in production and receive support (details).

    Once you upgrade your server, you’ll want to enable new features that require things like new work item types.  We are working on changes that will hopefully make it easier for RC.  Here’s the documentation you’ll need to make the necessary changes.

    Updating an Upgraded Team Project to Access New Features

    After you upgrade to Visual Studio 11 Team Foundation Server Beta, you can still access the data from team projects that you created in the previous release. By downloading a localized zip file, extracting the files, and running the provided batch file of commands, you can update your team project to use the following new tools for managing the application lifecycle:

    read more…

  • Buck Hodges

    Running only impacted tests in TFS 2010 Build


    Richard Hundhausen pointed out this blog post recently, and I thought I’d mention it here.  Rob Maher walks through the process of setting up a build definition to run only the tests that involve the code that was changed.

    TFS 2010 Build - Only run impacted tests

    If your tests take a long time to run, you may wish to only run the tests that have been impacted by code changes checked in with the build (and of course run a full nightly build that executes all tests :) Unfortunately there is no out of the box feature to do this, so we need to edit our build xaml to do it.


  • Buck Hodges

    TFS 11 Beta upgrade: Existing workflows that have custom workflow activities using the TFS client OM


    Duat, a developer on Team Foundation Build, has written a blog post on how to resolve post-upgrade issues with your build workflow if your 2010 build workflow uses custom workflow activities that use the TFS client object model.

    Your custom assemblies need update, or else, redirecting

    Loading your custom assemblies in the TFS 11 build service process triggers loading TFS 2010 assemblies, and the Workflow Foundation (WF) services are not happy about that. Why?

    The build process template, for a particular reason, references the TFS OM assemblies by their simple names. When there are more than one version of the same assembly present in the process, the WF services, while loading and validating the build workflow, attempts to resolve the simple-name references with best effort, and in this case it decides to fail with a namespace ambiguity error.

    Here’s what you likely see when this issue occurs:

    TF215097: An error occurred while initializing a build for build definition \TFS\Build MAIN: The root element of the build process template found at $/TFS/BuildProcessTemplates/MainDefaultTemplate.xaml (version C182) is not valid. (The build process failed validation. Details: Validation Error: Compiler error(s) encountered processing expression "New Microsoft.TeamFoundation.Build.Workflow.Activities.BuildSettings()".'BuildSettings' is ambiguous in the namespace 'Microsoft.TeamFoundation.Build.Workflow.Activities'.


Page 1 of 1 (5 items)