private void StartWithChromeV2Debugger(string file, string nodePath, bool startBrowser) { var serviceProvider = _project.Site; // Here we need to massage the env variables into the format expected by node and vs code var webBrowserUrl = GetFullUrl(); var envVars = GetEnvironmentVariables(webBrowserUrl); var runtimeArguments = ConvertArguments(this._project.GetProjectProperty(NodeProjectProperty.NodeExeArguments)); var scriptArguments = ConvertArguments(this._project.GetProjectProperty(NodeProjectProperty.ScriptArguments)); var cwd = _project.GetWorkingDirectory(); // Current working directory var configuration = new JObject( new JProperty("name", "Debug Node.js program from Visual Studio"), new JProperty("type", "node2"), new JProperty("request", "launch"), new JProperty("program", file), new JProperty("args", scriptArguments), new JProperty("runtimeExecutable", nodePath), new JProperty("runtimeArgs", runtimeArguments), new JProperty("cwd", cwd), new JProperty("console", "externalTerminal"), new JProperty("env", JObject.FromObject(envVars)), new JProperty("trace", CheckEnableDiagnosticLoggingOption()), new JProperty("sourceMaps", true), new JProperty("stopOnEntry", true)); var jsonContent = configuration.ToString(); var debugTargets = new[] { new VsDebugTargetInfo4() { dlo = (uint)DEBUG_LAUNCH_OPERATION.DLO_CreateProcess, guidLaunchDebugEngine = WebKitDebuggerV2Guid, bstrExe = file, bstrOptions = jsonContent } }; var processInfo = new VsDebugTargetProcessInfo[debugTargets.Length]; var debugger = (IVsDebugger4)serviceProvider.GetService(typeof(SVsShellDebugger)); debugger.LaunchDebugTargets4(1, debugTargets, processInfo); // Launch browser if (startBrowser && !string.IsNullOrWhiteSpace(webBrowserUrl)) { var uri = new Uri(webBrowserUrl); OnPortOpenedHandler.CreateHandler( uri.Port, timeout: 5_000, // 5 seconds action: () => { VsShellUtilities.OpenBrowser(webBrowserUrl, (uint)__VSOSPFLAGS.OSP_LaunchNewBrowser); } ); } }
private void StartAndAttachDebugger(string file, string nodePath, bool startBrowser) { // start the node process var workingDir = _project.GetWorkingDirectory(); var url = GetFullUrl(); var env = GetEnvironmentVariablesString(url); var interpreterOptions = _project.GetProjectProperty(NodeProjectProperty.NodeExeArguments); var debugOptions = this.GetDebugOptions(); var script = GetFullArguments(file, includeNodeArgs: false); var process = NodeDebugger.StartNodeProcessWithInspect(exe: nodePath, script: script, dir: workingDir, env: env, interpreterOptions: interpreterOptions, debugOptions: debugOptions); process.Start(); // setup debug info and attach var debugUri = $"http://127.0.0.1:{process.DebuggerPort}"; var dbgInfo = new VsDebugTargetInfo4(); dbgInfo.dlo = (uint)DEBUG_LAUNCH_OPERATION.DLO_AlreadyRunning; dbgInfo.LaunchFlags = (uint)__VSDBGLAUNCHFLAGS.DBGLAUNCH_StopDebuggingOnEnd; dbgInfo.guidLaunchDebugEngine = WebkitDebuggerGuid; dbgInfo.dwDebugEngineCount = 1; var enginesPtr = MarshalDebugEngines(new[] { WebkitDebuggerGuid }); dbgInfo.pDebugEngines = enginesPtr; dbgInfo.guidPortSupplier = WebkitPortSupplierGuid; dbgInfo.bstrPortName = debugUri; dbgInfo.fSendToOutputWindow = 0; // we connect through a URI, so no need to set the process, // we need to set the process id to '1' so the debugger is able to attach dbgInfo.bstrExe = $"\01"; AttachDebugger(dbgInfo); if (startBrowser) { Uri uri = null; if (!String.IsNullOrWhiteSpace(url)) { uri = new Uri(url); } if (uri != null) { OnPortOpenedHandler.CreateHandler( uri.Port, shortCircuitPredicate: () => process.HasExited, action: () => { VsShellUtilities.OpenBrowser(url, (uint)__VSOSPFLAGS.OSP_LaunchNewBrowser); } ); } } }
private int Start(string file, bool debug) { string nodePath = GetNodePath(); if (nodePath == null) { Nodejs.ShowNodejsNotInstalled(); return(VSConstants.S_OK); } bool startBrowser = ShouldStartBrowser(); if (debug) { StartWithDebugger(file); } else { var psi = new ProcessStartInfo(); psi.UseShellExecute = false; psi.FileName = nodePath; psi.Arguments = GetFullArguments(file); psi.WorkingDirectory = _project.GetWorkingDirectory(); string webBrowserUrl = GetFullUrl(); Uri uri = null; if (!String.IsNullOrWhiteSpace(webBrowserUrl)) { uri = new Uri(webBrowserUrl); psi.EnvironmentVariables["PORT"] = uri.Port.ToString(); } foreach (var nameValue in GetEnvironmentVariables()) { psi.EnvironmentVariables[nameValue.Key] = nameValue.Value; } var process = NodeProcess.Start( psi, NodejsPackage.Instance.GeneralOptionsPage.WaitOnAbnormalExit, NodejsPackage.Instance.GeneralOptionsPage.WaitOnNormalExit); _project.OnDispose += process.ResponseToTerminateEvent; if (startBrowser && uri != null) { OnPortOpenedHandler.CreateHandler( uri.Port, shortCircuitPredicate: () => process.HasExited, action: () => { VsShellUtilities.OpenBrowser(webBrowserUrl, (uint)__VSOSPFLAGS.OSP_LaunchNewBrowser); } ); } } return(VSConstants.S_OK); }
private void StartNodeProcess(string file, string nodePath, bool startBrowser) { //TODO: looks like this duplicates a bunch of code in NodeDebugger var psi = new ProcessStartInfo() { UseShellExecute = false, FileName = nodePath, Arguments = GetFullArguments(file, includeNodeArgs: true), WorkingDirectory = _project.GetWorkingDirectory() }; var webBrowserUrl = GetFullUrl(); Uri uri = null; if (!String.IsNullOrWhiteSpace(webBrowserUrl)) { uri = new Uri(webBrowserUrl); psi.EnvironmentVariables["PORT"] = uri.Port.ToString(); } foreach (var nameValue in GetEnvironmentVariables()) { psi.EnvironmentVariables[nameValue.Key] = nameValue.Value; } var process = NodeProcess.Start( psi, waitOnAbnormal: NodejsPackage.Instance.GeneralOptionsPage.WaitOnAbnormalExit, waitOnNormal: NodejsPackage.Instance.GeneralOptionsPage.WaitOnNormalExit); this._project.OnDispose += process.ResponseToTerminateEvent; if (startBrowser && uri != null) { OnPortOpenedHandler.CreateHandler( uri.Port, shortCircuitPredicate: () => process.HasExited, action: () => { VsShellUtilities.OpenBrowser(webBrowserUrl, (uint)__VSOSPFLAGS.OSP_LaunchNewBrowser); } ); } }
private void StartWithChromeV2Debugger(string file, string nodePath, bool shouldStartBrowser, string browserPath) { var serviceProvider = _project.Site; // Here we need to massage the env variables into the format expected by node and vs code var webBrowserUrl = GetFullUrl(); var envVars = GetEnvironmentVariables(webBrowserUrl); var debuggerPort = this._project.GetProjectProperty(NodeProjectProperty.DebuggerPort); if (string.IsNullOrWhiteSpace(debuggerPort)) { debuggerPort = NodejsConstants.DefaultDebuggerPort.ToString(); } var runtimeArguments = ConvertArguments(this._project.GetProjectProperty(NodeProjectProperty.NodeExeArguments)); // If we supply the port argument we also need to manually add --inspect-brk=port to the runtime arguments runtimeArguments = runtimeArguments.Append($"--inspect-brk={debuggerPort}"); var scriptArguments = ConvertArguments(this._project.GetProjectProperty(NodeProjectProperty.ScriptArguments)); var cwd = _project.GetWorkingDirectory(); // Current working directory var config = new NodePinezorroDebugLaunchConfig(file, scriptArguments, nodePath, runtimeArguments, debuggerPort, cwd, CheckEnableDiagnosticLoggingOption(), _project.ProjectGuid.ToString(), JObject.FromObject(envVars)); bool usingV3Debugger = ShouldUseV3CdpDebugger(); if (usingV3Debugger && shouldStartBrowser && (browserPath.EndsWith("chrome.exe") || browserPath.EndsWith("msedge.exe"))) { config = new NodePinezorroDebugLaunchConfig() { ConfigName = "Debug Node program and browser from Visual Studio", Request = "launch", DebugType = browserPath.EndsWith("chrome.exe") ? "chrome" : "edge", RuntimeExecutable = browserPath, BrowserUrl = webBrowserUrl, BrowserUserDataDir = true, Server = config.toPwaChromeServerConfig(), WorkingDir = cwd, WebRoot = cwd, ProjectGuid = _project.ProjectGuid.ToString() }; shouldStartBrowser = false; // the v3 cdp debug adapter will launch the browser as part of debugging so no need to launch it here anymore } var jsonContent = JObject.FromObject(config).ToString(); var debugTargets = new[] { new VsDebugTargetInfo4() { dlo = (uint)DEBUG_LAUNCH_OPERATION.DLO_CreateProcess, guidLaunchDebugEngine = GetDebuggerGuid(), bstrExe = file, bstrOptions = jsonContent } }; var processInfo = new VsDebugTargetProcessInfo[debugTargets.Length]; var debugger = (IVsDebugger4)serviceProvider.GetService(typeof(SVsShellDebugger)); debugger.LaunchDebugTargets4(1, debugTargets, processInfo); // Launch browser if (shouldStartBrowser && !string.IsNullOrWhiteSpace(webBrowserUrl)) { var uri = new Uri(webBrowserUrl); OnPortOpenedHandler.CreateHandler( uri.Port, timeout: 5_000, // 5 seconds action: () => OpenBrowser(browserPath, webBrowserUrl) ); } }
private void StartWithChromeV2Debugger(string file, string nodePath, bool startBrowser) { var serviceProvider = _project.Site; var setupConfiguration = new SetupConfiguration(); var setupInstance = setupConfiguration.GetInstanceForCurrentProcess(); var visualStudioInstallationInstanceID = setupInstance.GetInstanceId(); // The Node2Adapter depends on features only in Node v6+, so the old v5.4 version of node will not suffice for this scenario // This node.exe will be the one used by the node2 debug adapter, not the one used to host the user code. var pathToNodeExe = Path.Combine(setupInstance.GetInstallationPath(), "JavaScript\\Node.JS\\v6.4.0_x86\\Node.exe"); // We check the registry to see if any parameters for the node.exe invocation have been specified (like "--inspect"), and append them if we find them. string nodeParams = CheckForRegistrySpecifiedNodeParams(); if (!string.IsNullOrEmpty(nodeParams)) { pathToNodeExe = pathToNodeExe + " " + nodeParams; } var pathToNode2DebugAdapterRuntime = Environment.ExpandEnvironmentVariables(@"""%ALLUSERSPROFILE%\" + $@"Microsoft\VisualStudio\NodeAdapter\{visualStudioInstallationInstanceID}\extension\out\src\nodeDebug.js"""); string trimmedPathToNode2DebugAdapter = pathToNode2DebugAdapterRuntime.Replace("\"", ""); if (!File.Exists(trimmedPathToNode2DebugAdapter)) { pathToNode2DebugAdapterRuntime = Environment.ExpandEnvironmentVariables(@"""%ALLUSERSPROFILE%\" + $@"Microsoft\VisualStudio\NodeAdapter\{visualStudioInstallationInstanceID}\out\src\nodeDebug.js"""); } // Here we need to massage the env variables into the format expected by node and vs code var webBrowserUrl = GetFullUrl(); var envVars = GetEnvironmentVariables(webBrowserUrl); var cwd = _project.GetWorkingDirectory(); // Current working directory var configuration = new JObject( new JProperty("name", "Debug Node.js program from Visual Studio"), new JProperty("type", "node2"), new JProperty("request", "launch"), new JProperty("program", file), new JProperty("runtimeExecutable", nodePath), new JProperty("cwd", cwd), new JProperty("console", "externalTerminal"), new JProperty("env", JObject.FromObject(envVars)), new JProperty("trace", CheckEnableDiagnosticLoggingOption()), new JProperty("sourceMaps", true), new JProperty("stopOnEntry", true), new JProperty("$adapter", pathToNodeExe), new JProperty("$adapterArgs", pathToNode2DebugAdapterRuntime)); var jsonContent = configuration.ToString(); var debugTargets = new[] { new VsDebugTargetInfo4() { dlo = (uint)DEBUG_LAUNCH_OPERATION.DLO_CreateProcess, guidLaunchDebugEngine = WebKitDebuggerV2Guid, bstrExe = file, bstrOptions = jsonContent } }; var processInfo = new VsDebugTargetProcessInfo[debugTargets.Length]; var debugger = serviceProvider.GetService(typeof(SVsShellDebugger)) as IVsDebugger4; debugger.LaunchDebugTargets4(1, debugTargets, processInfo); // Launch browser if (startBrowser) { Uri uri = null; if (!String.IsNullOrWhiteSpace(webBrowserUrl)) { uri = new Uri(webBrowserUrl); } if (uri != null) { OnPortOpenedHandler.CreateHandler( uri.Port, shortCircuitPredicate: () => false, action: () => { VsShellUtilities.OpenBrowser(webBrowserUrl, (uint)__VSOSPFLAGS.OSP_LaunchNewBrowser); } ); } } }