public override void ShowInExplorer(string serverItem) { if (!String.IsNullOrEmpty(serverItem)) { Assembly tfsVC = TfsVersionControlAssembly; // if the tool window hasn't been opened yet "explorer" will be null, so we make sure it has opened at least once via ExecuteCommand DTEInstance.ExecuteCommand("View.TfsSourceControlExplorer"); Type explorer = tfsVC.GetType("Microsoft.VisualStudio.TeamFoundation.VersionControl.ToolWindowSccExplorer"); var prop = explorer.GetProperty("Instance", BindingFlags.NonPublic | BindingFlags.Static); object toolWindowSccExplorerInstance = prop.GetValue(null, null); if (toolWindowSccExplorerInstance != null) { var navMethod = toolWindowSccExplorerInstance.GetType().GetMethod("Navigate", BindingFlags.Default | BindingFlags.Instance | BindingFlags.NonPublic); if (navMethod != null) { navMethod.Invoke(toolWindowSccExplorerInstance, new object[] { serverItem }); dynamic dynEx = new AccessPrivateWrapper(toolWindowSccExplorerInstance); dynamic x2 = new AccessPrivateWrapper(dynEx.SccExplorer); DispatchScrollToSccExplorerSelection(ScrollToDispatchLagTime, x2); } } } }
virtual public void DispatchOpenSceToPath(string serverPath, object workspace) { /* In VS2013 (unlike VS2010) the Source Control Explorer opens asynchronously. This caused an issue that when * the SCE was not open and "Locate in TFS" was clicked we would not be able to open the SCE to the correct place * because it hadn't finished opening and connecting. * * There aren't any obvious events to which to subscribe, thus we do some polling in a separate thread via * the Dispatcher. It has to be a separate thread in order to not block the SCE from loading. * */ // This will make sure the SCE window is open, or will open dynamic sccToolWindow = new AccessPrivateWrapper(HatterasPackage._wrapped.GetToolWindowSccExplorer(true)); dynamic explorer = new AccessPrivateWrapper(sccToolWindow.SccExplorer); // We don't want to loop infinitely, if we've tried a few times and it's still not connected then just give up // By default this will be about five seconds (10 attempts, 0.5 seconds interval) var poller = new DispatchedPoller(MaxDispatchAttempts, DispatchPollTime, () => { return !explorer.IsDisconnected; }, () => { // The explorer is connected, so we're ready to go OpenSceToPathWithPrecedingCall(serverPath, workspace, explorer); }); poller.Go(); }