22
33using System ;
44using System . ComponentModel . Composition ;
5+ using System . IO ;
6+ using Microsoft . NodejsTools . Project ;
7+ using Microsoft . VisualStudio . Setup . Configuration ;
58using Microsoft . VisualStudio . Shell . Interop ;
69using Microsoft . VisualStudio . Workspace ;
710using Microsoft . VisualStudio . Workspace . Debug ;
811using Microsoft . VisualStudio . Workspace . Extensions . VS . Debug ;
12+ using Newtonsoft . Json . Linq ;
913
1014namespace 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 {
0 commit comments