Outlook:使用新扩展程序保存TFS-PBI会锁定PBI

时间:2013-10-10 10:16:02

标签: c# tfs outlook

我正在尝试在Outlook中创建一个新按钮,它会查找任务ID,获取已连接的PBI并将mailitem添加为附件。

非常简单:

public void mnuAttachToPBI_Clicked(Office.IRibbonControl control)
{

    Microsoft.Office.Interop.Outlook.Selection sel = Global.CurrentApplication.ActiveExplorer().Selection;

    if (sel != null && sel.Count > 0)
    {
        string subj;
        foreach (MailItem mailItem in sel)
        {
            subj = mailItem.Subject.Substring(mailItem.Subject.IndexOf('['));
            subj = subj.Substring(0, subj.IndexOf(']'));
            subj = subj.Replace("[", String.Empty);
            subj = subj.Replace("]", string.Empty);
            int taskId;
            if (Int32.TryParse(subj, out taskId))
            {
                WorkItem wi = TfsHandler.GetPbi(taskId);
                if (wi != null)
                {
                    string fileName = Path.GetInvalidFileNameChars().Aggregate(mailItem.Subject + ".msg", (current, c) => current.Replace(c.ToString(), "_"));
                    string path = Path.Combine(Path.GetTempPath(), fileName);

                    mailItem.SaveAs(path, OlSaveAsType.olMSG);
                    wi.Attachments.Add(new Microsoft.TeamFoundation.WorkItemTracking.Client.Attachment(path));
                    wi.Save();
                    wi.Close();
                    File.Delete(path);
                }
            }
        }
    }
}

静态TFS处理程序类如下所示:

private static List<WorkItem> _allWorkItems;

private const string ITEM_TYPE_NAME_PBI = "PBI";
private const string ITEM_TYPE_NAME_TASK = "Task";

private static List<WorkItem> AllWorkItems
{
    get
    {
        if (_allWorkItems == null)
        {
            WorkItemCollection wc = new WorkItemStore(TFS_SRV).Query(
                    " SELECT [System.Id], [System.WorkItemType]," +
                " [System.State], [System.AssignedTo], [System.Title] " +
                " FROM WorkItems");

            _allWorkItems = new List<WorkItem>();
            foreach (WorkItem w in wc)
                _allWorkItems.Add(w);
        }

        return _allWorkItems;
    }
}

/// <summary>
/// Gets the PBI, if the workitem is a task id, it checks parents
/// </summary>
/// <param name="workItemId"></param>
/// <returns></returns>
public static WorkItem GetPbi(int workItemId)
{
    WorkItem result = AllWorkItems.FirstOrDefault(f => f.Id == workItemId);

    if (result.Type.Name == ITEM_TYPE_NAME_TASK)
    {
        result = AllWorkItems.FirstOrDefault(f => f.Id == result.WorkItemLinks[0].TargetId);
    }

    return result;
}   

工作正常:我检查一下,如果邮件项目标题中有[ID],则获取任务,如果是任务,我会获得PBI,将邮件另存为附件并添加。

但如果我尝试从outlook打开PBI,我会得到:


团队基础错误

跨线程操作无效:控制''从创建它的线程以外的线程访问。

确定

由于我正在关闭并保存工作项而不是PBI,我真的希望这会处理这些事情。

我没有为这个问题找到任何好的解决方案,因为我是一个初学者,我不知道自己能看到问题。

我的网站是否有错误,或者我的方法根本不可能?

1 个答案:

答案 0 :(得分:1)

你将不得不做一些线程工作。当您单击Outlook中的按钮时,Outlook会生成一个新线程,该线程尝试访问位于单独的threas上的兑现工作项(在您第一次调用该属性时创建的那个。

您可能需要创建拥有数据的自己的后台线程上下文。然后,当单击该按钮时,您可以将上下文封送到同一个线程上下文以执行并传回数据。

这是一个痛苦但是Outlook的发展......