/// <summary> /// 現在のプロセスを指定したデバッガーにアタッチします。 /// </summary> /// <param name="debuggerInfo">現在のプロセスをアタッチするデバッガー情報。</param> /// <returns>アタッチに成功した場合は<c>True</c>。その他の場合は<c>False</c>。</returns> public static bool AttachTo(DebuggerInfo debuggerInfo) { if (debuggerInfo == null) { return(false); } if (Debugger.IsAttached) { return(false); } lock (_Providers) { foreach (var p in _Providers) { if (p.AttachToType(debuggerInfo)) { return(true); } } } return(false); }
/// <summary> /// 派生クラスで実装された場合、現在のプロセスを指定したデバッガーにアタッチします。 /// </summary> /// <param name="debuggerInfo">現在のプロセスをアタッチするデバッガー情報。</param> /// <returns><paramref name="debuggerInfo" />が現在のインスタンスのデバッガー情報で、アタッチに成功した場合は<c>True</c>。その他の場合は<c>False</c>。</returns> public abstract bool AttachToType(DebuggerInfo debuggerInfo);
/// <summary> /// Visual Studioデバッガーにアタッチします。 /// </summary> /// <param name="debuggerInfo">現在のプロセスをアタッチするデバッガー情報。</param> /// <returns><paramref name="debuggerInfo" />がVisual Studioのデバッガー情報で、アタッチに成功した場合は<c>True</c>。その他の場合は<c>False</c>。</returns> public override bool AttachToType(DebuggerInfo debuggerInfo) { if (debuggerInfo == null || debuggerInfo.DebuggerType != typeof(VisualStudioDebuggerInfoProvider) || !(debuggerInfo.ProcessId > 0)) { return(false); } IBindCtx bc = null; IRunningObjectTable rot = null; IEnumMoniker enumMoniker = null; try { var r = NativeMethods.CreateBindCtx(0, out bc); Marshal.ThrowExceptionForHR(r); if (bc == null) { throw new Win32Exception(); } bc.GetRunningObjectTable(out rot); if (rot == null) { throw new Win32Exception(); } rot.EnumRunning(out enumMoniker); if (enumMoniker == null) { throw new Win32Exception(); } var cp = Process.GetCurrentProcess().Id; var dteSuffix = ":" + debuggerInfo.ProcessId; var moniker = new IMoniker[1]; while (enumMoniker.Next(1, moniker, IntPtr.Zero) == 0 && moniker[0] != null) { string dn; moniker[0].GetDisplayName(bc, null, out dn); if (dn.StartsWith("!VisualStudio.DTE.") && dn.EndsWith(dteSuffix)) { object dte, dbg, lps; rot.GetObject(moniker[0], out dte); for (var i = 0; i < 10; i++) { try { dbg = dte.GetType().InvokeMember("Debugger", BindingFlags.GetProperty, null, dte, null); lps = dbg.GetType().InvokeMember("LocalProcesses", BindingFlags.GetProperty, null, dbg, null); var lpn = (System.Collections.IEnumerator)lps.GetType().InvokeMember("GetEnumerator", BindingFlags.InvokeMethod, null, lps, null); while (lpn.MoveNext()) { var pn = Convert.ToInt32(lpn.Current.GetType().InvokeMember("ProcessID", BindingFlags.GetProperty, null, lpn.Current, null)); if (pn == cp) { lpn.Current.GetType().InvokeMember("Attach", BindingFlags.InvokeMethod, null, lpn.Current, null); return(true); } } } catch (COMException) { Thread.Sleep(250); } } Marshal.ReleaseComObject(moniker[0]); break; } Marshal.ReleaseComObject(moniker[0]); } return(false); } finally { if (enumMoniker != null) { Marshal.ReleaseComObject(enumMoniker); } if (rot != null) { Marshal.ReleaseComObject(rot); } if (bc != null) { Marshal.ReleaseComObject(bc); } } }