/// <summary> /// Starts the debug service with the specified TCP socket port. /// </summary> /// <param name="debugServicePort">The port number for the debug service.</param> public void StartDebugService(int debugServicePort, ProfilePaths profilePaths) { this.debugAdapter = new DebugAdapter( hostDetails, profilePaths, new TcpSocketServerChannel(debugServicePort), this.languageServer?.EditorOperations); this.debugAdapter.SessionEnded += (obj, args) => { Logger.Write( LogLevel.Normal, "Previous debug session ended, restarting debug service..."); this.StartDebugService(debugServicePort, profilePaths); }; this.debugAdapter.Start().Wait(); Logger.Write( LogLevel.Normal, string.Format( "Debug service started, listening on port {0}", debugServicePort)); }
/// <summary> /// Stops the language or debug services if either were started. /// </summary> public void StopServices() { // TODO: Need a new way to shut down the services this.languageServer = null; this.debugAdapter = null; }
/// <summary> /// Stops the language or debug services if either were started. /// </summary> public void StopServices() { this.languageServer?.Stop().Wait(); this.languageServer = null; this.debugAdapter?.Stop().Wait(); this.debugAdapter = null; }
private void OnDebugServiceClientConnect(object sender, TcpSocketServerChannel serverChannel) { MessageDispatcher messageDispatcher = new MessageDispatcher(this.logger); ProtocolEndpoint protocolEndpoint = new ProtocolEndpoint( serverChannel, messageDispatcher, this.logger); protocolEndpoint.UnhandledException += ProtocolEndpoint_UnhandledException; bool ownsEditorSession = this.editorSession == null; if (ownsEditorSession) { this.editorSession = this.CreateDebugSession( this.hostDetails, profilePaths, protocolEndpoint, messageDispatcher, this.languageServer?.EditorOperations, this.enableConsoleRepl); } this.debugAdapter = new DebugAdapter( this.editorSession, ownsEditorSession, messageDispatcher, protocolEndpoint, this.logger); this.debugAdapter.SessionEnded += (obj, args) => { if (!ownsEditorSession) { this.logger.Write( LogLevel.Normal, "Previous debug session ended, restarting debug service listener..."); this.debugServiceListener.Start(); } else { // Exit the host process this.serverCompletedTask.SetResult(true); } }; this.debugAdapter.Start(); protocolEndpoint.Start(); }
private void OnDebugServiceClientConnect(object sender, TcpSocketServerChannel serverChannel) { MessageDispatcher messageDispatcher = new MessageDispatcher(this.logger); ProtocolEndpoint protocolEndpoint = new ProtocolEndpoint( serverChannel, messageDispatcher, this.logger); if (this.enableConsoleRepl) { this.debugAdapter = new DebugAdapter( this.editorSession, false, messageDispatcher, protocolEndpoint, this.logger); } else { EditorSession debugSession = this.CreateDebugSession( this.hostDetails, profilePaths, protocolEndpoint, messageDispatcher, this.languageServer?.EditorOperations, false); this.debugAdapter = new DebugAdapter( debugSession, true, messageDispatcher, protocolEndpoint, this.logger); } this.debugAdapter.SessionEnded += (obj, args) => { this.logger.Write( LogLevel.Normal, "Previous debug session ended, restarting debug service listener..."); this.debugServiceListener.Start(); }; this.debugAdapter.Start(); protocolEndpoint.Start(); }
static void Main(string[] args) { #if DEBUG bool waitForDebugger = args.Any( arg => string.Equals( arg, "/waitForDebugger", StringComparison.InvariantCultureIgnoreCase)); if (waitForDebugger) { if (Debugger.IsAttached) { Debugger.Break(); } else { Debugger.Launch(); } } #endif string logPath = null; string logPathArgument = args.FirstOrDefault( arg => arg.StartsWith( "/logPath:", StringComparison.InvariantCultureIgnoreCase)); if (!string.IsNullOrEmpty(logPathArgument)) { logPath = logPathArgument.Substring(9).Trim('"'); } LogLevel logLevel = LogLevel.Normal; string logLevelArgument = args.FirstOrDefault( arg => arg.StartsWith( "/logLevel:", StringComparison.InvariantCultureIgnoreCase)); if (!string.IsNullOrEmpty(logLevelArgument)) { // Attempt to parse the log level Enum.TryParse <LogLevel>( logLevelArgument.Substring(10).Trim('"'), true, out logLevel); } bool runDebugAdapter = args.Any( arg => string.Equals( arg, "/debugAdapter", StringComparison.InvariantCultureIgnoreCase)); // Catch unhandled exceptions for logging purposes AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; ProtocolEndpoint server = null; if (runDebugAdapter) { logPath = logPath ?? "DebugAdapter.log"; server = new DebugAdapter(); } else { logPath = logPath ?? "EditorServices.log"; server = new LanguageServer(); } // Start the logger with the specified log path and level Logger.Initialize(logPath, logLevel); FileVersionInfo fileVersionInfo = FileVersionInfo.GetVersionInfo( System.Reflection.Assembly.GetExecutingAssembly().Location); Logger.Write( LogLevel.Normal, string.Format( "PowerShell Editor Services Host v{0} starting (pid {1})...", fileVersionInfo.FileVersion, Process.GetCurrentProcess().Id)); // Start the server server.Start().Wait(); Logger.Write(LogLevel.Normal, "PowerShell Editor Services Host started!"); // Wait for the server to finish server.WaitForExit(); Logger.Write(LogLevel.Normal, "PowerShell Editor Services Host exited normally."); }
async Task ListenForMessages() { this.messageLoopSyncContext = SynchronizationContext.Current; // Ensure that the console is using UTF-8 encoding System.Console.InputEncoding = Encoding.UTF8; System.Console.OutputEncoding = Encoding.UTF8; // Open the standard input/output streams this.inputStream = System.Console.OpenStandardInput(); this.outputStream = System.Console.OpenStandardOutput(); IMessageSerializer messageSerializer = null; IMessageProcessor messageProcessor = null; // Use a different serializer and message processor based // on whether this instance should host a language server // debug adapter. if (this.runDebugAdapter) { DebugAdapter debugAdapter = new DebugAdapter(); debugAdapter.Initialize(); messageProcessor = debugAdapter; messageSerializer = new V8MessageSerializer(); } else { // Set up the LanguageServer LanguageServer languageServer = new LanguageServer(); languageServer.Initialize(); messageProcessor = languageServer; messageSerializer = new JsonRpcMessageSerializer(); } // Set up the reader and writer this.messageReader = new MessageReader( this.inputStream, messageSerializer); this.messageWriter = new MessageWriter( this.outputStream, messageSerializer); // Set up the console host which will send events // through the MessageWriter this.consoleHost = new StdioConsoleHost(messageWriter); // Set up the PowerShell session this.editorSession = new EditorSession(); this.editorSession.StartSession(this.consoleHost); this.editorSession.PowerShellContext.OutputWritten += powerShellContext_OutputWritten; if (this.runDebugAdapter) { // Attach to debugger events from the PowerShell session this.editorSession.DebugService.DebuggerStopped += DebugService_DebuggerStopped; } // Run the message loop bool isRunning = true; while (isRunning) { Message newMessage = null; try { // Read a message from stdin newMessage = await this.messageReader.ReadMessage(); } catch (MessageParseException e) { // TODO: Write an error response Logger.Write( LogLevel.Error, "Could not parse a message that was received:\r\n\r\n" + e.ToString()); // Continue the loop continue; } // Process the message await messageProcessor.ProcessMessage( newMessage, this.editorSession, this.messageWriter); } }