Skip to content

Commit 0489c06

Browse files
author
Paul van Brenk
committed
Enable Webkit debugger for Open Folder debugging.
note: adding support for the legacy webkit debugger requires changes to the IVsDebugLaunchTargetProvider. So I decided against that for now.
1 parent 8c66a7c commit 0489c06

File tree

2 files changed

+86
-12
lines changed

2 files changed

+86
-12
lines changed

Nodejs/Product/Nodejs/Debugger/NodeDebugProvider.cs

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,14 @@
22

33
using System;
44
using System.ComponentModel.Composition;
5+
using System.IO;
6+
using Microsoft.NodejsTools.Project;
7+
using Microsoft.VisualStudio.Setup.Configuration;
58
using Microsoft.VisualStudio.Shell.Interop;
69
using Microsoft.VisualStudio.Workspace;
710
using Microsoft.VisualStudio.Workspace.Debug;
811
using Microsoft.VisualStudio.Workspace.Extensions.VS.Debug;
12+
using Newtonsoft.Json.Linq;
913

1014
namespace Microsoft.NodejsTools.Debugger
1115
{
@@ -42,9 +46,24 @@ internal class NodeJsDebugLaunchProvider : IVsDebugLaunchTargetProvider
4246
}";
4347

4448
public void SetupDebugTargetInfo(ref VsDebugTargetInfo vsDebugTargetInfo, DebugLaunchActionContext debugLaunchContext)
49+
{
50+
var nodeExe = debugLaunchContext.LaunchConfiguration.GetValue<string>(NodeExeKey, defaultValue: Nodejs.GetPathToNodeExecutableFromEnvironment());
51+
52+
var nodeVersion = Nodejs.GetNodeVersion(nodeExe);
53+
if (nodeVersion >= new Version(8, 0) || NodejsProjectLauncher.CheckDebugProtocolOption())
54+
{
55+
SetupDebugTargetInfoForWebkitV2Protocol(ref vsDebugTargetInfo, debugLaunchContext, nodeExe);
56+
}
57+
else
58+
{
59+
this.SetupDebugTargetInfoForNodeProtocol(ref vsDebugTargetInfo, debugLaunchContext, nodeExe);
60+
}
61+
}
62+
63+
private void SetupDebugTargetInfoForNodeProtocol(ref VsDebugTargetInfo vsDebugTargetInfo, DebugLaunchActionContext debugLaunchContext, string nodeExe)
4564
{
4665
var target = vsDebugTargetInfo.bstrExe;
47-
vsDebugTargetInfo.bstrExe = debugLaunchContext.LaunchConfiguration.GetValue<string>(NodeExeKey, Nodejs.GetPathToNodeExecutableFromEnvironment());
66+
vsDebugTargetInfo.bstrExe = nodeExe;
4867
var nodeJsArgs = vsDebugTargetInfo.bstrArg;
4968
vsDebugTargetInfo.bstrArg = "\"" + target + "\"";
5069
if (!string.IsNullOrEmpty(nodeJsArgs))
@@ -58,6 +77,61 @@ public void SetupDebugTargetInfo(ref VsDebugTargetInfo vsDebugTargetInfo, DebugL
5877
vsDebugTargetInfo.grfLaunch = (uint)__VSDBGLAUNCHFLAGS.DBGLAUNCH_StopDebuggingOnEnd;
5978
}
6079

80+
private void SetupDebugTargetInfoForWebkitV2Protocol(ref VsDebugTargetInfo vsDebugTargetInfo, DebugLaunchActionContext debugLaunchContext, string nodeExe)
81+
{
82+
// todo: refactor the debugging and process starting so we can re-use
83+
84+
var setupConfiguration = new SetupConfiguration();
85+
var setupInstance = setupConfiguration.GetInstanceForCurrentProcess();
86+
var visualStudioInstallationInstanceID = setupInstance.GetInstanceId();
87+
88+
// The Node2Adapter depends on features only in Node v6+, so the old v5.4 version of node will not suffice for this scenario
89+
// This node.exe will be the one used by the node2 debug adapter, not the one used to host the user code.
90+
var pathToNodeExe = Path.Combine(setupInstance.GetInstallationPath(), "JavaScript\\Node.JS\\v6.4.0_x86\\Node.exe");
91+
92+
// 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.
93+
var nodeParams = NodejsProjectLauncher.CheckForRegistrySpecifiedNodeParams();
94+
if (!string.IsNullOrEmpty(nodeParams))
95+
{
96+
pathToNodeExe = pathToNodeExe + " " + nodeParams;
97+
}
98+
99+
var pathToNode2DebugAdapterRuntime = Environment.ExpandEnvironmentVariables(@"""%ALLUSERSPROFILE%\" +
100+
$@"Microsoft\VisualStudio\NodeAdapter\{visualStudioInstallationInstanceID}\extension\out\src\nodeDebug.js""");
101+
102+
string trimmedPathToNode2DebugAdapter = pathToNode2DebugAdapterRuntime.Replace("\"", "");
103+
if (!File.Exists(trimmedPathToNode2DebugAdapter))
104+
{
105+
pathToNode2DebugAdapterRuntime = Environment.ExpandEnvironmentVariables(@"""%ALLUSERSPROFILE%\" +
106+
$@"Microsoft\VisualStudio\NodeAdapter\{visualStudioInstallationInstanceID}\out\src\nodeDebug.js""");
107+
}
108+
109+
var target = vsDebugTargetInfo.bstrExe;
110+
var cwd = Path.GetDirectoryName(target); // Current working directory
111+
112+
var configuration = new JObject(
113+
new JProperty("name", "Debug Node.js program from Visual Studio"),
114+
new JProperty("type", "node2"),
115+
new JProperty("request", "launch"),
116+
new JProperty("program", target),
117+
new JProperty("runtimeExecutable", nodeExe),
118+
new JProperty("cwd", cwd),
119+
new JProperty("console", "externalTerminal"),
120+
new JProperty("diagnosticLogging", NodejsProjectLauncher.CheckEnableDiagnosticLoggingOption()),
121+
new JProperty("sourceMaps", true),
122+
new JProperty("stopOnEntry", true),
123+
new JProperty("$adapter", pathToNodeExe),
124+
new JProperty("$adapterArgs", pathToNode2DebugAdapterRuntime));
125+
126+
var jsonContent = configuration.ToString();
127+
128+
vsDebugTargetInfo.dlo = DEBUG_LAUNCH_OPERATION.DLO_CreateProcess;
129+
vsDebugTargetInfo.clsidCustom = NodejsProjectLauncher.WebKitDebuggerV2Guid;
130+
vsDebugTargetInfo.bstrExe = target;
131+
vsDebugTargetInfo.bstrOptions = jsonContent;
132+
vsDebugTargetInfo.grfLaunch = (uint)__VSDBGLAUNCHFLAGS.DBGLAUNCH_StopDebuggingOnEnd;
133+
}
134+
61135
[ExportLaunchConfigurationProvider(LaunchConfigurationProviderType, new[] { ".js" }, "nodejs", NodeJsSchema)]
62136
public class LaunchConfigurationProvider : ILaunchConfigurationProvider
63137
{

Nodejs/Product/Nodejs/Project/NodejsProjectLauncher.cs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ internal class NodejsProjectLauncher : IProjectLauncher
3232
private readonly NodejsProjectNode _project;
3333
private int? _testServerPort;
3434

35-
private static readonly Guid WebkitDebuggerGuid = Guid.Parse("4cc6df14-0ab5-4a91-8bb4-eb0bf233d0fe");
36-
private static readonly Guid WebkitPortSupplierGuid = Guid.Parse("4103f338-2255-40c0-acf5-7380e2bea13d");
37-
private static readonly Guid WebKitDebuggerV2Guid = Guid.Parse("30d423cc-6d0b-4713-b92d-6b2a374c3d89");
35+
public static readonly Guid WebkitDebuggerGuid = Guid.Parse("4cc6df14-0ab5-4a91-8bb4-eb0bf233d0fe");
36+
public static readonly Guid WebkitPortSupplierGuid = Guid.Parse("4103f338-2255-40c0-acf5-7380e2bea13d");
37+
internal static readonly Guid WebKitDebuggerV2Guid = Guid.Parse("30d423cc-6d0b-4713-b92d-6b2a374c3d89");
3838

3939
public NodejsProjectLauncher(NodejsProjectNode project)
4040
{
@@ -97,28 +97,28 @@ private int Start(string file, bool debug)
9797
return VSConstants.S_OK;
9898
}
9999

100-
private static bool CheckUseNewChromeDebugProtocolOption()
100+
internal static bool CheckUseNewChromeDebugProtocolOption()
101101
{
102102
var optionString = NodejsDialogPage.LoadString(name: "WebKitVersion", cat: "Debugging");
103103

104104
return !StringComparer.OrdinalIgnoreCase.Equals(optionString, "V1");
105105
}
106106

107-
private static bool CheckDebugProtocolOption()
107+
internal static bool CheckDebugProtocolOption()
108108
{
109109
var optionString = NodejsDialogPage.LoadString(name: "DebugProtocol", cat: "Debugging");
110110

111111
return StringComparer.OrdinalIgnoreCase.Equals(optionString, "chrome");
112112
}
113113

114-
private static bool CheckEnableDiagnosticLoggingOption()
114+
internal static bool CheckEnableDiagnosticLoggingOption()
115115
{
116116
var optionString = NodejsDialogPage.LoadString(name: "DiagnosticLogging", cat: "Debugging");
117117

118118
return StringComparer.OrdinalIgnoreCase.Equals(optionString, "true");
119119
}
120120

121-
private static string CheckForRegistrySpecifiedNodeParams()
121+
internal static string CheckForRegistrySpecifiedNodeParams()
122122
{
123123
var paramString = NodejsDialogPage.LoadString(name: "NodeCmdParams", cat: "Debugging");
124124

@@ -372,7 +372,7 @@ private void StartWithDebugger(string startupFile)
372372
}
373373
}
374374

375-
private void StartWithChromeV2Debugger(string program, string nodeRuntimeExecutable, bool startBrowser)
375+
private void StartWithChromeV2Debugger(string file, string nodePath, bool startBrowser)
376376
{
377377
var serviceProvider = _project.Site;
378378

@@ -412,8 +412,8 @@ private void StartWithChromeV2Debugger(string program, string nodeRuntimeExecuta
412412
new JProperty("name", "Debug Node.js program from Visual Studio"),
413413
new JProperty("type", "node2"),
414414
new JProperty("request", "launch"),
415-
new JProperty("program", program),
416-
new JProperty("runtimeExecutable", nodeRuntimeExecutable),
415+
new JProperty("program", file),
416+
new JProperty("runtimeExecutable", nodePath),
417417
new JProperty("cwd", cwd),
418418
new JProperty("console", "externalTerminal"),
419419
new JProperty("env", JObject.FromObject(envVars)),
@@ -429,7 +429,7 @@ private void StartWithChromeV2Debugger(string program, string nodeRuntimeExecuta
429429
new VsDebugTargetInfo4() {
430430
dlo = (uint)DEBUG_LAUNCH_OPERATION.DLO_CreateProcess,
431431
guidLaunchDebugEngine = WebKitDebuggerV2Guid,
432-
bstrExe = program,
432+
bstrExe = file,
433433
bstrOptions = jsonContent
434434
}
435435
};

0 commit comments

Comments
 (0)