public static VisualStudioDebugger GetAttached()
        {
            if (!System.Diagnostics.Debugger.IsAttached)
            {
                return(null);
            }

            var context = new STAContext();

            var instance = GetFirstOrDefaultDTE(context, x =>
            {
                // Try multiple time, as DTE might report it is busy
                var debugger = x.DTE.Debugger;
                if (debugger.DebuggedProcesses == null)
                {
                    return(false);
                }

                return(debugger.DebuggedProcesses.OfType <EnvDTE.Process>().Any(debuggedProcess => debuggedProcess.ProcessID == System.Diagnostics.Process.GetCurrentProcess().Id));
            });

            if (instance.DTE == null)
            {
                context.Dispose();
                return(null);
            }

            return(new VisualStudioDebugger(context, instance.DTE, instance.ProcessId));
        }
        public static VisualStudioDebugger GetByProcess(int processId)
        {
            var context = new STAContext();

            var instance = GetFirstOrDefaultDTE(context, x => x.ProcessId == processId);

            if (instance.DTE == null)
            {
                context.Dispose();
                return(null);
            }

            return(new VisualStudioDebugger(context, instance.DTE, instance.ProcessId));
        }
        private static VisualStudioDTE.Instance GetFirstOrDefaultDTE(STAContext context, Func <VisualStudioDTE.Instance, bool> predicate)
        {
            return(context.Execute(() =>
            {
                // Locate all Visual Studio DTE
                var dtes = VisualStudioDTE.GetActiveDTEs().ToArray();

                // Find DTE
                MessageFilter.Register();
                var result = dtes.FirstOrDefault(predicate);
                MessageFilter.Revoke();

                return result;
            }));
        }
 private VisualStudioDebugger(STAContext context, DTE dte, int processId)
 {
     this.context   = context;
     this.dte       = dte;
     this.ProcessId = processId;
 }