protected override async Task <CommandProcessorThread> ConnectAsync(CancellationToken ct) { var remoteProcess = _process as PythonRemoteProcess; try { _serviceProvider.GetPythonToolsService().Logger.LogEvent(Logging.PythonLogEvent.DebugRepl, new Logging.DebugReplInfo { RemoteProcess = remoteProcess != null, Version = _process.LanguageVersion.ToVersion().ToString() }); } catch (Exception ex) { Debug.Fail(ex.ToUnhandledExceptionMessage(GetType())); } if (remoteProcess == null) { var conn = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP); conn.Bind(new IPEndPoint(IPAddress.Loopback, 0)); conn.Listen(0); var portNum = ((IPEndPoint)conn.LocalEndPoint).Port; var proc = System.Diagnostics.Process.GetProcessById(_process.Id); var thread = CommandProcessorThread.Create(this, conn, proc); await _process.ConnectReplAsync(portNum); return(thread); } // Ignore SSL errors, since user was already prompted about them and chose to ignore them when he attached to this process. using (var debugConn = await remoteProcess.ConnectAsync(false, ct)) { // After the REPL attach response is received, we go from // using the debugger protocol to the REPL protocol. // It's important to have a clean break between the 2, and at the right time. // The server will send the debugger protocol response for attach // before sending anything else and as soon as we read that // response, we stop reading any more messages. // Then we give the stream to the REPL protocol handler. try { var response = await debugConn.SendRequestAsync(new LDP.RemoteReplAttachRequest(), ct, resp => { Debug.WriteLine("Stopping debug connection message processing. Switching from debugger protocol to REPL protocol."); // This causes the message handling loop to exit throw new OperationCanceledException(); }); if (!response.accepted) { WriteError(Strings.ConnErrorMessages_RemoteAttachRejected); return(null); } // Get the stream out of the connection before Dispose is called, // so that the stream doesn't get closed. var stream = debugConn.DetachStream(); return(CommandProcessorThread.Create(this, stream)); } catch (FailedRequestException ex) { WriteError(ex.Message); return(null); } } }
public static CommandProcessorThread Create( PythonInteractiveEvaluator evaluator, Stream stream ) { var thread = new CommandProcessorThread(evaluator, null); thread._stream = stream; thread.StartOutputThread(false); return(thread); }
public static CommandProcessorThread Create( PythonInteractiveEvaluator evaluator, Socket listenerSocket, Process process ) { var thread = new CommandProcessorThread(evaluator, process); thread._listenerSocket = listenerSocket; thread.StartOutputThread(process.StartInfo.RedirectStandardOutput); return(thread); }
public static CommandProcessorThread Create( PythonInteractiveEvaluator evaluator, Stream stream ) { var thread = new CommandProcessorThread(evaluator, null); thread._stream = stream; // Should be quickly replaced, but it's the best guess we have thread._currentWorkingDirectory = Environment.CurrentDirectory; thread.StartOutputThread(false); return(thread); }
public StreamLock(CommandProcessorThread evaluator, bool throwIfDisconnected) { Monitor.Enter(evaluator._streamLock); try { if (throwIfDisconnected) { evaluator.ThrowIfDisconnected(); } _evaluator = evaluator; } catch { // If any exceptions are thrown in the constructor, we // must exit the lock to avoid a deadlock. Monitor.Exit(evaluator._streamLock); throw; } }
protected override CommandProcessorThread Connect() { var remoteProcess = _process as PythonRemoteProcess; if (remoteProcess == null) { var conn = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP); conn.Bind(new IPEndPoint(IPAddress.Loopback, 0)); conn.Listen(0); var portNum = ((IPEndPoint)conn.LocalEndPoint).Port; var proc = System.Diagnostics.Process.GetProcessById(_process.Id); var thread = CommandProcessorThread.Create(this, conn, proc); _process.ConnectRepl(portNum); return(thread); } // Ignore SSL errors, since user was already prompted about them and chose to ignore them when he attached to this process. var stream = remoteProcess.Connect(false); bool connected = false; try { stream.Write(PythonRemoteProcess.ReplCommandBytes); string attachResp = stream.ReadAsciiString(PythonRemoteProcess.Accepted.Length); if (attachResp != PythonRemoteProcess.Accepted) { throw new ConnectionException(ConnErrorMessages.RemoteAttachRejected); } connected = true; } finally { if (!connected) { if (stream != null) { stream.Close(); } stream = null; } } return(CommandProcessorThread.Create(this, stream)); }
public StreamUnlock(CommandProcessorThread evaluator) { Debug.Assert(Monitor.IsEntered(evaluator._streamLock)); _evaluator = evaluator; Monitor.Exit(evaluator._streamLock); }
// Creates a command processor that will use the provided stream as the REPL connection (used for remote debugging REPL). protected void CreateCommandProcessor(Stream stream, bool redirectStdOutput, Process process) { _curListener = new CommandProcessorThread(this, stream, redirectStdOutput, process); }
// Creates a command processor that will listen for incoming connections on the socket (used for regular REPL and for local debugging REPL). protected void CreateCommandProcessor(Socket listenerSocket, bool redirectStdOutput, Process process) { _curListener = new CommandProcessorThread(this, listenerSocket, redirectStdOutput, process); }
public SocketLock(CommandProcessorThread evaluator) { Monitor.Enter(evaluator._socketLock); #if DEBUG Debug.Assert(evaluator._socketLockedThread == null); evaluator._socketLockedThread = Thread.CurrentThread; #endif _evaluator = evaluator; }
public static CommandProcessorThread Create( PythonInteractiveEvaluator evaluator, Stream stream ) { var thread = new CommandProcessorThread(evaluator, null); thread._stream = stream; // Should be quickly replaced, but it's the best guess we have thread._currentWorkingDirectory = Environment.CurrentDirectory; thread.StartOutputThread(false); return thread; }
public static CommandProcessorThread Create( PythonInteractiveEvaluator evaluator, Socket listenerSocket, Process process ) { var thread = new CommandProcessorThread(evaluator, process); thread._listenerSocket = listenerSocket; thread._currentWorkingDirectory = process.StartInfo.WorkingDirectory; thread.StartOutputThread(process.StartInfo.RedirectStandardOutput); return thread; }
public SocketUnlock(CommandProcessorThread evaluator) { #if DEBUG Debug.Assert(evaluator._socketLockedThread == Thread.CurrentThread); evaluator._socketLockedThread = null; #endif _evaluator = evaluator; Monitor.Exit(evaluator._socketLock); }
public virtual void Close() { if (_curListener != null) { _curListener.Dispose(); _curListener = null; } _attached = false; }
protected virtual Task <CommandProcessorThread> ConnectAsync(CancellationToken ct) { _serviceProvider.GetUIThread().MustBeCalledFromUIThreadOrThrow(); var interpreterPath = Configuration?.GetInterpreterPath(); if (string.IsNullOrWhiteSpace(interpreterPath)) { WriteError(Strings.ReplEvaluatorInterpreterNotConfigured.FormatUI(DisplayName)); return(null); } else if (!File.Exists(interpreterPath)) { WriteError(Strings.ReplEvaluatorInterpreterNotFound); return(null); } var processInfo = new ProcessStartInfo(interpreterPath); #if DEBUG bool debugMode = Environment.GetEnvironmentVariable("_PTVS_DEBUG_REPL") != null; processInfo.CreateNoWindow = !debugMode; processInfo.UseShellExecute = debugMode; processInfo.RedirectStandardOutput = !debugMode; processInfo.RedirectStandardError = !debugMode; processInfo.RedirectStandardInput = !debugMode; #else processInfo.CreateNoWindow = true; processInfo.UseShellExecute = false; processInfo.RedirectStandardOutput = true; processInfo.RedirectStandardError = true; processInfo.RedirectStandardInput = true; #endif var conn = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP); conn.Bind(new IPEndPoint(IPAddress.Loopback, 0)); conn.Listen(0); var portNum = ((IPEndPoint)conn.LocalEndPoint).Port; var workingDirectory = Configuration.WorkingDirectory; if (!string.IsNullOrEmpty(workingDirectory)) { processInfo.WorkingDirectory = workingDirectory; } else { processInfo.WorkingDirectory = CommonUtils.GetParent(processInfo.FileName); } #if DEBUG if (!debugMode) { #endif var env = processInfo.Environment; foreach (var kv in _serviceProvider.GetPythonToolsService().GetFullEnvironment(Configuration)) { env[kv.Key] = kv.Value; } #if DEBUG } #endif var args = new List <string>(); var interpreterArguments = Configuration.InterpreterArguments; if (!string.IsNullOrWhiteSpace(interpreterArguments)) { args.Add(interpreterArguments); } args.Add(ProcessOutput.QuoteSingleArgument(PythonToolsInstallPath.GetFile("visualstudio_py_repl.py"))); args.Add("--port"); args.Add(portNum.ToString()); args.Add("--execution-mode"); args.Add(string.IsNullOrEmpty(BackendName) ? "standard" : BackendName); processInfo.Arguments = string.Join(" ", args); Process process; try { if (!File.Exists(processInfo.FileName)) { throw new Win32Exception(Microsoft.VisualStudioTools.Project.NativeMethods.ERROR_FILE_NOT_FOUND); } process = Process.Start(processInfo); if (process.WaitForExit(100)) { throw new Win32Exception(process.ExitCode); } } catch (Win32Exception e) { if (e.NativeErrorCode == Microsoft.VisualStudioTools.Project.NativeMethods.ERROR_FILE_NOT_FOUND) { WriteError(Strings.ReplEvaluatorInterpreterNotFound); } else { WriteError(Strings.ErrorStartingInteractiveProcess.FormatUI(e.ToString())); } return(null); } catch (Exception e) when(!e.IsCriticalException()) { return(null); } return(Task.FromResult(CommandProcessorThread.Create(this, conn, process))); }
public static CommandProcessorThread Create( PythonInteractiveEvaluator evaluator, Stream stream ) { var thread = new CommandProcessorThread(evaluator, null); thread._stream = stream; thread.StartOutputThread(false); return thread; }