I have created a Visual Studio Package that can achieve this. Here is the step-by-step guide
1. Using VS2010 create a project of type "Visual Studio Package"
2. Select language as "C#" and select "Next"
3. Specify package information and select "Next"
4. Now select "Menu Command" and "Tool Window" and select "Next"
5. Specify command options, tool window options and select "Next"
6. De-select test project options and select "Finish". Now we have completed creating a new package project.
7. Add TFS references to the project
8. Make following code changes
VS2010.TFSHelperPackage.GuidList Class
.. public const string guidVSPackage1CmdSetString2 = "6E282364-7C4B-4E12-868D-AC8572708416"; .. public static readonly Guid guidVSPackage1CmdSet2 = new Guid(guidVSPackage1CmdSetString2); ..
VS2010.TFSHelperPackage.PkgCmdIDList Class
.. public const uint cmdidCopyWorkItemAdvanced = 0x100; ..TFSHelperPackage Class -> Initialize()
protected override void Initialize() { .... // Create the command for the menu item. CommandID menuCommandID2 = new CommandID(GuidList.guidVSPackage1CmdSet2, (int)PkgCmdIDList.cmdidCopyWorkItemAdvanced); MenuCommand menuItem2 = new MenuCommand(CopyWorkItemAdvancedCallback, menuCommandID2); mcs.AddCommand(menuItem2); .. } private void CopyWorkItemAdvancedCallback(object sender, EventArgs e) {}
Update "TFSHelperPackage.vsct"
.... .... .. ... ... ...
Now GuidSymbol name="guidTFSContextMenu" is very important as value "517" is the id for "Results List" menu item. Refer to Using EnableVSIPLogging to identify menus and commands with VS 2005 + SP1 to find out Menu command Id/GUIDs.
9. Add a new windows form as follows
10. Now update CopyWorkItemAdvancedCallback with following code
private void CopyWorkItemAdvancedCallback(object sender, EventArgs e) { using(CopyWorkItemAdvancedForm cw = new CopyWorkItemAdvancedForm(this)) { if(cw.ShowDialog() == System.Windows.Forms.DialogResult.OK) { cw.Close(); } } }
11. Update CopyWorkItemAdvancedForm code behind as follows
public partial class CopyWorkItemAdvancedForm : Form { private IServiceProvider _serviceProvider; private IWorkItemTrackingDocument _currentDocument; private WorkItem _currentWorkItem; private WorkItem _newWorkItem; private WorkItemStore _workItemStore; public CopyWorkItemAdvancedForm(IServiceProvider serviceProvider) { InitializeComponent(); _serviceProvider = serviceProvider; LoadControls(); } private void LoadControls() { this.cmbProjects.Items.Clear(); this.cmbWorkItemTypes.Items.Clear(); //Load source workitem _currentDocument = WitDocumentHelper.GetCurrentWitDocument(_serviceProvider); string selectedItemId = string.Empty; if (_currentDocument is IResultsDocument) { int cnt = ((IResultsDocument)_currentDocument).SelectedItemIds.Length; if (cnt > 0) { IResultsDocument resultDocument = (IResultsDocument)_currentDocument; selectedItemId = resultDocument.SelectedItemIds[0].ToString(); _currentWorkItem = resultDocument.ResultListDataProvider.GetItem(0); } } else if (_currentDocument is IWorkItemDocument) { // To be completed } else if (_currentDocument is IQueryDocument) { // To be completed } else { // To be completed } this.Text = "Create Copy of Work Item with options ... [ " + selectedItemId + "]"; //Load dropdowns var dte = Package.GetGlobalService(typeof(EnvDTE.DTE)) as EnvDTE.DTE; TeamFoundationServerExt ext = dte.GetObject("Microsoft.VisualStudio.TeamFoundation.TeamFoundationServerExt") as TeamFoundationServerExt; TfsTeamProjectCollection teamProjectCollection = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri(ext.ActiveProjectContext.DomainUri)); // Refer to http://msdn.microsoft.com/en-us/library/bb286958.aspx for list of types available with GetService _workItemStore = teamProjectCollection.GetService(); if (_workItemStore != null) { if (_workItemStore.Projects.Count > 0) { foreach (Project prj in _workItemStore.Projects) { this.cmbProjects.Items.Add(prj.Name); if (this.cmbWorkItemTypes.Items.Count == 0) { foreach (WorkItemType wtype in prj.WorkItemTypes) { string wtypeName = wtype.Name; if (!this.cmbWorkItemTypes.Items.Contains(wtypeName)) this.cmbWorkItemTypes.Items.Add(wtypeName); } } } } } this.cmbWorkItemTypes.SelectedIndex = this.cmbWorkItemTypes.Items.IndexOf(_currentWorkItem.Type.Name); } private void btnOk_Click(object sender, EventArgs e) { if (_currentWorkItem != null) { CreateNewWorkItem(); string message = string.Format("Copied Item Successfully !!! \r\n Source Item ID {0} has {1} Attachments and {2} Links \r\n\r\n Target Item ID {3} has {4} Attachments and {5} Links", _currentWorkItem.Id, _currentWorkItem.Attachments.Count, _currentWorkItem.Links.Count, _newWorkItem.Id, _newWorkItem.Attachments.Count, _newWorkItem.Links.Count); MessageBox.Show(message, this.Text, MessageBoxButtons.OK); } this.DialogResult = System.Windows.Forms.DialogResult.OK; } private void CreateNewWorkItem() { Project targetProject = _workItemStore.Projects[this.cmbProjects.SelectedItem.ToString()]; WorkItemType wit = targetProject.WorkItemTypes[this.cmbWorkItemTypes.SelectedItem.ToString()]; _newWorkItem = _currentWorkItem.Copy(wit); RelatedLink source2Target = new RelatedLink(targetProject.Id); _newWorkItem.Links.Add(source2Target); System.Net.WebClient request = new System.Net.WebClient(); request.Credentials = System.Net.CredentialCache.DefaultCredentials; string tempPath = System.IO.Path.GetTempPath(); if (_currentWorkItem.Attachments.Count > 0) { foreach (Attachment attach in _currentWorkItem.Attachments) { string attachmentPath = Path.Combine(tempPath, attach.Name); request.DownloadFile(attach.Uri, attachmentPath); _newWorkItem.Attachments.Add(new Attachment(attachmentPath)); } } _newWorkItem.Save(SaveFlags.MergeLinks); } private void btnCancel_Click(object sender, EventArgs e) { this.DialogResult = System.Windows.Forms.DialogResult.Cancel; } }
12. Also add a new helper class WitDocumentHelper
class WitDocumentHelper { public static IWorkItemTrackingDocument GetCurrentWitDocument(IServiceProvider serviceProvider) { Debug.Assert(serviceProvider != null); EnvDTE.DTE dte = (EnvDTE.DTE)serviceProvider.GetService(typeof(EnvDTE.DTE)); if (dte.ActiveDocument == null) return null; // No active document DocumentService docService = (DocumentService)serviceProvider.GetService(typeof(DocumentService)); if (docService == null) return null; // Possibly VSTS WIT is not installed or instantiated yet. IWorkItemTrackingDocument doc = docService.FindDocument(dte.ActiveDocument.FullName, serviceProvider); return doc; // Caller must release the document after use } }
This completes the task of creating a package to copy workitem between projects. Complete source code is available on Git via codeplex at tfshelperforvs2010.codeplex.com.
All of the biggest technological inventions created by man - the airplane, the automobile, the computer - says little about his intelligence, but speaks volumes about his laziness. ~Mark Kennedy
Great Article
ReplyDeleteASP.NET MVC Training
Online MVC Training
Online MVC Training India
Dot Net Training in Chennai
.Net Online Training
.net training online
Dot Net Online Training