Example #1
0
        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);
                }
                    );
            }
        }
Example #2
0
        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);
                    }
                        );
                }
            }
        }
Example #3
0
        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);
        }
Example #4
0
        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);
                    }
                        );
                }
            }
        }