Example #1
0
        private void UpdateDTEDebuggerProcessAndThread()
        {
            EnvDTE.Process dteActiveProcess = null;
            foreach (EnvDTE.Process dteProcess in _serviceProvider.GetDTE().Debugger.DebuggedProcesses)
            {
                if (dteProcess.ProcessID == _process.Id)
                {
                    dteActiveProcess = dteProcess;
                    break;
                }
            }

            if (dteActiveProcess != _serviceProvider.GetDTE().Debugger.CurrentProcess)
            {
                _serviceProvider.GetDTE().Debugger.CurrentProcess = dteActiveProcess;
            }

            EnvDTE.Thread dteActiveThread = null;
            foreach (EnvDTE.Thread dteThread in _serviceProvider.GetDTE().Debugger.CurrentProgram.Threads)
            {
                if (_threadIdMapper.GetPythonThreadId((uint)dteThread.ID) == _threadId)
                {
                    dteActiveThread = dteThread;
                    break;
                }
            }

            if (dteActiveThread != _serviceProvider.GetDTE().Debugger.CurrentThread)
            {
                _serviceProvider.GetDTE().Debugger.CurrentThread = dteActiveThread;
            }
        }
Example #2
0
        /// <summary>
        /// Attempts to load the specified process into a debugger using the specified debug engine
        /// and the best debugger available.
        /// If any instance of Visual Studio process is already associated with the current
        /// (calling) process, then that instance's debugger is targetd.
        /// Otherwise, the any first instance of Visual Studio is targetd.
        /// </summary>
        /// <param name="subjectProcessId">Id of the process to be debugged.</param>
        /// <param name="debugEngine">Name of the debugger script engine to use e.g. "script" or "native" or "managed".</param>
        public static void DebugAttachToProcess(int subjectProcessId, string debugEngine)
        {
            // Register COM message filter on this thd to enforce a call retry policy
            // should our COM calls into the DTE (in another apartment) be rejected.
            using (var mf = new ResilientMessageFilterScope())
            {
                EnvDTE.DTE dte = GetAllDTEs().FirstOrDefault(x => ProcessExtensions.IsProcessAAncestorOfProcessB(x.Key, Process.GetCurrentProcess().Id)).Value;
                if (dte == null)
                {
                    dte = GetAllDTEs().FirstOrDefault().Value;
                }

                IEnumerable <EnvDTE.Process> processes = dte.Debugger.LocalProcesses.OfType <EnvDTE.Process>();
                EnvDTE.Process process = processes.SingleOrDefault(x => x.ProcessID == subjectProcessId);
                // A.
                if (process != null)
                {
                    EnvDTE80.Process2 p2 = (EnvDTE80.Process2)process;
                    p2.Attach2(debugEngine);
                }
                // B.
                else
                {
                    throw new InvalidOperationException("Unable to debug the process: Visual Studio debugger not found.");
                    // TODO: spin up an instance of Visual Studio in this case?
                }
            }
        }
Example #3
0
        /// <inheritdoc />
        public DetachDebuggerResult DetachFromProcess(Process process)
        {
            if (process == null)
            {
                throw new ArgumentNullException("process");
            }

            DetachDebuggerResult result = DetachDebuggerResult.AlreadyDetached;

            try
            {
                IVisualStudio visualStudio = GetVisualStudio(false, logger);
                if (visualStudio != null)
                {
                    visualStudio.Call(dte =>
                    {
                        EnvDTE.Process dteProcess = FindProcess(dte.Debugger.DebuggedProcesses, process);
                        if (dteProcess != null)
                        {
                            dteProcess.Detach(false);
                            result = DetachDebuggerResult.Detached;
                        }
                    });
                }
            }
            catch (VisualStudioException ex)
            {
                result = DetachDebuggerResult.CouldNotDetach;

                logger.Log(LogSeverity.Debug, "Failed to detach Visual Studio debugger from process.", ex);
            }

            return(result);
        }
Example #4
0
        /// <inheritdoc />
        public bool IsAttachedToProcess(Process process)
        {
            if (process == null)
            {
                throw new ArgumentNullException("process");
            }

            bool result = false;

            try
            {
                // TODO: Consider all instances of Visual Studio if not attached to a particular one.
                IVisualStudio visualStudio = GetVisualStudio(false, logger);
                if (visualStudio == null)
                {
                    return(false);
                }

                visualStudio.Call(dte =>
                {
                    EnvDTE.Process dteProcess = FindProcess(dte.Debugger.DebuggedProcesses, process);
                    if (dteProcess != null)
                    {
                        result = true;
                    }
                });
            }
            catch (VisualStudioException ex)
            {
                logger.Log(LogSeverity.Debug, "Failed to detect whether Visual Studio debugger was attached to process.", ex);
            }

            return(result);
        }
Example #5
0
        private bool IsMatch(AttachDescriptor descriptor, Process process)
        {
            var rtn = IsProcessMatch(descriptor, process) &&
                      IsUsernameMatch(descriptor, process) &&
                      IsAppPoolMatch(descriptor, process);

            return(rtn);
        }
Example #6
0
        /// <inheritdoc />
        public AttachDebuggerResult AttachToProcess(Process process)
        {
            if (process == null)
            {
                throw new ArgumentNullException("process");
            }

            AttachDebuggerResult result = AttachDebuggerResult.CouldNotAttach;

            try
            {
                IVisualStudio visualStudio = GetVisualStudio(true, logger);
                if (visualStudio != null)
                {
                    visualStudio.Call(dte =>
                    {
                        EnvDTE.Process dteProcess = FindProcess(dte.Debugger.DebuggedProcesses, process);
                        if (dteProcess != null)
                        {
                            result = AttachDebuggerResult.AlreadyAttached;
                        }
                        else
                        {
                            dteProcess = FindProcess(dte.Debugger.LocalProcesses, process);
                            if (dteProcess != null)
                            {
                                Process2 dteProcess2   = dteProcess as Process2;
                                Debugger2 dteDebugger2 = dte.Debugger as Debugger2;
                                if (dteProcess2 != null && dteDebugger2 != null)
                                {
                                    IList <Guid> engineGuids = GetEngineGuids();
                                    Engine[] engines         = GetEngines(dteDebugger2, engineGuids);
                                    dteProcess2.Attach2(engines);
                                }
                                else
                                {
                                    dteProcess.Attach();
                                }

                                result = AttachDebuggerResult.Attached;
                            }
                            else
                            {
                                logger.Log(LogSeverity.Debug, "Failed to attach Visual Studio debugger to process because it was not found in the LocalProcesses list.");
                            }
                        }
                    });
                }
            }
            catch (VisualStudioException ex)
            {
                logger.Log(LogSeverity.Debug, "Failed to attach Visual Studio debugger to process.", ex);
            }

            return(result);
        }
Example #7
0
        protected bool IsProcessMatch(AttachDescriptor descriptor, Process process)
        {
            if (descriptor.ProcessNames.Any() == false)
            {
                return(true);
            }

            return(descriptor.IsProcessNamesRegex
                                ? descriptor.ProcessNameRegexes.Any(rgx => rgx.IsMatch(process.Name))
                                : descriptor.ProcessNames.Any(name => process.Name.EndsWith(name, StringComparison.OrdinalIgnoreCase)));
        }
Example #8
0
        protected bool IsUsernameMatch(AttachDescriptor descriptor, Process process)
        {
            if (string.IsNullOrEmpty(descriptor.Username))
            {
                return(true);
            }

            var procOwner = process.GetProcessUser();

            if (procOwner == null)
            {
                return(true);
            }

            return(descriptor.IsProcessNamesRegex
                                ? descriptor.UsernameRegex.IsMatch(procOwner)
                                : procOwner.EndsWith(descriptor.Username, StringComparison.OrdinalIgnoreCase));
        }
Example #9
0
        private static bool AttachToProcess(Process processOutput, EnvDTE.Process process, Guid[] engines = null)
        {
            // Retry the attach itself 3 times before displaying a Retry/Cancel
            // dialog to the user.
            var dte = process.DTE;

            dte.SuppressUI = true;
            try {
                try {
                    if (engines == null)
                    {
                        process.Attach();
                    }
                    else
                    {
                        var process3 = process as EnvDTE90.Process3;
                        if (process3 == null)
                        {
                            return(false);
                        }
                        process3.Attach2(engines.Select(engine => engine.ToString("B")).ToArray());
                    }
                    return(true);
                } catch (COMException) {
                    if (processOutput.WaitForExit(500))
                    {
                        // Process exited while we were trying
                        return(false);
                    }
                }
            } finally {
                dte.SuppressUI = false;
            }

            // Another attempt, but display UI.
            process.Attach();
            return(true);
        }
Example #10
0
        protected bool IsAppPoolMatch(AttachDescriptor descriptor, Process process)
        {
            if (string.IsNullOrEmpty(descriptor.AppPool))
            {
                return(true);
            }

            if (process.IsIISWorkerProcess() == false)
            {
                // not IIS
                return(true);
            }

            var appPoolName = process.GetAppPoolName();

            if (appPoolName == null)
            {
                return(false);
            }

            return(descriptor.IsAppPoolRegex
                                ? descriptor.AppPoolRegex.IsMatch(appPoolName)
                                : appPoolName.EndsWith(descriptor.AppPool, StringComparison.OrdinalIgnoreCase));
        }