internal static void SkipInitialDebugBreak(uint dwProcessId) { if (!NativeDebuggingMethods.DebugActiveProcess(dwProcessId)) { throw new LastWin32Exception(); } try { bool done = false; uint mainThread = 0; while (!done) { dynamic debugEvent = null; if (!WaitForDebugEvent(ref debugEvent, (int)TimeSpan.FromSeconds(10).TotalMilliseconds)) { throw new LastWin32Exception(); } switch ((NativeDebugEventCode)debugEvent.header.dwDebugEventCode) { case NativeDebugEventCode.CREATE_PROCESS_DEBUG_EVENT: new SafeFileHandle(debugEvent.union.CreateProcess.hFile, true).Dispose(); break; case NativeDebugEventCode.LOAD_DLL_DEBUG_EVENT: new SafeFileHandle(debugEvent.union.LoadDll.hFile, true).Dispose(); break; case NativeDebugEventCode.EXCEPTION_DEBUG_EVENT: case NativeDebugEventCode.EXIT_PROCESS_DEBUG_EVENT: mainThread = debugEvent.header.dwThreadId; done = true; break; } if (!NativeDebuggingMethods.ContinueDebugEvent(debugEvent.header.dwProcessId, debugEvent.header.dwThreadId, NativeDebuggingMethods.ContinueStatus.DBG_CONTINUE)) { throw new LastWin32Exception(); } } SuspendThread(new IntPtr(mainThread)); } finally { if (!NativeDebuggingMethods.DebugActiveProcessStop(dwProcessId)) { throw new LastWin32Exception(); } } }
/// <summary> /// Stop debugging the specified process (detach) /// </summary> /// <param name="process">process to detach from</param> /// <remarks>After detaching, the process is removed from the caches and can not be accessed. If detaching at a debug /// event, do not call Continue on the event. </remarks> public void Detach(NativeDbgProcess process) { if (process == null) { throw new ArgumentNullException("process"); } EnsureIsOnWin32EventThread(); int pid = process.Id; bool fDetachOk = NativeMethods.DebugActiveProcessStop((uint)pid); if (!fDetachOk) { int err = Marshal.GetLastWin32Error(); throw new InvalidOperationException("Failed to detach to process " + pid + "error=" + err); } RemoveProcess(pid); }