示例#1
0
        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);
        }
示例#2
0
        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();
                }
            }
        }
示例#3
0
        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);
        }
示例#4
0
        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;
        }
示例#5
0
        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;
        }
示例#6
0
        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();
                }
            }
        }
示例#7
0
        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);
        }
示例#8
0
        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);
        }