public virtual void AttachReplTest() { using (var interactive = Prepare(enableAttach: true)) { var app = interactive.App; var project = app.OpenProject(@"TestData\DebuggerProject.sln"); Assert.IsNotNull(PythonToolsPackage.GetStartupProject(app.ServiceProvider), "Startup project was not set"); Assert.IsTrue(interactive.Settings.EnableAttach, "EnableAttach was not set"); using (var dis = new DefaultInterpreterSetter(interactive.GetAnalyzer().InterpreterFactory)) { var activeDescr = app.GetService <UIThreadBase>().Invoke(() => project.GetPythonProject().GetInterpreterFactory().Configuration.Description); Assert.AreEqual(dis.CurrentDefault.Configuration.Description, activeDescr); interactive.Reset(); interactive.ClearScreen(); const string attachCmd = "$attach"; interactive.SubmitCode(attachCmd); app.OnDispose(() => { if (app.Dte.Debugger.CurrentMode != EnvDTE.dbgDebugMode.dbgDesignMode) { app.DismissAllDialogs(); try { app.ExecuteCommand("Debug.StopDebugging"); } catch (COMException) { } WaitForMode(app.Dte.Debugger, EnvDTE.dbgDebugMode.dbgDesignMode); } }); app.Dte.Debugger.Breakpoints.Add(File: "BreakpointTest.py", Line: 1); interactive.WaitForText(">" + attachCmd, ">"); WaitForMode(app.Dte.Debugger, EnvDTE.dbgDebugMode.dbgRunMode); interactive.Show(); const string import = "import BreakpointTest"; interactive.SubmitCode(import, wait: false); interactive.WaitForText(">" + attachCmd, ">" + import, ""); WaitForMode(app.Dte.Debugger, EnvDTE.dbgDebugMode.dbgBreakMode); Assert.AreEqual(EnvDTE.dbgEventReason.dbgEventReasonBreakpoint, app.Dte.Debugger.LastBreakReason); Assert.AreEqual(app.Dte.Debugger.BreakpointLastHit.FileLine, 1); app.ExecuteCommand("Debug.DetachAll"); WaitForMode(app.Dte.Debugger, EnvDTE.dbgDebugMode.dbgDesignMode); interactive.WaitForText(">" + attachCmd, ">" + import, "hello", ">"); } } }
private void Connect() { var processInfo = new ProcessStartInfo(_interpreter.Configuration.InterpreterPath); bool debugMode = Environment.GetEnvironmentVariable("DEBUG_REPL") != null; #if DEBUG processInfo.CreateNoWindow = !debugMode; processInfo.UseShellExecute = debugMode; processInfo.RedirectStandardOutput = !debugMode; processInfo.RedirectStandardError = !debugMode; #else processInfo.CreateNoWindow = true; processInfo.UseShellExecute = false; processInfo.RedirectStandardOutput = true; processInfo.RedirectStandardError = true; #endif string filename, dir; ProjectAnalyzer analyzer; if (PythonToolsPackage.TryGetStartupFileAndDirectory(out filename, out dir, out analyzer)) { processInfo.WorkingDirectory = dir; var startupProj = PythonToolsPackage.GetStartupProject(); if (startupProj != null) { string searchPath = startupProj.GetProjectProperty(CommonConstants.SearchPath, true); if (!string.IsNullOrEmpty(searchPath)) { processInfo.EnvironmentVariables[_interpreter.Configuration.PathEnvironmentVariable] = searchPath; } } } List <string> args = new List <string>() { "\"" + Path.Combine(PythonToolsPackage.GetPythonToolsInstallPath(), "visualstudio_py_repl.py") + "\"" }; if (!String.IsNullOrWhiteSpace(CurrentOptions.StartupScript)) { args.Add("--launch_file"); args.Add("\"" + CurrentOptions.StartupScript + "\""); } bool multipleScopes = true; if (!String.IsNullOrWhiteSpace(CurrentOptions.ExecutionMode)) { // change ID to module name if we have a registered mode var modes = ExecutionMode.GetRegisteredModes(); string modeValue = CurrentOptions.ExecutionMode; foreach (var mode in modes) { if (mode.Id == CurrentOptions.ExecutionMode) { modeValue = mode.Type; multipleScopes = mode.SupportsMultipleScopes; break; } } args.Add("--execution_mode"); args.Add(modeValue); } if (multipleScopes != _multipleScopes) { var multiScopeSupportChanged = MultipleScopeSupportChanged; if (multiScopeSupportChanged != null) { multiScopeSupportChanged(this, EventArgs.Empty); } _multipleScopes = multipleScopes; } processInfo.Arguments = String.Join(" ", args); _process = new Process(); _process.StartInfo = processInfo; _process.Start(); #if DEBUG string socket; if (debugMode) { socket = "5000"; } else { socket = _process.StandardOutput.ReadLine(); } #else // read what socket we should connect back to var socket = _process.StandardOutput.ReadLine(); #endif for (int i = 0; i < 10; i++) { try { // connect back to the socket _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP); _socket.Blocking = true; _socket.Connect(new IPEndPoint(IPAddress.Loopback, Int32.Parse(socket))); break; } catch (SocketException) { } } var outputThread = new Thread(OutputThread); outputThread.Name = "PythonReplEvaluator: " + _interpreter.GetInterpreterDisplay(); outputThread.Start(); if (processInfo.RedirectStandardOutput) { var readOutputThread = new Thread(ReadOutput); readOutputThread.Start(); } if (processInfo.RedirectStandardError) { var readErrorThread = new Thread(ReadError); readErrorThread.Start(); } }