Creating a TFS Work Item from an Outlook mail message using VSTO
Many times new work-items are the by-product of an email thread. Sometimes it a question that turns into a feature request or a bug report from an external customer. When this happens I need to move the email message to one screen and open VS in another. Browse out to the Work Item menu and create a new work item. Go back to Outlook and CTRL+A, CTRL+C to get the message, go back to VS and paste it … not really a big deal but why not streamline it a bit more?
So I spent a few minutes looking at the VSTO wizard that comes with Visual Studio 2005 (see more here: https://msdn.microsoft.com/office/understanding/vsto/training/labs05/default.aspx) and whipped up a quick Outlook add-in that lets me right-click on an Email and create a new workitem from it. You can see an example of the context menu created in Outlook when your right-click on an email message. Notice the "Create Workitem" menu item.
The email subject becomes the bug title and the email body the description. It would be just a tad more work to save the email as a temp file and make it an attachment instead.
To get started you will want to create an Outlook Add-In project (this means you need to have VSTO installed!). This will create a lot of the plumbing code you need to make this work. I've only included the code I modified. The link I gave earlier includes walk-throughs that will teach you how to do this.
The code is fairly well documented so I won't spend a lot of time on it. This is a quick hack - about 30 minutes of work (which was mostly figuring out how to write an Outlook add-in) and it is pretty rigid. A better solution would be to let the user configure the project and server name. Also support for mandatory fields or custom fields would need to be added - but I think this shows how easy it is to extend Outlook in a time-saving way.
using System;
using System.Windows.Forms;
using Microsoft.VisualStudio.Tools.Applications.Runtime;
using Outlook = Microsoft.Office.Interop.Outlook;
using Office = Microsoft.Office.Core;
using System.Collections.Generic;
using Microsoft.Office.Interop.Outlook;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
namespace EmailToWorkitem
{
public partial class ThisApplication
{
// the prompt and action name
const string createNewPrompt = "Create Workitem";
Outlook.Explorer _explorer = null;
private void ThisApplication_Startup(object sender, System.EventArgs e)
{
// cache the explorer object
_explorer = this.Explorers.Application.ActiveExplorer();
// when an email selection changes this event will fire
_explorer.SelectionChange += new ExplorerEvents_10_SelectionChangeEventHandler(_explorer_SelectionChange);
}
// event fired when any selection changes.
void _explorer_SelectionChange()
{
foreach (object selectedItem in _explorer.Selection)
{
// we only want to deal with selected mail items
MailItem item = selectedItem as MailItem;
if (item != null)
{
// see if the action already exists on mail item
Action newAction = item.Actions[createNewPrompt];
// and create it if it does not
if(newAction == null)
{
newAction = item.Actions.Add();
newAction.Name = createNewPrompt;
newAction.ShowOn = OlActionShowOn.olMenu;
newAction.Enabled = true;
item.Save();
}
// add the event handler for our action
item.CustomAction += new ItemEvents_10_CustomActionEventHandler(item_CustomAction);
}
}
}
void item_CustomAction(object Action, object Response, ref bool Cancel)
{
try
{
Action mailAction = (Action)Action;
switch (mailAction.Name)
{
// only process the action we know about
case createNewPrompt:
try
{
MailItem mailItem = _explorer.Selection[1] as MailItem;
if (mailItem != null)
{
// TODO: modify the server details to point you your server
TeamFoundationServer tfs = TeamFoundationServerFactory.GetServer("https://yourserver:8080");
WorkItemStore store = (WorkItemStore)tfs.GetService(typeof(WorkItemStore));
// TODO: modify the project name to your project
WorkItemTypeCollection workItemTypes = store.Projects["YOURPROJECT"].WorkItemTypes;
// Enter the work item as a bug
WorkItemType wit = workItemTypes["bug"];
WorkItem workItem = new WorkItem(wit);
workItem.Title = mailItem.Subject;
workItem.Description = mailItem.Body;
workItem.Save();
MessageBox.Show(string.Format("Created bug {0}", workItem.Id));
}
else
{
MessageBox.Show("Unable to convert selected item to a mail item");
}
}
finally
{
Cancel = true;
}
break;
}
}
catch (System.Exception e)
{
MessageBox.Show(e.ToString());
}
}
private void ThisApplication_Shutdown(object sender, System.EventArgs e)
{
}
#region VSTO generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InternalStartup()
{
this.Startup += new System.EventHandler(ThisApplication_Startup);
this.Shutdown += new System.EventHandler(ThisApplication_Shutdown);
}
#endregion
}
}
Comments
- Anonymous
May 04, 2006
Rob Caron tells us the localized Team Foundation Server versions have shipped. He also posts about the... - Anonymous
May 04, 2006
A while back, I took at a look at Personify Design's Teamlook tool that provided functionality within... - Anonymous
August 12, 2006
I recently had to put together a list of links to code samples.&nbsp; This isn't even close to comprehensive,... - Anonymous
August 12, 2006
I recently had to put together a list of links to code samples.&nbsp; This isn't even close to comprehensive,... - Anonymous
March 07, 2008
General OzTFS.com – Australian Team Foundation Server online community Radio TFS – Team System Talk Radio