/// Invoking the StartAsync event signals that the language server should be started, and triggers a call to this routine. /// This routine contains the logic to start the server and estabilishes a connection that is returned (exceptions here are shown in the info bar of VS). public async Task <Connection> ActivateAsync(CancellationToken token) { await Task.Yield(); Telemetry.SendEvent(Telemetry.ExtensionEvent.Activate); try { #if MANUAL string ServerReaderPipe = $"QsLanguageServerReaderPipe"; string ServerWriterPipe = $"QsLanguageServerWriterPipe"; #else var root = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); var serverPath = Path.Combine(root, "LanguageServer"); var exe = Path.Combine(serverPath, "Microsoft.Quantum.QsLanguageServer.exe"); var time = DateTime.Now.Ticks; string ServerReaderPipe = $"QsLanguageServerReaderPipe{time}"; string ServerWriterPipe = $"QsLanguageServerWriterPipe{time}"; string LogPath = Path.Combine(Path.GetTempPath(), $"qsp-{time}.log"); ProcessStartInfo info = new ProcessStartInfo { FileName = exe, UseShellExecute = false, CreateNoWindow = true, Arguments = $"--writer={ServerWriterPipe} --reader={ServerReaderPipe} --log={LogPath}" }; Process process = new Process { StartInfo = info }; if (!process.Start()) { return(null); } #endif var bufferSize = 256; var pipeSecurity = new PipeSecurity(); var id = new SecurityIdentifier(WellKnownSidType.AuthenticatedUserSid, null); // I don't think WorldSid ("Everyone") is necessary pipeSecurity.AddAccessRule(new PipeAccessRule(id, PipeAccessRights.ReadWrite, System.Security.AccessControl.AccessControlType.Allow)); var readerPipe = new NamedPipeServerStream(ServerWriterPipe, PipeDirection.InOut, 4, PipeTransmissionMode.Message, PipeOptions.Asynchronous, bufferSize, bufferSize, pipeSecurity); var writerPipe = new NamedPipeServerStream(ServerReaderPipe, PipeDirection.InOut, 4, PipeTransmissionMode.Message, PipeOptions.Asynchronous, bufferSize, bufferSize, pipeSecurity); await readerPipe.WaitForConnectionAsync(token).ConfigureAwait(true); await writerPipe.WaitForConnectionAsync(token).ConfigureAwait(true); return(new Connection(readerPipe, writerPipe)); } catch (Exception e) { Telemetry.SendEvent(Telemetry.ExtensionEvent.Error, ("id", e.GetType().Name), ("reason", e.Message)); throw; } }
public void OnTelemetry(JToken args) { try { var name = (string)args["event"]; var props = args["properties"]?.ToObject <Dictionary <string, object> >(); Telemetry.SendEvent(name, props); } catch (Exception ex) { Debug.Assert(false, $"error sending telemetry: \n{ex}"); } }
/// The server only processes any notifications *after* it has been initialized properly. /// Hence we need to wait until after initialization to send all solution events that have already been raised, /// and start listening to new ones. public Task OnServerInitializedAsync() => Task.Run(() => Telemetry.SendEvent(Telemetry.ExtensionEvent.LspReady));