TFS在工作项转换上执行自定义代码 [英] TFS Execute Custom Code on a Work Item Transition
问题描述
我希望TFS 2010在发生特定的工作流程转换时运行一些自定义代码.有可能吗?
I'd like TFS 2010 to run a bit of custom code whenever a particular workflow transition happens. Is that possible?
我找到了有关自定义操作"的文档,这些文档似乎是可以自动触发工作项转换的操作(我说得对吗?)我还找到了与构建"相关的自定义活动" .但是没有什么可以满足这个特定要求的-我错过了什么吗?
I've found documentation about Custom Actions, which seem to be actions that can automatically trigger work item transitions (am I getting that right?) I also found Custom Activities, which are related to Builds. But nothing that serves this particular requirement - am I missing something?
感谢您的帮助!
推荐答案
这非常可行.
它是如此可行,以至于有很多方法可以做到这一点.我的最爱之一是制作服务器端插件. (请注意,这仅适用于TFS 2010)
It is so doable, that there are many ways to do it. One of my favorites is to make a server side plugin. (Note, this only works on TFS 2010)
这些博客文章显示了基础知识:
These blog posts show the basics:
- In C#
- In VB
以下是我从开源项目 TFS聚合器中修改的一些代码:
Here is some code that I have modified from my open source project TFS Aggregator:
public class WorkItemChangedEventHandler : ISubscriber
{
/// <summary>
/// This is the one where all the magic starts. Main() so to speak.
/// </summary>
public EventNotificationStatus ProcessEvent(TeamFoundationRequestContext requestContext, NotificationType notificationType, object notificationEventArgs,
out int statusCode, out string statusMessage, out ExceptionPropertyCollection properties)
{
statusCode = 0;
properties = null;
statusMessage = String.Empty;
try
{
if (notificationType == NotificationType.Notification && notificationEventArgs is WorkItemChangedEvent)
{
// Change this object to be a type we can easily get into
WorkItemChangedEvent ev = notificationEventArgs as WorkItemChangedEvent;
// Connect to the setting file and load the location of the TFS server
string tfsUri = TFSAggregatorSettings.TFSUri;
// Connect to TFS so we are ready to get and send data.
Store store = new Store(tfsUri);
// Get the id of the work item that was just changed by the user.
int workItemId = ev.CoreFields.IntegerFields[0].NewValue;
// Download the work item so we can update it (if needed)
WorkItem eventWorkItem = store.Access.GetWorkItem(workItemId);
if ((string)(eventWorkItem.Fields["State"].Value) == "Done")
{
// If the estimated work was changed then revert it back.
// We are in done and don't want to allow changes like that.
foreach (IntegerField integerField in ev.ChangedFields.IntegerFields)
{
if (integerField.Name == "Estimated Work")
{
eventWorkItem.Open();
eventWorkItem.Fields["Estimated Work"].Value = integerField.OldValue;
eventWorkItem.Save();
}
}
}
}
}
}
return EventNotificationStatus.ActionPermitted;
}
public string Name
{
get { return "SomeName"; }
}
public SubscriberPriority Priority
{
get { return SubscriberPriority.Normal; }
}
public WorkItemChangedEventHandler()
{
//DON"T ADD ANYTHING HERE UNLESS YOU REALLY KNOW WHAT YOU ARE DOING.
//TFS DOES NOT LIKE CONSTRUCTORS HERE AND SEEMS TO FREEZE WHEN YOU TRY :(
}
public Type[] SubscribedTypes()
{
return new Type[1] { typeof(WorkItemChangedEvent) };
}
}
/// <summary>
/// Singleton Used to access TFS Data. This keeps us from connecting each and every time we get an update.
/// </summary>
public class Store
{
private readonly string _tfsServerUrl;
public Store(string tfsServerUrl)
{
_tfsServerUrl = tfsServerUrl;
}
private TFSAccess _access;
public TFSAccess Access
{
get { return _access ?? (_access = new TFSAccess(_tfsServerUrl)); }
}
}
/// <summary>
/// Don't use this class directly. Use the StoreSingleton.
/// </summary>
public class TFSAccess
{
private readonly WorkItemStore _store;
public TFSAccess(string tfsUri)
{
TfsTeamProjectCollection tfs = new TfsTeamProjectCollection(new Uri(tfsUri));
_store = (WorkItemStore)tfs.GetService(typeof(WorkItemStore));
}
public WorkItem GetWorkItem(int workItemId)
{
return _store.GetWorkItem(workItemId);
}
}
这篇关于TFS在工作项转换上执行自定义代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!