I have a 3rd party library that is doing something internally that causes it to slow down greatly when the debugger is attached, even in release mode.
I have found 1
Assuming you know which instance/version of Visual Studio is attached to your process, you can detach it as follows:
object dt = Marshal.GetActiveObject("VisualStudio.DTE.12.0")
DTE dte = (DTE)dt;
dte.Debugger.DetachAll();
The "12" is for version 2013 of Visual Studio. For another version, change accordingly. This requires a reference to EnvDTE, which is usually located at C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies\EnvDTE.dll
This will dettach ALL processes from that instance of Visual Studio, so if, for whatever reason, Visual Studio was attached to other processes in addition to yours, those processes would also become detached. Furthermore, you may get unexpected results if you have more than one instance of Visual Studio opened.
To be careful to only detach the current proccess and only the right instance of Visual Studio, use the following code:
using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using EnvDTE;
public class Test
{
public static void DetachCurrentProcesses()
{
System.Diagnostics.Process[] procs = System.Diagnostics.Process.GetProcessesByName("devenv");
DTE dte = null;
foreach (System.Diagnostics.Process devenv in procs) {
do {
System.Threading.Thread.Sleep(2000);
dte = AutomateVS.GetDTE(devenv.Id);
} while (dte == null);
IEnumerable processes = dte.Debugger.DebuggedProcesses.OfType();
if (!processes.Any)
continue;
int currentID = System.Diagnostics.Process.GetCurrentProcess().Id;
processes.Where(p => p.ProcessID == currentID).ToList.ForEach(p => p.Detach(false));
Marshal.ReleaseComObject(dte);
}
}
}
///
/// Source to this class: http://blogs.msdn.com/b/kirillosenkov/archive/2011/08/10/how-to-get-dte-from-visual-studio-process-id.aspx
///
///
public class AutomateVS
{
[DllImport("ole32.dll")]
private static extern int CreateBindCtx(uint reserved, out IBindCtx ppbc);
public static DTE GetDTE(int processId)
{
string progId = "!VisualStudio.DTE.10.0:" + processId.ToString();
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.
}
if (!string.IsNullOrEmpty(name) && string.Equals(name, progId, StringComparison.Ordinal))
{
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 (DTE)runningObject;
}
}