예제 #1
0
        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);
        }
예제 #2
0
        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();
        }
예제 #3
0
        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();
        }
예제 #4
0
        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);
        }