Skip to content

Instantly share code, notes, and snippets.

@nem0
Created December 16, 2019 15:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nem0/7e3147b0d38bcf52844dd5eb835091d4 to your computer and use it in GitHub Desktop.
Save nem0/7e3147b0d38bcf52844dd5eb835091d4 to your computer and use it in GitHub Desktop.
detach and attach vs debugger
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Text.RegularExpressions;
using System.Diagnostics;
using EnvDTE;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
bool attach = System.IO.File.Exists("envdte_detached.txt");
foreach (var p in System.Diagnostics.Process.GetProcesses())
{
if(p.ProcessName.Contains("devenv"))
{
DTE d = GetDTE(p.Id, 1000);
if (attach) {
int to_attach = int.Parse(System.IO.File.ReadAllText("envdte_detached.txt"));
System.IO.File.Delete("envdte_detached.txt");
foreach (var lp in d.Debugger.LocalProcesses) {
var lpp = lp as EnvDTE.Process;
int pid = lpp.ProcessID;
if (to_attach == pid) {
lpp.Attach();
return;
}
}
}
else
{
if (d.Debugger.DebuggedProcesses != null) {
foreach(var dp in d.Debugger.DebuggedProcesses) {
var dpp = dp as EnvDTE.Process;
dpp.Detach();
System.IO.File.WriteAllText("envdte_detached.txt", dpp.ProcessID.ToString());
return;
}
}
}
}
}
}
private static EnvDTE.DTE GetDTE(int processId, int timeout)
{
EnvDTE.DTE res = null;
DateTime startTime = DateTime.Now;
while (res == null && DateTime.Now.Subtract(startTime).Seconds < timeout)
{
System.Threading.Thread.Sleep(1000);
res = GetDTE(processId);
}
return res;
}
[DllImport("ole32.dll")]
private static extern int CreateBindCtx(uint reserved, out IBindCtx ppbc);
private static EnvDTE.DTE GetDTE(int processId)
{
object runningObject = null;
IBindCtx bindCtx = null;
IRunningObjectTable rot = null;
IEnumMoniker enumMonikers = null;
try
{
Marshal.ThrowExceptionForHR(CreateBindCtx(reserved: 0, ppbc: out bindCtx));
bindCtx.GetRunningObjectTable(out rot);
rot.EnumRunning(out enumMonikers);
IMoniker[] moniker = new IMoniker[1];
IntPtr numberFetched = IntPtr.Zero;
while (enumMonikers.Next(1, moniker, numberFetched) == 0)
{
IMoniker runningObjectMoniker = moniker[0];
string name = null;
try
{
if (runningObjectMoniker != null)
{
runningObjectMoniker.GetDisplayName(bindCtx, null, out name);
}
}
catch (UnauthorizedAccessException)
{
// Do nothing, there is something in the ROT that we do not have access to.
}
Regex monikerRegex = new Regex(@"!VisualStudio.DTE\.\d+\.\d+\:" + processId, RegexOptions.IgnoreCase);
if (!string.IsNullOrEmpty(name) && monikerRegex.IsMatch(name))
{
Marshal.ThrowExceptionForHR(rot.GetObject(runningObjectMoniker, out runningObject));
break;
}
}
}
finally
{
if (enumMonikers != null)
{
Marshal.ReleaseComObject(enumMonikers);
}
if (rot != null)
{
Marshal.ReleaseComObject(rot);
}
if (bindCtx != null)
{
Marshal.ReleaseComObject(bindCtx);
}
}
return runningObject as EnvDTE.DTE;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment