How to Write a Team Foundation Version Control Add-in for Visual Studio

The purpose of this post is to give step by step instructions to get users started writing a Team Foundation Version Control Add-in for Visual Studio.  This is not intended to be a comprehensive reference guide, but rather a guide to get things jump started.  This guide focuses on the classes specific to extending Team Foundation Version Control in Visual Studio, it does not cover any of the Team Foundation SDK classes since those are covered elsewhere.

The Team Foundation Version Control extensibility classes first appeared in the December CTP. Beta 3 and Beta 3 refresh do not have these classes.

Step 1: Help Visual Studio Find Team Foundation Assemblies

The Team Foundation assemblies you need to reference are in Visual Studio’s PrivateAssemblies directory.  Visual Studio Add Reference browse dialog does not list the PrivateAssemblies directory by default so you must change some registry settings so you can easily add references to the Team Foundation assemblies.  Close all instances of Visual Studio, backup your registry if you want to be completely safe, copy the following lines into a batch file and run it:

reg add HKCU\Software\Microsoft\.NETFramework\AssemblyFolders\Microsoft.TeamFoundation /ve /d "%programfiles%\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies" /f
reg add HKCU\Software\Microsoft\.NETFramework\AssemblyFolders\Microsoft.TeamFoundation.Build.Common /ve /d "%programfiles%\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies" /f
reg add HKCU\Software\Microsoft\.NETFramework\AssemblyFolders\Microsoft.TeamFoundation.Client /ve /d "%programfiles%\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies" /f
reg add HKCU\Software\Microsoft\.NETFramework\AssemblyFolders\Microsoft.TeamFoundation.Common /ve /d "%programfiles%\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies" /f
reg add HKCU\Software\Microsoft\.NETFramework\AssemblyFolders\Microsoft.TeamFoundation.Common.Library /ve /d "%programfiles%\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies" /f
reg add HKCU\Software\Microsoft\.NETFramework\AssemblyFolders\Microsoft.TeamFoundation.VersionControl.Client /ve /d "%programfiles%\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies" /f
reg add HKCU\Software\Microsoft\.NETFramework\AssemblyFolders\Microsoft.TeamFoundation.VersionControl.Common /ve /d "%programfiles%\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies" /f
reg add HKCU\Software\Microsoft\.NETFramework\AssemblyFolders\Microsoft.TeamFoundation.VersionControl.Common.Integration /ve /d "%programfiles%\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies" /f
reg add HKCU\Software\Microsoft\.NETFramework\AssemblyFolders\Microsoft.TeamFoundation.WorkItemTracking.Client /ve /d "%programfiles%\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies" /f
reg add HKCU\Software\Microsoft\.NETFramework\AssemblyFolders\Microsoft.TeamFoundation.WorkItemTracking.Client.Cache /ve /d "%programfiles%\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies" /f
reg add HKCU\Software\Microsoft\.NETFramework\AssemblyFolders\Microsoft.TeamFoundation.WorkItemTracking.Client.DataStore /ve /d "%programfiles%\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies" /f
reg add HKCU\Software\Microsoft\.NETFramework\AssemblyFolders\Microsoft.TeamFoundation.WorkItemTracking.Client.Provision /ve /d "%programfiles%\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies" /f
reg add HKCU\Software\Microsoft\.NETFramework\AssemblyFolders\Microsoft.TeamFoundation.WorkItemTracking.Client.QueryLanguage /ve /d "%programfiles%\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies" /f
reg add HKCU\Software\Microsoft\.NETFramework\AssemblyFolders\Microsoft.TeamFoundation.WorkItemTracking.Client.RuleEngine /ve /d "%programfiles%\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies" /f
reg add HKCU\Software\Microsoft\.NETFramework\AssemblyFolders\Microsoft.TeamFoundation.WorkItemTracking.Proxy /ve /d "%programfiles%\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies" /f

Step 2: Create a Visual Studio Add-In Project

 

  1. From the Visual Studio File, New, Project… menu expand the “Other Project Types” from the Project types tree. 
  2. Select Extensiblity under the “Other Project Types” node and then select Visual Studio Add-in. 
  3. Press OK
  4. Press the Next button
  5. For this example, I will use a C# project.  Similar instructions apply for the other managed languages, however, the syntax is different. 
    Choose Create an Add-in using Visual C#
  6. Press the Next button
  7. Check the “Microsoft Visual Studio 2005” check box.  Uncheck all others (you may have more items than what is shown below).
  8. Press the Next button
  9. Name your add-in and give it an appropriate description and then press Next
  10. Check the “Would you like to create a command bar UI for the Add-in”
  11. The rest of the settings will vary based on what your add-in will do and your individual preferences
  12. Press Finish

 

Step 3: Add references to Team Foundation Assemblies

 

  1. Right click on the References folder for your new project you created in Step 2
  2. Choose Add Reference….
  3. Add the following references:
  • Microsoft.TeamFoundation.Client

  • Microsoft.TeamFoundation.VersionControl.Client

  • Microsoft.TeamFoundation.VersionControl.Controls

  • Microsoft.VisualStudio.TeamFoundation

  • Microsoft.VisualStudio.TeamFoundation.Client

  • Microsoft.VisualStudio.TeamFoundation.VersionControl
     

 

  1. Press OK

 

Step 4: Add using statement to all files that will be referencing Team Foundation

 

Add the following using lines to files that will be referencing Team Foundation:

 

using Microsoft.VisualStudio.TeamFoundation;

using Microsoft.TeamFoundation.Client;

using Microsoft.VisualStudio.TeamFoundation.VersionControl;

using Microsoft.TeamFoundation.VersionControl.Client;

 

You may find you do not need all of these references depending on what your add-in does.

Step 5: Obtain Reference to Appropriate Team Foundation Objects

 

There are several objects that you can create a reference to at this point, but I will focus on the one that is the most useful for a Visual Studio Add-in.

 

The top level class used to access all other Team Foundation Version Control Extensiblity classes is called the VersionControlExt class.  You obtain a reference to the single instance of this class via the DTE2 object that Visual Studio passes your add-in (e.g. in the OnConnection method in Connect.cs).  In the generated add-in code in connects.cs, you will see that a member variable _applicationObject is set in the OnConnection method.  To access VersionControlExt, you use that _applicationObject.  For example:

 

VersionControlExt vce;

vce = _applicationObject.GetObject("Microsoft.VisualStudio.TeamFoundation.VersionControl.VersionControlExt") as VersionControlExt;

 

The VersionControlExt object can be used to do the following:

 

Method/Property

Description

Explorer

Access the Source Control Explorer.  This is very useful for add-ins that need a selection of scope.  The class is VersionControlExplorerExt.

FindChangeSet

Find and display a specific changeset from your add-in

History

Access the History Toolwindow from your add-in.  The class is HistoryExt

PendingChanges

Access the collection of pending changes (as displayed in the Pending Changes Toolwindow) from your add-in.  The class is PendingChagnesExt.

SolutionWorkspace

Get the Workspace object that contains the currently opened solution.  If there is no solution opened or the solution is not under version control this will be null.

ViewChangeSetDetails

Display detailed information about a changeset

ViewShelveSetDetails

Display detailed information about a shelveset

 

VersionControlExplorerExt

 

This represents the Source Control Explorer singleton.  Add-ins that want to use the selection context to scope their operations will use this object.  Keep in mind that if the Source Control Explorer (SCE) is not displayed, the Explorer property on VersionControlExt will be null.  If you want to force the display of the SCE from your Add-in use the View.TfsSourceControlExplorer DTE command as follows:

 

_applicationObject.ExecuteCommand(“View.TfsSourceControlExplorer”);

 

Where _applicationObject is the DTE2 object set in your OnConnection method.

 

Methods and Properties

 

Method/Property/Events

Description

Connected

Bool that is true if the SCE is connected to a Team Foundation Server; false otherwise

CurrentFolderItem

This is a VersionControlExplorerItem that represents the currently selected folder in the SCE.  This is the folder contents that are displayed in the right hand pane

SelectedItems

An array of VersionControlExplorerItem that represents all of the selected items in the SCE.

SelectionChanged

An event that is fired when the selection changes in the SCE.  This is useful if you need to dislable or enable your Add-in based on what is selected

ShowDeletedItems

Boolean that specifies if deleted items are shown or not.  Setting this value will change the SCE to reflect the specified value

Workspace

The SCE’s Workspace.  This is the currently selected workspace in the SCE Workspace combobox.

 

VersionControlExplorerItem

 

Objects of this class represent a single version controlled file or folder.  You can get the selected items or current folder from the VersionControlExplorerExt object.

 

Method/Property/Events

Description

DeletionId

Id used to identify the deletion of this item.  This is needed when doing an undelete

HasOtherWorkspaceChanges

True if there are changes on this item in a different workspace (either by the current user or some other user)

ImplicitLockStatus

This is  LockLevel enum that specifies if this item has an implicit lock (e.g. the parent folder is locked)

IsDeleted

Bool that specifies if this item has been deleted

IsImplicitFolder

Bool that specifies if this folder exists on the client but not on the server yet.   This happens on pending adds, branches, renames and other operations that introduce new folders when they are checked in.

IsFolder

Bool that specifies if this item is a folder

ItemId

The unique id for this item

LocalPath

String that specifies where the server item maps to on the user’s local disk based on the current Workspace.  This will be null if this item is not mapped or has not been retrieved yet.

LockOwner

String representing the person who owns the lock on this item

LockStatus

LockLevel that specifies the lock, if any, on this item

PendingChange

PendingChange on this item, if any, for the current user in the current workspace

SourceServerPath

The server path to the item in its original location.  For example, if the current user has a pending rename on the item in the current workspace, then this value would be the server path to the original location.

TargetServerPath

The target path to the item in its new location.  For example, if the current user has a pending rename on the item in the current workspace, then this value would be the server path to the new location.

WorkspaceChanges

A ChangeType object that represents the changes on this item by the current user in the current workspace

 

 

PendingChangesExt

 

This class represents the pending changes listed in Visual Studio’s Pending Changes Toolwindow (specifically, the File List channel). 

 

Method/Property/Events

Description

CheckedChanged

Event that is fired when the checked state of one or more pending changes has changed

CheckedItems

Array of PendingChange objects that are current checked

Items

Array of PendingChange objects for all pending changes in the current workspace

SelectedItems

Array of PendingChange objects that are currently selected in the Pending Change toolwindow

SelectionChanged

Event that is fired when there is a change in the pending changes that are selected

 

VersionControlHistoryExt

 

This class represents the History toolwindow in Visual Studio.

 

Method/Property/Events

Description

Clear

Removes all of the items from the history toolwindow

SelectedItems

Array of Changeset objects for the currently selected changesets in the history toolwindow

SelectionChanged

Event that is fired when the user changes the selection in the history toolwindow

Show

Displays history for the specified item