/// <summary> /// Creates process info used to start the project with no debugging. /// </summary> private ProcessStartInfo CreateProcessStartInfoNoDebug(string startupFile, IPythonProjectLaunchProperties props) { string command = CreateCommandLineNoDebug(startupFile, props); ProcessStartInfo startInfo; if (!(props.GetIsWindowsApplication() ?? false) && (_pyService.DebuggerOptions.WaitOnAbnormalExit || _pyService.DebuggerOptions.WaitOnNormalExit)) { command = "/c \"\"" + props.GetInterpreterPath() + "\" " + command; if (_pyService.DebuggerOptions.WaitOnNormalExit && _pyService.DebuggerOptions.WaitOnAbnormalExit) { command += " & pause"; } else if (_pyService.DebuggerOptions.WaitOnNormalExit) { command += " & if not errorlevel 1 pause"; } else if (_pyService.DebuggerOptions.WaitOnAbnormalExit) { command += " & if errorlevel 1 pause"; } command += "\""; startInfo = new ProcessStartInfo(Path.Combine(Environment.SystemDirectory, "cmd.exe"), command); } else { startInfo = new ProcessStartInfo(props.GetInterpreterPath(), command); } startInfo.WorkingDirectory = props.GetWorkingDirectory(); //In order to update environment variables we have to set UseShellExecute to false startInfo.UseShellExecute = false; var env = new Dictionary <string, string>(props.GetEnvironment(true)); PythonProjectLaunchProperties.MergeEnvironmentBelow(env, null, true); foreach (var kv in env) { startInfo.EnvironmentVariables[kv.Key] = kv.Value; } return(startInfo); }
private ProcessStartInfo CreateProcessStartInfo( CommandStartInfo startInfo, IPythonProjectLaunchProperties props ) { bool alwaysPause = startInfo.ExecuteInConsoleAndPause; // We only want to run the webserver in a console. startInfo.ExecuteIn = "console"; startInfo.AdjustArgumentsForProcessStartInfo(props.GetInterpreterPath(), handleConsoleAndPause: false); var psi = new ProcessStartInfo { FileName = startInfo.Filename, Arguments = startInfo.Arguments, WorkingDirectory = startInfo.WorkingDirectory, UseShellExecute = false }; var env = new Dictionary <string, string>(startInfo.EnvironmentVariables, StringComparer.OrdinalIgnoreCase); PythonProjectLaunchProperties.MergeEnvironmentBelow(env, new Dictionary <string, string> { { "SERVER_HOST", "localhost" }, { "SERVER_PORT", TestServerPortString } }, true); foreach (var kv in env) { psi.EnvironmentVariables[kv.Key] = kv.Value; } // Pause if the user has requested it. string pauseCommand = null; if (alwaysPause || _pyService.DebuggerOptions.WaitOnAbnormalExit && _pyService.DebuggerOptions.WaitOnNormalExit) { pauseCommand = "pause"; } else if (_pyService.DebuggerOptions.WaitOnAbnormalExit && !_pyService.DebuggerOptions.WaitOnNormalExit) { pauseCommand = "if errorlevel 1 pause"; } else if (_pyService.DebuggerOptions.WaitOnNormalExit && !_pyService.DebuggerOptions.WaitOnAbnormalExit) { pauseCommand = "if not errorlevel 1 pause"; } if (!string.IsNullOrEmpty(pauseCommand)) { psi.Arguments = string.Format("/c \"{0} {1}\" & {2}", ProcessOutput.QuoteSingleArgument(psi.FileName), psi.Arguments, pauseCommand ); psi.FileName = Path.Combine(Environment.SystemDirectory, "cmd.exe"); } return(psi); }
private unsafe DebugTargetInfo CreateDebugTargetInfo( CommandStartInfo startInfo, IPythonProjectLaunchProperties props ) { var dti = new DebugTargetInfo(); var alwaysPause = startInfo.ExecuteInConsoleAndPause; // We only want to debug a web server in a console. startInfo.ExecuteIn = "console"; startInfo.AdjustArgumentsForProcessStartInfo(props.GetInterpreterPath(), handleConsoleAndPause: false); try { dti.Info.dlo = DEBUG_LAUNCH_OPERATION.DLO_CreateProcess; dti.Info.bstrExe = startInfo.Filename; dti.Info.bstrCurDir = startInfo.WorkingDirectory; dti.Info.bstrRemoteMachine = null; dti.Info.fSendStdoutToOutputWindow = 0; if (!(props.GetIsNativeDebuggingEnabled() ?? false)) { dti.Info.bstrOptions = string.Join(";", GetGlobalDebuggerOptions(true, alwaysPause) .Concat(GetProjectDebuggerOptions()) .Where(s => !string.IsNullOrEmpty(s)) .Select(s => s.Replace(";", ";;")) ); } if (startInfo.EnvironmentVariables != null && startInfo.EnvironmentVariables.Any()) { // Environment variables should be passed as a // null-terminated block of null-terminated strings. // Each string is in the following form:name=value\0 var buf = new StringBuilder(); foreach (var kv in startInfo.EnvironmentVariables) { buf.AppendFormat("{0}={1}\0", kv.Key, kv.Value); } buf.Append("\0"); dti.Info.bstrEnv = buf.ToString(); } dti.Info.bstrArg = startInfo.Arguments; if (props.GetIsNativeDebuggingEnabled() ?? false) { dti.Info.dwClsidCount = 2; dti.Info.pClsidList = Marshal.AllocCoTaskMem(sizeof(Guid) * 2); var engineGuids = (Guid *)dti.Info.pClsidList; engineGuids[0] = dti.Info.clsidCustom = DkmEngineId.NativeEng; engineGuids[1] = AD7Engine.DebugEngineGuid; } else { // Set the Python debugger dti.Info.clsidCustom = new Guid(AD7Engine.DebugEngineId); dti.Info.grfLaunch = (uint)__VSDBGLAUNCHFLAGS.DBGLAUNCH_StopDebuggingOnEnd; } // Null out dti so that it is not disposed before we return. var result = dti; dti = null; return(result); } finally { if (dti != null) { dti.Dispose(); } } }
/// <summary> /// Sets up debugger information. /// </summary> private unsafe void SetupDebugInfo( ref VsDebugTargetInfo dbgInfo, string startupFile, IPythonProjectLaunchProperties props ) { bool enableNativeCodeDebugging = false; dbgInfo.dlo = DEBUG_LAUNCH_OPERATION.DLO_CreateProcess; dbgInfo.bstrExe = props.GetInterpreterPath(); dbgInfo.bstrCurDir = props.GetWorkingDirectory(); dbgInfo.bstrArg = CreateCommandLineDebug(startupFile, props); dbgInfo.bstrRemoteMachine = null; dbgInfo.fSendStdoutToOutputWindow = 0; if (!enableNativeCodeDebugging) { string interpArgs = _project.GetProperty(PythonConstants.InterpreterArgumentsSetting); dbgInfo.bstrOptions = AD7Engine.VersionSetting + "=" + _project.GetInterpreterFactory().GetLanguageVersion().ToString(); if (!(props.GetIsWindowsApplication() ?? false)) { if (_pyService.DebuggerOptions.WaitOnAbnormalExit) { dbgInfo.bstrOptions += ";" + AD7Engine.WaitOnAbnormalExitSetting + "=True"; } if (_pyService.DebuggerOptions.WaitOnNormalExit) { dbgInfo.bstrOptions += ";" + AD7Engine.WaitOnNormalExitSetting + "=True"; } } if (_pyService.DebuggerOptions.TeeStandardOutput) { dbgInfo.bstrOptions += ";" + AD7Engine.RedirectOutputSetting + "=True"; } if (_pyService.DebuggerOptions.BreakOnSystemExitZero) { dbgInfo.bstrOptions += ";" + AD7Engine.BreakSystemExitZero + "=True"; } if (_pyService.DebuggerOptions.DebugStdLib) { dbgInfo.bstrOptions += ";" + AD7Engine.DebugStdLib + "=True"; } if (!String.IsNullOrWhiteSpace(interpArgs)) { dbgInfo.bstrOptions += ";" + AD7Engine.InterpreterOptions + "=" + interpArgs.Replace(";", ";;"); } var djangoDebugging = _project.GetProperty("DjangoDebugging"); bool enableDjango; if (!String.IsNullOrWhiteSpace(djangoDebugging) && Boolean.TryParse(djangoDebugging, out enableDjango)) { dbgInfo.bstrOptions += ";" + AD7Engine.EnableDjangoDebugging + "=True"; } } var env = new Dictionary <string, string>(props.GetEnvironment(true)); PythonProjectLaunchProperties.MergeEnvironmentBelow(env, null, true); if (env.Any()) { //Environment variables should be passed as a //null-terminated block of null-terminated strings. //Each string is in the following form:name=value\0 var buf = new StringBuilder(); foreach (var kv in env) { buf.AppendFormat("{0}={1}\0", kv.Key, kv.Value); } buf.Append("\0"); dbgInfo.bstrEnv = buf.ToString(); } if (props.GetIsNativeDebuggingEnabled() ?? false) { dbgInfo.dwClsidCount = 2; dbgInfo.pClsidList = Marshal.AllocCoTaskMem(sizeof(Guid) * 2); var engineGuids = (Guid *)dbgInfo.pClsidList; engineGuids[0] = dbgInfo.clsidCustom = DkmEngineId.NativeEng; engineGuids[1] = AD7Engine.DebugEngineGuid; } else { // Set the Python debugger dbgInfo.clsidCustom = new Guid(AD7Engine.DebugEngineId); dbgInfo.grfLaunch = (uint)__VSDBGLAUNCHFLAGS.DBGLAUNCH_StopDebuggingOnEnd; } }
private ProcessStartInfo CreateProcessStartInfo( CommandStartInfo startInfo, IPythonProjectLaunchProperties props ) { bool alwaysPause = startInfo.ExecuteInConsoleAndPause; // We only want to run the webserver in a console. startInfo.ExecuteIn = "console"; startInfo.AdjustArgumentsForProcessStartInfo(props.GetInterpreterPath(), handleConsoleAndPause: false); var psi = new ProcessStartInfo { FileName = startInfo.Filename, Arguments = startInfo.Arguments, WorkingDirectory = startInfo.WorkingDirectory, UseShellExecute = false }; var env = new Dictionary<string, string>(startInfo.EnvironmentVariables, StringComparer.OrdinalIgnoreCase); PythonProjectLaunchProperties.MergeEnvironmentBelow(env, new Dictionary<string, string> { { "SERVER_HOST", "localhost" }, { "SERVER_PORT", TestServerPortString } }, true); foreach(var kv in env) { psi.EnvironmentVariables[kv.Key] = kv.Value; } // Pause if the user has requested it. string pauseCommand = null; if (alwaysPause || _pyService.DebuggerOptions.WaitOnAbnormalExit && _pyService.DebuggerOptions.WaitOnNormalExit) { pauseCommand = "pause"; } else if (_pyService.DebuggerOptions.WaitOnAbnormalExit && !_pyService.DebuggerOptions.WaitOnNormalExit) { pauseCommand = "if errorlevel 1 pause"; } else if (_pyService.DebuggerOptions.WaitOnNormalExit && !_pyService.DebuggerOptions.WaitOnAbnormalExit) { pauseCommand = "if not errorlevel 1 pause"; } if (!string.IsNullOrEmpty(pauseCommand)) { psi.Arguments = string.Format("/c \"{0} {1}\" & {2}", ProcessOutput.QuoteSingleArgument(psi.FileName), psi.Arguments, pauseCommand ); psi.FileName = Path.Combine(Environment.SystemDirectory, "cmd.exe"); } return psi; }
private unsafe DebugTargetInfo CreateDebugTargetInfo( CommandStartInfo startInfo, IPythonProjectLaunchProperties props ) { var dti = new DebugTargetInfo(); var alwaysPause = startInfo.ExecuteInConsoleAndPause; // We only want to debug a web server in a console. startInfo.ExecuteIn = "console"; startInfo.AdjustArgumentsForProcessStartInfo(props.GetInterpreterPath(), handleConsoleAndPause: false); try { dti.Info.dlo = DEBUG_LAUNCH_OPERATION.DLO_CreateProcess; dti.Info.bstrExe = startInfo.Filename; dti.Info.bstrCurDir = startInfo.WorkingDirectory; dti.Info.bstrRemoteMachine = null; dti.Info.fSendStdoutToOutputWindow = 0; if (!(props.GetIsNativeDebuggingEnabled() ?? false)) { dti.Info.bstrOptions = string.Join(";", GetGlobalDebuggerOptions(true, alwaysPause) .Concat(GetProjectDebuggerOptions()) .Where(s => !string.IsNullOrEmpty(s)) .Select(s => s.Replace(";", ";;")) ); } if (startInfo.EnvironmentVariables != null && startInfo.EnvironmentVariables.Any()) { // Environment variables should be passed as a // null-terminated block of null-terminated strings. // Each string is in the following form:name=value\0 var buf = new StringBuilder(); foreach (var kv in startInfo.EnvironmentVariables) { buf.AppendFormat("{0}={1}\0", kv.Key, kv.Value); } buf.Append("\0"); dti.Info.bstrEnv = buf.ToString(); } dti.Info.bstrArg = startInfo.Arguments; if (props.GetIsNativeDebuggingEnabled() ?? false) { dti.Info.dwClsidCount = 2; dti.Info.pClsidList = Marshal.AllocCoTaskMem(sizeof(Guid) * 2); var engineGuids = (Guid*)dti.Info.pClsidList; engineGuids[0] = dti.Info.clsidCustom = DkmEngineId.NativeEng; engineGuids[1] = AD7Engine.DebugEngineGuid; } else { // Set the Python debugger dti.Info.clsidCustom = new Guid(AD7Engine.DebugEngineId); dti.Info.grfLaunch = (uint)__VSDBGLAUNCHFLAGS.DBGLAUNCH_StopDebuggingOnEnd; } // Null out dti so that it is not disposed before we return. var result = dti; dti = null; return result; } finally { if (dti != null) { dti.Dispose(); } } }
/// <summary> /// Creates process info used to start the project with no debugging. /// </summary> private ProcessStartInfo CreateProcessStartInfoNoDebug(string startupFile, IPythonProjectLaunchProperties props) { string command = CreateCommandLineNoDebug(startupFile, props); ProcessStartInfo startInfo; if (!(props.GetIsWindowsApplication() ?? false) && (_pyService.DebuggerOptions.WaitOnAbnormalExit || _pyService.DebuggerOptions.WaitOnNormalExit)) { command = "/c \"\"" + props.GetInterpreterPath() + "\" " + command; if (_pyService.DebuggerOptions.WaitOnNormalExit && _pyService.DebuggerOptions.WaitOnAbnormalExit) { command += " & pause"; } else if (_pyService.DebuggerOptions.WaitOnNormalExit) { command += " & if not errorlevel 1 pause"; } else if (_pyService.DebuggerOptions.WaitOnAbnormalExit) { command += " & if errorlevel 1 pause"; } command += "\""; startInfo = new ProcessStartInfo(Path.Combine(Environment.SystemDirectory, "cmd.exe"), command); } else { startInfo = new ProcessStartInfo(props.GetInterpreterPath(), command); } startInfo.WorkingDirectory = props.GetWorkingDirectory(); //In order to update environment variables we have to set UseShellExecute to false startInfo.UseShellExecute = false; var env = new Dictionary<string, string>(props.GetEnvironment(true), StringComparer.OrdinalIgnoreCase); PythonProjectLaunchProperties.MergeEnvironmentBelow(env, null, true); foreach (var kv in env) { startInfo.EnvironmentVariables[kv.Key] = kv.Value; } return startInfo; }
/// <summary> /// Sets up debugger information. /// </summary> private unsafe void SetupDebugInfo( ref VsDebugTargetInfo dbgInfo, string startupFile, IPythonProjectLaunchProperties props ) { bool enableNativeCodeDebugging = false; dbgInfo.dlo = DEBUG_LAUNCH_OPERATION.DLO_CreateProcess; dbgInfo.bstrExe = props.GetInterpreterPath(); dbgInfo.bstrCurDir = props.GetWorkingDirectory(); dbgInfo.bstrArg = CreateCommandLineDebug(startupFile, props); dbgInfo.bstrRemoteMachine = null; dbgInfo.fSendStdoutToOutputWindow = 0; if (!enableNativeCodeDebugging) { // Set up project- and environment-specific debug options. Global debug options are passed // to the engine by CustomDebuggerEventHandler via IDebugEngine2.SetMetric in response to // the VsPackageMessage.SetDebugOptions custom debug event. string interpArgs = _project.GetProperty(PythonConstants.InterpreterArgumentsSetting); dbgInfo.bstrOptions = AD7Engine.VersionSetting + "=" + _project.GetInterpreterFactory().GetLanguageVersion().ToString(); if (props.GetIsWindowsApplication() ?? false) { dbgInfo.bstrOptions += ";" + AD7Engine.IsWindowsApplication + "=True"; } if (!String.IsNullOrWhiteSpace(interpArgs)) { dbgInfo.bstrOptions += ";" + AD7Engine.InterpreterOptions + "=" + interpArgs.Replace(";", ";;"); } var djangoDebugging = _project.GetProperty("DjangoDebugging"); bool enableDjango; if (!String.IsNullOrWhiteSpace(djangoDebugging) && Boolean.TryParse(djangoDebugging, out enableDjango)) { dbgInfo.bstrOptions += ";" + AD7Engine.EnableDjangoDebugging + "=True"; } } var env = new Dictionary<string, string>(props.GetEnvironment(true), StringComparer.OrdinalIgnoreCase); PythonProjectLaunchProperties.MergeEnvironmentBelow(env, null, true); if (env.Any()) { //Environment variables should be passed as a //null-terminated block of null-terminated strings. //Each string is in the following form:name=value\0 var buf = new StringBuilder(); foreach (var kv in env) { buf.AppendFormat("{0}={1}\0", kv.Key, kv.Value); } buf.Append("\0"); dbgInfo.bstrEnv = buf.ToString(); } if (props.GetIsNativeDebuggingEnabled() ?? false) { dbgInfo.dwClsidCount = 2; dbgInfo.pClsidList = Marshal.AllocCoTaskMem(sizeof(Guid) * 2); var engineGuids = (Guid*)dbgInfo.pClsidList; engineGuids[0] = dbgInfo.clsidCustom = DkmEngineId.NativeEng; engineGuids[1] = AD7Engine.DebugEngineGuid; } else { // Set the Python debugger dbgInfo.clsidCustom = new Guid(AD7Engine.DebugEngineId); dbgInfo.grfLaunch = (uint)__VSDBGLAUNCHFLAGS.DBGLAUNCH_StopDebuggingOnEnd; } }