Beispiel #1
0
 /// <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);
 }
Beispiel #2
0
 /// <summary>
 /// 派生クラスで実装された場合、現在のプロセスを指定したデバッガーにアタッチします。
 /// </summary>
 /// <param name="debuggerInfo">現在のプロセスをアタッチするデバッガー情報。</param>
 /// <returns><paramref name="debuggerInfo" />が現在のインスタンスのデバッガー情報で、アタッチに成功した場合は<c>True</c>。その他の場合は<c>False</c>。</returns>
 public abstract bool AttachToType(DebuggerInfo debuggerInfo);
Beispiel #3
0
        /// <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);
                }
            }
        }