private CommandStartInfo GetStartInfo(bool debug, bool runUnknownCommands = true) { var cmd = debug ? _debugServerCommand : _runServerCommand; var customCmd = cmd as CustomCommand; if (customCmd == null && cmd != null) { // We have a command we don't understand, so we'll execute it // but won't start debugging. The (presumably) flavored project // that provided the command is responsible for handling the // attach. if (runUnknownCommands) { cmd.Execute(null); } return(null); } CommandStartInfo startInfo = null; var project2 = _project as IPythonProject2; if (customCmd != null && project2 != null) { // We have one of our own commands, so let's use the actual // start info. try { startInfo = customCmd.GetStartInfo(project2); } catch (InvalidOperationException ex) { var target = _project.GetProperty(debug ? DebugWebServerTargetProperty : RunWebServerTargetProperty ); if (string.IsNullOrEmpty(target) && !File.Exists(_project.GetStartupFile())) { // The exception was raised because no startup file // is set. throw new InvalidOperationException(SR.GetString(SR.NoStartupFileAvailable), ex); } else { throw; } } } if (startInfo == null) { if (!File.Exists(_project.GetStartupFile())) { throw new InvalidOperationException(SR.GetString(SR.NoStartupFileAvailable)); } // No command, so set up a startInfo that looks like the default // launcher. startInfo = new CommandStartInfo { Filename = _project.GetStartupFile(), Arguments = _project.GetProperty(CommonConstants.CommandLineArguments) ?? string.Empty, WorkingDirectory = _project.GetWorkingDirectory(), EnvironmentVariables = null, TargetType = "script", ExecuteIn = "console" }; } return(startInfo); }
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(); } } }
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 CommandStartInfo GetStartInfo(bool debug, bool runUnknownCommands = true) { var cmd = debug ? _debugServerCommand : _runServerCommand; var customCmd = cmd as CustomCommand; if (customCmd == null && cmd != null) { // We have a command we don't understand, so we'll execute it // but won't start debugging. The (presumably) flavored project // that provided the command is responsible for handling the // attach. if (runUnknownCommands) { cmd.Execute(null); } return null; } CommandStartInfo startInfo = null; var project2 = _project as IPythonProject2; if (customCmd != null && project2 != null) { // We have one of our own commands, so let's use the actual // start info. try { startInfo = customCmd.GetStartInfo(project2); } catch (InvalidOperationException ex) { var target = _project.GetProperty(debug ? DebugWebServerTargetProperty : RunWebServerTargetProperty ); if (string.IsNullOrEmpty(target) && !File.Exists(_project.GetStartupFile())) { // The exception was raised because no startup file // is set. throw new InvalidOperationException(SR.GetString(SR.NoStartupFileAvailable), ex); } else { throw; } } } if (startInfo == null) { if (!File.Exists(_project.GetStartupFile())) { throw new InvalidOperationException(SR.GetString(SR.NoStartupFileAvailable)); } // No command, so set up a startInfo that looks like the default // launcher. startInfo = new CommandStartInfo { Filename = _project.GetStartupFile(), Arguments = _project.GetProperty(CommonConstants.CommandLineArguments) ?? string.Empty, WorkingDirectory = _project.GetWorkingDirectory(), EnvironmentVariables = null, TargetType = "script", ExecuteIn = "console" }; } 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(); } } }
public int LaunchProject(bool debug) { bool isWindows; if (!Boolean.TryParse(_project.GetProperty(CommonConstants.IsWindowsApplication) ?? Boolean.FalseString, out isWindows)) { isWindows = false; } var cmd = debug ? _debugServerCommand : _runServerCommand; var customCmd = cmd as CustomCommand; if (customCmd == null && cmd != null) { // We have a command we don't understand, so we'll execute it // but won't start debugging. The (presumably) flavored project // that provided the command is responsible for handling the // attach. cmd.Execute(null); return(VSConstants.S_OK); } CommandStartInfo startInfo = null; var project2 = _project as IPythonProject2; if (customCmd != null && project2 != null) { // We have one of our own commands, so let's use the actual // start info. try { startInfo = customCmd.GetStartInfo(project2); } catch (InvalidOperationException ex) { var target = _project.GetProperty(debug ? DebugWebServerTargetProperty : RunWebServerTargetProperty ); if (string.IsNullOrEmpty(target) && !File.Exists(_project.GetStartupFile())) { // The exception was raised because no startup file // is set. throw new InvalidOperationException(SR.GetString(SR.NoStartupFileAvailable), ex); } else { throw; } } } if (startInfo == null) { if (!File.Exists(_project.GetStartupFile())) { throw new InvalidOperationException(SR.GetString(SR.NoStartupFileAvailable)); } // No command, so set up a startInfo that looks like the default // launcher. startInfo = new CommandStartInfo { Filename = _project.GetStartupFile(), Arguments = _project.GetProperty(CommonConstants.CommandLineArguments) ?? string.Empty, WorkingDirectory = _project.GetWorkingDirectory(), EnvironmentVariables = null, TargetType = "script", ExecuteIn = "console" }; } if (isWindows) { // Must run hidden if running with pythonw startInfo.ExecuteIn = "hidden"; } var env = startInfo.EnvironmentVariables; if (env == null) { env = startInfo.EnvironmentVariables = new Dictionary <string, string>(); } string value; if (!env.TryGetValue("SERVER_HOST", out value) || string.IsNullOrEmpty(value)) { env["SERVER_HOST"] = "localhost"; } int dummyInt; if (!env.TryGetValue("SERVER_PORT", out value) || string.IsNullOrEmpty(value) || !int.TryParse(value, out dummyInt)) { env["SERVER_PORT"] = TestServerPortString; } if (debug) { _pyService.Logger.LogEvent(Logging.PythonLogEvent.Launch, 1); using (var dsi = CreateDebugTargetInfo(startInfo, GetInterpreterPath(_project, isWindows))) { dsi.Launch(_serviceProvider); } } else { _pyService.Logger.LogEvent(Logging.PythonLogEvent.Launch, 0); var psi = CreateProcessStartInfo(startInfo, GetInterpreterPath(_project, isWindows)); var process = Process.Start(psi); if (process != null) { StartBrowser(GetFullUrl(), () => process.HasExited); } } return(VSConstants.S_OK); }
private ProcessStartInfo CreateProcessStartInfo( CommandStartInfo startInfo, string interpreterPath ) { bool alwaysPause = startInfo.ExecuteInConsoleAndPause; // We only want to run the webserver in a console. startInfo.ExecuteIn = "console"; startInfo.AdjustArgumentsForProcessStartInfo(interpreterPath, handleConsoleAndPause: false); var psi = new ProcessStartInfo { FileName = startInfo.Filename, Arguments = startInfo.Arguments, WorkingDirectory = startInfo.WorkingDirectory, UseShellExecute = false }; if (startInfo.EnvironmentVariables != null) { foreach (var kv in startInfo.EnvironmentVariables) { psi.EnvironmentVariables[kv.Key] = kv.Value; } } if (!psi.EnvironmentVariables.ContainsKey("SERVER_HOST") || string.IsNullOrEmpty(psi.EnvironmentVariables["SERVER_HOST"])) { psi.EnvironmentVariables["SERVER_HOST"] = "localhost"; } int dummyInt; if (!psi.EnvironmentVariables.ContainsKey("SERVER_PORT") || string.IsNullOrEmpty(psi.EnvironmentVariables["SERVER_PORT"]) || !int.TryParse(psi.EnvironmentVariables["SERVER_PORT"], out dummyInt)) { psi.EnvironmentVariables["SERVER_PORT"] = TestServerPortString; } // 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); }