public bool AttachToProcess(ProcessOutput proc, Guid portSupplier, string transportQualifierUri) { var debugger3 = (EnvDTE90.Debugger3)DTE.Debugger; var transports = debugger3.Transports; EnvDTE80.Transport transport = null; for (int i = 1; i <= transports.Count; ++i) { var t = transports.Item(i); if (Guid.Parse(t.ID) == portSupplier) { transport = t; break; } } if (transport == null) { return false; } var processes = debugger3.GetProcesses(transport, transportQualifierUri); if (processes.Count < 1) { return false; } // Retry the attach itself 3 times before displaying a Retry/Cancel // dialog to the user. DTE.SuppressUI = true; try { try { processes.Item(1).Attach(); return true; } catch (COMException) { if (proc.Wait(TimeSpan.FromMilliseconds(500))) { // Process exited while we were trying return false; } } } finally { DTE.SuppressUI = false; } // Another attempt, but display UI. processes.Item(1).Attach(); return true; }
private void RunTestCase(VisualStudioApp app, IFrameworkHandle frameworkHandle, IRunContext runContext, TestCase test, Dictionary<string, NodejsProjectSettings> sourceToSettings) { var testResult = new TestResult(test); frameworkHandle.RecordStart(test); testResult.StartTime = DateTimeOffset.Now; NodejsProjectSettings settings; if (!sourceToSettings.TryGetValue(test.Source, out settings)) { sourceToSettings[test.Source] = settings = LoadProjectSettings(test.Source); } if (settings == null) { frameworkHandle.SendMessage( TestMessageLevel.Error, "Unable to determine interpreter to use for " + test.Source); RecordEnd( frameworkHandle, test, testResult, null, "Unable to determine interpreter to use for " + test.Source, TestOutcome.Failed); return; } NodejsTestInfo testInfo = new NodejsTestInfo(test.FullyQualifiedName); List<string> args = new List<string>(); int port = 0; if (runContext.IsBeingDebugged && app != null) { app.GetDTE().Debugger.DetachAll(); args.AddRange(GetDebugArgs(settings, out port)); } var workingDir = Path.GetDirectoryName(CommonUtils.GetAbsoluteFilePath(settings.WorkingDir, testInfo.ModulePath)); args.AddRange(GetInterpreterArgs(test, workingDir, settings.ProjectRootDir)); //Debug.Fail("attach debugger"); if (!File.Exists(settings.NodeExePath)) { frameworkHandle.SendMessage(TestMessageLevel.Error, "Interpreter path does not exist: " + settings.NodeExePath); return; } lock (_syncObject) { _nodeProcess = ProcessOutput.Run( settings.NodeExePath, args, workingDir, null, false, null, false); #if DEBUG frameworkHandle.SendMessage(TestMessageLevel.Informational, "cd " + workingDir); frameworkHandle.SendMessage(TestMessageLevel.Informational, _nodeProcess.Arguments); #endif _nodeProcess.Wait(TimeSpan.FromMilliseconds(500)); if (runContext.IsBeingDebugged && app != null) { try { //the '#ping=0' is a special flag to tell VS node debugger not to connect to the port, //because a connection carries the consequence of setting off --debug-brk, and breakpoints will be missed. string qualifierUri = string.Format("tcp://localhost:{0}#ping=0", port); while (!app.AttachToProcess(_nodeProcess, NodejsRemoteDebugPortSupplierUnsecuredId, qualifierUri)) { if (_nodeProcess.Wait(TimeSpan.FromMilliseconds(500))) { break; } } #if DEBUG } catch (COMException ex) { frameworkHandle.SendMessage(TestMessageLevel.Error, "Error occurred connecting to debuggee."); frameworkHandle.SendMessage(TestMessageLevel.Error, ex.ToString()); KillNodeProcess(); } #else } catch (COMException) { frameworkHandle.SendMessage(TestMessageLevel.Error, "Error occurred connecting to debuggee."); KillNodeProcess(); } #endif } }
public bool AttachToProcess(ProcessOutput processOutput, EnvDTE.Process process, Guid[] engines = null) { // Retry the attach itself 3 times before displaying a Retry/Cancel // dialog to the user. var dte = GetDTE(); dte.SuppressUI = true; try { try { if (engines == null) { process.Attach(); } else { var process3 = process as EnvDTE90.Process3; if (process3 == null) { return false; } process3.Attach2(engines.Select(engine => engine.ToString("B")).ToArray()); } return true; } catch (COMException) { if (processOutput.Wait(TimeSpan.FromMilliseconds(500))) { // Process exited while we were trying return false; } } } finally { dte.SuppressUI = false; } // Another attempt, but display UI. process.Attach(); return true; }