在下面的代码中,我试图访问Debugger
一个有效DTE2
对象的属性(通过类似于此方法的方法获得),以检查它是否正在调试当前进程(可能会打开多个Visual Studio实例)。
它工作正常,但当一个Visual Studio(2015)实例显示一个模式对话框时(例如,询问是否应由于后台代码更改而重新加载当前加载的项目的源代码),访问dte.Debugger
将一直挂起,直到出现对话框由用户处理。尝试访问该dte
对象的其他成员也将挂起。
using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; using System.Threading; using EnvDTE; using EnvDTE80; using EnvDTE90a; public static class VSAutomation { public static int? GetCurrentDebuggerPid() { var taskCompletion = new TaskCompletionSource(); var staThread = new System.Threading.Thread(() => { try { int? debuggerPid = null; using (new MessageFilter()) { using (var currentProcess = System.Diagnostics.Process.GetCurrentProcess()) using (var vsInstances = System.Diagnostics.Process.GetProcessesByName("devenv").AsDisposable()) { foreach (var p in vsInstances.Enumerable) { DTE2 dte; if (TryGetVSInstance(p.Id, out dte)) { Utils.Retry(() => { var debugger = dte.Debugger; //MAY HANG HERE if (debugger != null) { foreach (Process2 process in debugger.DebuggedProcesses) { if (process.ProcessID == currentProcess.Id) { debuggerPid = p.Id; break; } } } Marshal.ReleaseComObject(dte); }, nbRetries: int.MaxValue, msInterval: 1000, retryOnlyOnExceptionTypes: typeof(COMException).InArray()); if (debuggerPid != null) break; } } } } taskCompletion.SetResult(debuggerPid); } catch (Exception ex) { taskCompletion.TrySetException(ex); } }) { IsBackground = true }; staThread.SetApartmentState(ApartmentState.STA); staThread.Start(); taskCompletion.Task.Wait(); return taskCompletion.Task.Result; } }
Debugger
尽管打开了模式对话框,是否有任何访问对象的方法?
如果不是,除了var debugger = dte.Debugger
在具有超时的任务中启动任务之外,是否有其他方法可以检测到需要执行用户操作?