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; } }
/// <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? } } }
/// <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); }
/// <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); }
private bool IsMatch(AttachDescriptor descriptor, Process process) { var rtn = IsProcessMatch(descriptor, process) && IsUsernameMatch(descriptor, process) && IsAppPoolMatch(descriptor, process); return(rtn); }
/// <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); }
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))); }
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)); }
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); }
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)); }