/// <summary> /// Attempts to load the specified process into a debugger using the specified debug engine /// and the best debugger available. /// If any instance of Visual Studio process is already associated with the current /// (calling) process, then that instance's debugger is targetd. /// Otherwise, the any first instance of Visual Studio is targetd. /// </summary> /// <param name="subjectProcessId">Id of the process to be debugged.</param> /// <param name="debugEngine">Name of the debugger script engine to use e.g. "script" or "native" or "managed".</param> public static void DebugAttachToProcess(int subjectProcessId, string debugEngine) { // Register COM message filter on this thd to enforce a call retry policy // should our COM calls into the DTE (in another apartment) be rejected. using (var mf = new ResilientMessageFilterScope()) { EnvDTE.DTE dte = GetAllDTEs().FirstOrDefault(x => ProcessExtensions.IsProcessAAncestorOfProcessB(x.Key, Process.GetCurrentProcess().Id)).Value; if (dte == null) { dte = GetAllDTEs().FirstOrDefault().Value; } IEnumerable <EnvDTE.Process> processes = dte.Debugger.LocalProcesses.OfType <EnvDTE.Process>(); EnvDTE.Process process = processes.SingleOrDefault(x => x.ProcessID == subjectProcessId); // A. if (process != null) { EnvDTE80.Process2 p2 = (EnvDTE80.Process2)process; p2.Attach2(debugEngine); } // B. else { throw new InvalidOperationException("Unable to debug the process: Visual Studio debugger not found."); // TODO: spin up an instance of Visual Studio in this case? } } }
private static bool TryAttach(EnvDTE80.Process2 process, string[] engines) { try { process.Attach2(engines); return(true); } catch { return(false); } }
private void AttachToW3wp(List <int> currentWorkerProcess) { EnvDTE80.Debugger2 dbg2 = _applicationObject.Debugger as EnvDTE80.Debugger2; EnvDTE80.Transport transport = dbg2.Transports.Item("Default"); EnvDTE80.Engine dbgEngine = null; string targetVersion = GetFrameworkVersion(); Trace.WriteLine("Attach Debug Engine: " + targetVersion); foreach (EnvDTE80.Engine item in transport.Engines) { if (item.Name.IndexOf(targetVersion) != -1) { dbgEngine = item; break; } } if (dbgEngine == null) { ShowMessage("Can't determine project's TargetFrameworkVersion - " + targetVersion); return; } Trace.WriteLine("Debug Engine Type: " + dbgEngine.Name); EnvDTE80.Process2 w3wpProcess = null; foreach (var proc in dbg2.LocalProcesses) { EnvDTE80.Process2 process = proc as EnvDTE80.Process2; if (process == null) { continue; } // Skip process in recycle. if (currentWorkerProcess.Contains(process.ProcessID) == true) { continue; } if (process.Name.IndexOf("W3WP.EXE", 0, StringComparison.OrdinalIgnoreCase) != -1) { w3wpProcess = process; break; } } if (w3wpProcess != null) { bool attached = false; string txt = string.Format("{0}({1})", w3wpProcess.Name, w3wpProcess.ProcessID); System.Diagnostics.Trace.WriteLine("Attaching to: " + txt); try { // I don't know why Attach2 method hang // when Visual Studio 2013 try to attach w3wp.exe hosting .NET 2.0/3.0/3.5 Web Application. if (targetVersion == "v2.0") { w3wpProcess.Attach(); } else { w3wpProcess.Attach2(dbgEngine); } attached = true; System.Diagnostics.Trace.WriteLine("Attached to: " + txt); } catch { } if (attached == true) { string startupUrl = GetProjectItemValue("WebApplication.IISUrl"); if (string.IsNullOrEmpty(startupUrl) == false) { RunInternetExplorer(startupUrl); } } } else { ShowMessage("Make sure the AppPool's Start Mode is AlwaysRunning"); } }