January 2009 - Posts
TFS 2008 - Quality Center Connector is now available
The December pre-release of the TFS 2008 - Quality Center Connector is now available for download. This release is packaged as a Microsoft Installer (MSI) package and includes a Viewer (GUI), Console (command-line) and Service versions of the Quality Center Connector.
In many customers I see that QA works with QC and the development works with Team System, this is a great solution for this kind of situation.
Before Installing make sure you read Getting Started guide.
Enjoy
TFS API Part 10: Add Area/Iteration Programmatically
In my last post I talk about TFS API Part 9: Get Area/Iteration Programmatically.
In this post I will show how to add Area or Iteration programmatically ICommonStructureService.

First add reference for Microsoft.TeamFoundation, Microsoft.TeamFoundation.Client, Microsoft.TeamFoundation.Common.dll,Microsoft.TeamFoundation.WorkItemTracking.Client.dll
located in - C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\PrivateAssemblies\
Add using for:
using Microsoft.TeamFoundation.Proxy;
using Microsoft.TeamFoundation.Server;
using Microsoft.TeamFoundation.Client;
Download Demo
If the Node not exists checking if there is more then one Area/Iteration to create
(Example: Area 7\\Sub Area 7)
int BackSlashIndex = ElementPath.LastIndexOf("\\");
string Newpathname = ElementPath.Substring(BackSlashIndex + 1);
string NewPath = (BackSlashIndex == 0 ? string.Empty : ElementPath.Substring(0, BackSlashIndex));
string PathRoot = rootNodePath + NewPath;
NodeInfo previousPath = null;
try
{
previousPath = css.GetNodeFromPath(PathRoot);
}
catch (Exception ex)
{
if (ex.Message.Contains("Invalid path."))
{
//just means that this path is not exist and we can continue.
previousPath = null;
}
else
{
throw ex;
}
}
if (previousPath == null)
{
//call this method to create the parent paths.
previousPath = AddNode(NewPath, projectName, nodeType);
}
string newPathUri = css.CreateNode(Newpathname, previousPath.Uri);
return css.GetNode(newPathUri);
Checking if the Node exists…
NodeInfo retVal;
string rootNodePath = "\\" + projectName + "\\" + nodeType.ToString();
//Check if this path already exsist
string newPath = rootNodePath + ElementPath;
try
{
retVal = css.GetNodeFromPath(newPath);
if (retVal != null)
{
return null; //already exists
}
}
catch (Exception ex)
{
if (ex.Message.Contains("The following node does not exist"))
{
//just means that this path is not exist and we can continue.
}
else
{
throw ex;
}
}
Download Demo
TFS API Part 9: Get Area/Iteration Programmatically
Over the last posts I talked about TFS API Part 7: Use IEventService To Get User Event Subscriptions and TFS API Part 8: Subscribe/Unsubscribe Events Using IEventService.
This summing up how to programmatically get / set Event Subscription using TFS API.
More about IEventService on later posts.
On this post I will show how to get Area and Iteration tree.
This can be useful to map your Area/Iteration tree on third party applications.
First add reference for Microsoft.TeamFoundation, Microsoft.TeamFoundation.Client, Microsoft.TeamFoundation.Common.dll,Microsoft.TeamFoundation.WorkItemTracking.Client.dll
located in - C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\PrivateAssemblies\

Download Demo
Add using for:
using Microsoft.TeamFoundation.Proxy;
using Microsoft.TeamFoundation.Server;
using Microsoft.TeamFoundation.Client;
Use ICommonStructureService to get the Area/Iteration nodes by specific project.
private void PopulateIteration()
{
ICommonStructureService css = (ICommonStructureService)server.GetService(typeof(ICommonStructureService));
//Gets Area/Iteration base Project
ProjectInfo projectInfo = css.GetProjectFromName(combo_project_list.SelectedValue.ToString());
NodeInfo[] nodes = css.ListStructures(projectInfo.Uri);
//GetNodes can use with:
//Area = 1
//Iteration = 0
XmlElement AreaTree = css.GetNodesXml(new string[] { nodes[1].Uri }, true);
XmlElement IterationsTree = css.GetNodesXml(new string[] { nodes[0].Uri }, true);
list_area.Items.Clear();
list_iteration.Items.Clear();
XmlNode AreaNodes = AreaTree.ChildNodes[0];
XmlNode IterationsNodes = IterationsTree.ChildNodes[0];
MakeList(AreaNodes, StructureType.Area);
MakeList(IterationsNodes, StructureType.Iteration);
}
Define structures – Area or Iteration
enum StructureType
{
Iteration = 0,
Area = 1
}
Building Area/Iteration tree using ChildNode from XmlElement
private void MakeList(XmlNode tree, StructureType type)
{
//Check if Area/Iteration has Childerns
if (tree.FirstChild != null)
{
int myNodeCount = tree.FirstChild.ChildNodes.Count;
for (int i = 0; i < myNodeCount; i++)
{
XmlNode Node = tree.ChildNodes[0].ChildNodes[i];
if (type == StructureType.Area)
list_area.Items.Add(Node.Attributes["Name"].Value);
else
list_iteration.Items.Add(Node.Attributes["Name"].Value);
}
}
}
Download Demo
TFS API Part 8: Subscribe/Unsubscribe Events Using IEventService
In the last post I wrote about TFS API Part 7: Use IEventService To Get User Event Subscriptions.
In this post I’ll show you have to user IEventService to Subscribe new Events and Unsubscribe existingEvents.
First add reference for Microsoft.TeamFoundation, Microsoft.TeamFoundation.Client, Microsoft.TeamFoundation.Common.dll,Microsoft.TeamFoundation.WorkItemTracking.Client.dll
located in - C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\PrivateAssemblies\
Download Demo
Add using for:
using Microsoft.TeamFoundation.Proxy;
using Microsoft.TeamFoundation.Server;
using Microsoft.TeamFoundation.Client;

I add the Event Type to the SubscriptionItem class
Here is available type for TFS:
BranchMovedEvent
BuildCompletionEvent
BuildStatusChangedEvent
CheckinEvent
CommonStructureChangedEvent
DataChangedEvent
IdentityChangedEvent
NodeCreatedEvent
NodePropertiesChangedEvent
NodeRenamedEvent
NodesDeletedEvent
ProjectCreatedEvent
ProjectDeletedEvent
WorkItemChangedEvent
Subscribe Event
You can add a Combo for picking the right Delivery preference.
DeliveryPreference delPrev = new DeliveryPreference();
switch (lbl_sch.Content.ToString())
{
case "Daily":
delPrev.Schedule = DeliverySchedule.Daily;
break;
case "Weekly":
delPrev.Schedule = DeliverySchedule.Weekly;
break;
default:
delPrev.Schedule = DeliverySchedule.Immediate;
break;
}
switch (lbl_type.Content.ToString())
{
case "EmailPlaintext":
delPrev.Type = DeliveryType.EmailPlaintext;
break;
case "Soap":
delPrev.Type = DeliveryType.Soap;
break;
default:
delPrev.Type = DeliveryType.EmailHtml;
break;
}
User u = (User)listBox1.SelectedItem;
//Adding user email to DeliveryPreference.
delPrev.Address = u.Email;
string userId = Environment.UserDomainName + @"\" + u.UserName;
try
{
//userid,event type,subscription expresstion,delivery preference
int event_id = EventService.SubscribeEvent(userId,
lbl_eventtype.Content.ToString(),
txt_sub.Text, delPrev);
MessageBox.Show("Subscribe Complete, Your SubscribeID is: " + event_id, "TFS", MessageBoxButton.OK, MessageBoxImage.Information);
}
catch (Exception ex)
{
MessageBox.Show("Error:" + ex.Message, "TFS Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
UnSubscribe Event
//Events list
if (listBox2.SelectedItem != null)
{
EventService.UnsubscribeEvent(Convert.ToInt32(listBox2.SelectedValue.ToString()));
MessageBox.Show("UnSubscribe Complete", "TFS", MessageBoxButton.OK, MessageBoxImage.Information);
}
else
{
MessageBox.Show("Please select Subscribe from the list.", "TFS", MessageBoxButton.OK, MessageBoxImage.Error);
}
Download Demo
WebTlk.com - “Shai Raiten: A Team System expert for you”

WebTlk published a post about me!
I’m putting a lot of hours for the community in Blogs, Lectures, Courses and assistance to every one approaches me.
There is nothing that makes me more happy than to see that all this hard work is worthwhile.
Thank You All.
Q: Work Item Definition - Layout Target Not Working
My post about How To: Manage Custom Controls In Team System and Web Access shows how to create Work Item Layout for Web and another for Team Explorer.
I got a comment from a reader that this Target layout is not working.
Reader:After exporting the Xml using Process Editor I’m editing the Xml file and inserting the new Layout, then I import it back to TFS and the Layout changes and only keeps <Layout Target="WinForms">.
Process Editor don’t know how to work item Target Layouts!!!
So even if you able to import the xml with those changes the next time you work with process editor all those changes will be erased.
The solution for this problem is to import the xml file using witimport to import the xml without Process Editor.
TFS API Part 7: Use IEventService To Get User Event Subscriptions
Over the previous posts I talked about Connecting TFS and Working with WorkItemStore.
The following posts will about about more advanced and interesting subjects
In this post I’ll show how to use IEventService to get user subscription from tfs.
We going to build a WPF application that will collect all users in TFS and show Event Subscriptions for each user.
Download Demo
First add reference for Microsoft.TeamFoundation, Microsoft.TeamFoundation.Client, Microsoft.TeamFoundation.Common.dll,Microsoft.TeamFoundation.WorkItemTracking.Client.dll
located in - C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\PrivateAssemblies\
Add using for:
using Microsoft.TeamFoundation.Proxy;
using Microsoft.TeamFoundation.Server;
using Microsoft.TeamFoundation.Client;
Connecting to TFS - TFS API Part 1: Domain Picker
DomainProjectPicker dp = new DomainProjectPicker(DomainProjectPickerMode.None);
dp.ShowDialog();
tfs = dp.SelectedServer;
if (dp.SelectedServer != null)
{
//Get IEventService interface using Tfs server.
EventService = (IEventService)tfs.GetService(typeof(IEventService));
GetUsersList();
}
Get User List - TFS API Part 4: Get TFS User List (Mail, Sid, Account, Domain)
private void GetUsersList()
{
IGroupSecurityService gss = (IGroupSecurityService)tfs.GetService(typeof(IGroupSecurityService));
Identity idSID = gss.ReadIdentity(SearchFactor.AccountName, "Team Foundation Valid Users", QueryMembership.Expanded);
Identity[] idUserName = gss.ReadIdentities(SearchFactor.Sid, idSID.Members, QueryMembership.None);
foreach (Identity id in idUserName)
{
if (id != null && id.Type == IdentityType.WindowsUser)
{
User u = new User(id.AccountName, id.MailAddress);
listBox1.Items.Add(u);
}
}
}
User Class
public class User
{
public string Email { get; set; }
public string UserName { get; set; }
public List<SubscriptionItem> SubList { get; set; }
public User(string username,string email)
{
this.UserName = username;
this.Email = email;
SubList = new List<SubscriptionItem>();
//Make sure you enter the Domain Name & User Name!
foreach (Subscription s in Window1.EventService.EventSubscriptions(Environment.UserDomainName + @"\" + this.UserName))
{
SubList.Add(new SubscriptionItem(s));
}
}
public override string ToString()
{
return UserName;
}
}
Subscription Item
public class SubscriptionItem
{
public int ID { get; set; }
public string ConditionString { get; set; }
public DeliverySchedule Schedule { get; set; }
public DeliveryType Type { get; set; }
public string Tag { get; set; }
public SubscriptionItem(Subscription s)
{
this.ID = s.ID;
this.Schedule = s.DeliveryPreference.Schedule;
this.Type = s.DeliveryPreference.Type;
this.ConditionString = s.ConditionString;
}
public override string ToString()
{
//In 2008 you can Tag you Subscription
if (string.IsNullOrEmpty(Tag))
return ID.ToString();
else
return Tag;
}
}
Download Demo
TFS API Part 6: WorkItemStore - Get Fields From WorkItemType
In TFS API Part 5: WorkItemStore - Get Project Details (WorkItemTypes, Queries) we use WorkItemStore to get all work item type from TFS.
In this post I’ll show how to take all fields for a specific Work Type.
First add reference for Microsoft.TeamFoundation, Microsoft.TeamFoundation.Client, Microsoft.TeamFoundation.Common.dll,Microsoft.TeamFoundation.WorkItemTracking.Client.dll
located in - C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\PrivateAssemblies\
Download Demo Project
using Microsoft.TeamFoundation.Proxy;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Server;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
Connect to TFS (TFS API Part 1: Domain Picker)
from Work Item type you can get FieldDefinition.
public class WitType
{
public WorkItemType Type { get; set; }
public List<string> Fields { get; set; }
public WitType(WorkItemType type)
{
this.Type = type;
this.Fields = new List<string>();
foreach (FieldDefinition f in Type.FieldDefinitions)
Fields.Add(f.Name);
}
public override string ToString()
{
return Type.Name;
}
}
Download Demo Project
How To: Disable the Team Members Feature
If you installed TFS Power Tools 2008 you will see couple of new features.
One of the features called – "Team Members" that allows you to collaborate with your team even better. One of the features is integration with instant messaging that allows you to see presence, IM, video, audio, etc from inside Team Explorer. You can read more about the feature here:http://blogs.msdn.com/bharry/archive/2008/10/01/preview-of-the-next-tfs-power-tools-release.aspx.
There is a lot of problems with that plug, for example the load time can be excessive…
And this error….

There is two ways to disable Team Member feature:
1.Visual Studio Options
Open Visual Studio –> Tools –> Options –>Team Foundation Server Power Tools –> General, then set Team Members to False.
2. Registry
Open Run and write “regedit”, navigate to HKCU\Software\Microsoft\VisualStudio\9.0\TeamFoundation\PowerTools
Add a new String Value named TeamTrackerHidden and set its value to True.

Team System User Group - Scrum and Team System
Even when the meeting starts at 3:00 am (Israel Time) the Scrum session was very interesting.
Trent Nix spoke about : What Is Scrum? and how it’s implement in Team System under the different templates:
Conchango's Scrum For Team System
Microsoft Escrum
Light Weight Scrum
Next month I’ll speak about Custom Control, hope to see you there.

IWin32Window Owner For WPF Window
I wrote a Word Plugin in WPF, when raise the window with ShowDialog it’s seems that all Word instances on the computer stucks, even new ones.
So I need to open My window just for a specific Word instance.
In Windows Form you can write -
But in WPF you need to use WindowInteropHelper.
//Create WPF Window
MainUI1 win = new MainUI1();
WindowInteropHelper helper = new WindowInteropHelper(win);
//Find Current Word Process
Process procs = Process.GetCurrentProcess();
//Get the handle from the process
IntPtr hwnd = procs.MainWindowHandle;
//Set Word handle to helper
helper.Owner = hwnd;
win.Show();
Hope this helps.
TFS API Part 5: WorkItemStore - Get Project Details (WorkItemTypes, Queries)
In TFS API Part 3: Get Project List Using ICommonStructureService we I use ICommonStructureService to get Team Projects.
In this post I’ll show how to use WorkItemStore to perform the same action, and take lots more information about the project.
First add reference for Microsoft.TeamFoundation, Microsoft.TeamFoundation.Client, Microsoft.TeamFoundation.Common.dll,Microsoft.TeamFoundation.WorkItemTracking.Client.dll
located in - C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\PrivateAssemblies\
Download Demo Project
using Microsoft.TeamFoundation.Proxy;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Server;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
Connect to TFS (TFS API Part 1: Domain Picker)
Add :
WorkItemStore store = (WorkItemStore)tfs.GetService(typeof(WorkItemStore));
Now very easily you can pull Project item.
foreach (Project project in store.Projects)
{
ProjectItem item = new ProjectItem(project.Name,project.WorkItemTypes,project.Uri.ToString(),project.StoredQueries);
combo_projects.Items.Add(item);
}
public class ProjectItem
{
public string Name { get; set; }
public List<string> WorkItemTypes { get; set; }
public string Uri { get; set; }
public List<string> Queries { get; set; }
public ProjectItem(string name ,WorkItemTypeCollection wittype, string uri, StoredQueryCollection queries)
{
this.Name = name;
this.Uri = uri;
this.WorkItemTypes = new List<string>();
foreach (WorkItemType wit in wittype)
this.WorkItemTypes.Add(wit.Name);
//Queries can be persisted on the Team Foundation
//Server using the StoredQueryCollection class.
this.Queries = new List<string>();
foreach (StoredQuery q in queries)
this.Queries.Add(q.Name);
}
public override string ToString()
{
return this.Name;
}
}
Download Demo Project
TFS API Part 4: Get TFS User List (Mail, Sid, Account, Domain)
In my previous posts TFS API Part 2: Domain Picker Using Registered Servers (Cache) I demonstrate how to connect TFS and how to get TFS Projects.
In this post I’ll show how to get User List from TFS by groups.
First add reference for Microsoft.TeamFoundation, Microsoft.TeamFoundation.Client, Microsoft.TeamFoundation.Common.dll
located in - C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\PrivateAssemblies\
Download Demo Project
Add using for Proxy,Client and Server.
*** Good to know -> An Identity structure represents a user, group, or Team Foundation Server application group, along with some of their attributes
using Microsoft.TeamFoundation.Proxy;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Server;
Connect to TFS and call GetTfsUsers(dp.SelectedServer) with the TFS.
Create IGroupSecurityService from TFS.
IGroupSecurityService gss = (IGroupSecurityService)server.GetService(typeof(IGroupSecurityService));
# Read Identitys
Using gss you can read all Identitys in TFS.
SearchFactor
AccountName -Logon name (for Windows identities) or an application group name, possibly qualified by domain name, such as AdventureWorks\JAaberg, ProjectURI\groupname, or GUID\groupname.
AdministrativeApplicationGroup - An administrative application group.
DistinguishedName - A LDAP escaped distinguished name, optionally prepended by LDAP://.
EveryoneApplicationGroup - The Team Foundation Server Everyone application group.
ServiceApplicationGroup - The service application group.
Sid - Contains a SID
Identity SIDS = gss.ReadIdentity(SearchFactor.AccountName, "Team Foundation Valid Users", QueryMembership.Expanded);
Identity SIDS = gss.ReadIdentity(SearchFactor.ServiceApplicationGroup, "Team Foundation Valid Users", QueryMembership.Expanded);
QueryMembership
Direct- Each Identity includes its direct members. However, these member identities will contain null members.
Expanded - Each returned identity includes its direct members. Each of these member identities contain their direct member identities, and so on.
None - No information about membership is returned, and corresponding properties are set to null.
Identity SIDS = gss.ReadIdentity(SearchFactor.AccountName, "Team Foundation Valid Users", QueryMembership.Expanded);
Identity SIDS = gss.ReadIdentity(SearchFactor.AccountName, "Team Foundation Valid Users", QueryMembership.Direct);
#
# Getting User List
To get Identity for each user use ReadIdentities by Sid.
Identity[] UserId = gss.ReadIdentities(SearchFactor.Sid, SIDS.Members, QueryMembership.None);
Download Demo Project
TFS API Part 3: Get Project List Using ICommonStructureService
In the first post about TFS API Part 1: Domain Picker we saw how to take TFS projects only by selecting them in the Domain Project Picker.
In the post I’ll saw how to take all project from the TFS Server.
Download Demo Project
First add reference for Microsoft.TeamFoundation,Microsoft.TeamFoundation.Client
located in - C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\PrivateAssemblies\
Add using for Proxy,Client and Server.
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Proxy;
using Microsoft.TeamFoundation.Server;
Connect to TFS Server
DomainProjectPicker dp = new DomainProjectPicker(DomainProjectPickerMode.None);
dp.ShowDialog();
After selecting the desire TFS I’ll make TeamFoundationServer object:
TeamFoundationServer tfs = dp.SelectedServer;
Create ICommonStructureService object that will take TFS Structure Service.
ICommonStructureService structureService = (ICommonStructureService)tfs.GetService(typeof(ICommonStructureService));
Use ListAllProjects method to get all Team Projects in the TFS.
ProjectInfo[] projects = structureService.ListAllProjects();
list_projects.DataSource = projects;

Download Demo Project
TFS API Part 2: Domain Picker Using Registered Servers (Cache)
In my previous post about TFS API Part 1: Domain Picker I showed how to use DomainPicker to connect TFS server.
In this post I’ll show how to connect and get TFS Servers using Registered Servers.
*** The disadvantage in this method is that you rely on your local computer cache.***
First add reference for Microsoft.TeamFoundation.Client
located in - C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\PrivateAssemblies\
Download Demo Project
All you need to do is:
TeamFoundationServer[] tfs_list = RegisteredServers.GetServers();
To connect TFS:
ICredentialsProvider provider = new UICredentialsProvider();
TeamFoundationServer tfs = TeamFoundationServerFactory.GetServer(comboBox1.Text,provider);

Download Demo Project
More Posts
Next page »