private Dictionary <Guid, string> GetTransportEngines() { var engines = new Dictionary <Guid, string>(); try { var ignoredEngines = new HashSet <Guid>(new[] { new Guid("2c18241e-069a-43b2-bd81-89c186af994b") }); foreach (Transport transport in _dteDebugger.Transports) { foreach (Engine engine in transport.Engines) { var engineId = Guid.Parse(engine.ID); if (ignoredEngines.Contains(engineId) || engines.ContainsKey(engineId)) { continue; } engines.Add(engineId, engine.Name); } } } catch (Exception e) { ReAttachUtils.ShowStartupError("Unable to get debugging engines for transports: " + e.Message); } return(engines); }
public async Task InitializeAsync(ReAttachPackage package, ReAttachHistory history, CancellationToken cancellationToken) { _history = history; await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); _ui = (await package.GetServiceAsync(typeof(ReAttachUi))) as ReAttachUi; if (_ui == null) { ReAttachUtils.ShowStartupError("Unable to obtain reference to UI."); return; } var debugger = (await package.GetServiceAsync(typeof(IVsDebugger))) as IVsDebugger; if (debugger == null) { ReAttachUtils.ShowStartupError("Unable to obtain reference to debugger."); return; } if (debugger.AdviseDebugEventCallback(this) != VSConstants.S_OK) { ReAttachUtils.ShowStartupError("Unable to subscribe on debug events."); return; } if (debugger.AdviseDebuggerEvents(this, out _cookie) != VSConstants.S_OK) { ReAttachUtils.ShowStartupError("Unable to subscribe on debugger mode changes."); return; } var dte = await package.GetServiceAsync(typeof(EnvDTE.DTE)) as DTE2; if (dte == null) { ReAttachUtils.ShowStartupError("Unable to get obtain reference to automation object model (DTE2)."); return; } _dteDebugger = dte.Debugger as Debugger2; if (_dteDebugger == null) { ReAttachUtils.ShowStartupError("Unable to get reference to debugger from automation object."); return; } _engines = GetTransportEngines(); }
public void Save() { var root = _package.UserRegistryRoot; if (root == null) { ReAttachUtils.ShowError("ReAttach save failed.", "Unable to open root key."); return; } var parent = root.CreateSubKey(ReAttachConstants.ReAttachRegistryKeyName); if (parent == null) { ReAttachUtils.ShowError("ReAttach save failed.", "Unable to open parent key."); root.Close(); return; } for (var i = 1; i <= ReAttachConstants.ReAttachHistorySize; i++) { var key = ReAttachConstants.ReAttachRegistryHistoryKeyPrefix + i; if (i <= _targets.Count) { var target = _targets[i - 1]; var json = JsonConvert.SerializeObject(target); parent.SetValue(key, json); } else { parent.DeleteValue(key, false); } } parent.Close(); root.Close(); }
public ReAttachResult ReAttach(ReAttachTarget target) { if (target == null) { return(ReAttachResult.Failed); } List <Process3> candidates; if (!target.IsLocal) { var transport = _dteDebugger.Transports.Item("Default"); var processes = _dteDebugger.GetProcesses(transport, target.ServerName).OfType <Process3>(); candidates = processes.Where(p => p.IsMatchingRemoteProcess(target)).ToList(); } else { var processes = _dteDebugger.LocalProcesses.OfType <Process3>(); candidates = processes.Where(p => p.IsMatchingLocalProcess(target)).ToList(); if (!candidates.Any()) // Do matching on processes running in exclusive mode. { candidates = processes.Where(p => p.IsMatchingExclusively(target)).ToList(); } } if (!candidates.Any()) { return(ReAttachResult.NotStarted); } Process3 process = null; // First try to use the pid. if (target.ProcessId > 0) { process = candidates.FirstOrDefault(p => p.ProcessID == target.ProcessId); } // If we don't have an exact match, just go for the highest PID matching. if (process == null) { var maxPid = candidates.Max(p => p.ProcessID); process = candidates.FirstOrDefault(p => p.ProcessID == maxPid); } if (process == null) { return(ReAttachResult.NotStarted); } try { if (target.Engines != null && target.Engines.Any()) { var engines = target.Engines.Where(e => _engines.ContainsKey(e)).Select(e => _engines[e]).ToArray(); process.Attach2(engines); } else { process.Attach(); } return(ReAttachResult.Success); } catch (COMException) { return(ReAttachResult.ElevationRequired); } catch (Exception e) { ReAttachUtils.ShowError($"Unable to ReAttach to process {process.Name} ({process.ProcessID}) based on target {target}", e.Message); } return(ReAttachResult.Failed); }