Example #1
0
        public static ProcessStartInfo CreateProcessStartInfo(IServiceProvider provider, LaunchConfiguration config)
        {
            var psi = new ProcessStartInfo {
                FileName = config.GetInterpreterPath(),
                Arguments = string.Join(" ", new[] {
                    config.InterpreterArguments,
                    ProcessOutput.QuoteSingleArgument(config.ScriptName),
                    config.ScriptArguments
                }.Where(s => !string.IsNullOrEmpty(s))),
                WorkingDirectory = config.WorkingDirectory,
                UseShellExecute = false
            };

            if (string.IsNullOrEmpty(psi.FileName)) {
                throw new FileNotFoundException(Strings.DebugLaunchInterpreterMissing);
            }
            if (!File.Exists(psi.FileName)) {
                throw new FileNotFoundException(Strings.DebugLaunchInterpreterMissing_Path.FormatUI(psi.FileName));
            }
            if (string.IsNullOrEmpty(psi.WorkingDirectory)) {
                psi.WorkingDirectory = PathUtils.GetParent(config.ScriptName);
            }
            if (string.IsNullOrEmpty(psi.WorkingDirectory)) {
                throw new DirectoryNotFoundException(Strings.DebugLaunchWorkingDirectoryMissing);
            }
            if (!Directory.Exists(psi.WorkingDirectory)) {
                throw new DirectoryNotFoundException(Strings.DebugLaunchWorkingDirectoryMissing_Path.FormatUI(psi.FileName));
            }

            foreach (var kv in provider.GetPythonToolsService().GetFullEnvironment(config)) {
                psi.Environment[kv.Key] = kv.Value;
            }

            var pyService = provider.GetPythonToolsService();
            // Pause if the user has requested it.
            string pauseCommand = null;
            if (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;
        }
Example #2
0
        public static unsafe DebugTargetInfo CreateDebugTargetInfo(IServiceProvider provider, LaunchConfiguration config)
        {
            var pyService = provider.GetPythonToolsService();
            var dti = new DebugTargetInfo(provider);

            try {
                dti.Info.dlo = DEBUG_LAUNCH_OPERATION.DLO_CreateProcess;
                dti.Info.bstrExe = config.GetInterpreterPath();
                dti.Info.bstrCurDir = config.WorkingDirectory;
                if (string.IsNullOrEmpty(dti.Info.bstrCurDir)) {
                    dti.Info.bstrCurDir = PathUtils.GetParent(config.ScriptName);
                }

                dti.Info.bstrRemoteMachine = null;
                dti.Info.fSendStdoutToOutputWindow = 0;

                bool nativeDebug = config.GetLaunchOption(PythonConstants.EnableNativeCodeDebugging).IsTrue();
                if (!nativeDebug) {
                    dti.Info.bstrOptions = string.Join(";",
                        GetGlobalDebuggerOptions(pyService)
                            .Concat(GetLaunchConfigurationOptions(config))
                            .Where(s => !string.IsNullOrEmpty(s))
                            .Select(s => s.Replace(";", ";;"))
                    );
                }

                // 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 provider.GetPythonToolsService().GetFullEnvironment(config)) {
                    buf.AppendFormat("{0}={1}\0", kv.Key, kv.Value);
                }
                if (buf.Length > 0) {
                    buf.Append("\0");
                    dti.Info.bstrEnv = buf.ToString();
                }

                var args = string.Join(" ", new[] {
                    config.InterpreterArguments,
                    ProcessOutput.QuoteSingleArgument(config.ScriptName),
                    config.ScriptArguments
                }.Where(s => !string.IsNullOrEmpty(s)));

                if (config.Environment != null) {
                    args = DoSubstitutions(config.Environment, args);
                }
                dti.Info.bstrArg = args;

                if (nativeDebug) {
                    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();
                }
            }
        }
Example #3
0
        private static void RunProfiler(SessionNode session, LaunchConfiguration config, bool openReport) {
            var process = new ProfiledProcess(
                (PythonToolsService)session._serviceProvider.GetService(typeof(PythonToolsService)),
                config.GetInterpreterPath(),
                string.Join(" ", ProcessOutput.QuoteSingleArgument(config.ScriptName), config.ScriptArguments),
                config.WorkingDirectory,
                session._serviceProvider.GetPythonToolsService().GetFullEnvironment(config)
            );

            string baseName = Path.GetFileNameWithoutExtension(session.Filename);
            string date = DateTime.Now.ToString("yyyyMMdd");
            string outPath = Path.Combine(Path.GetTempPath(), baseName + "_" + date + ".vsp");

            int count = 1;
            while (File.Exists(outPath)) {
                outPath = Path.Combine(Path.GetTempPath(), baseName + "_" + date + "(" + count + ").vsp");
                count++;
            }

            process.ProcessExited += (sender, args) => {
                var dte = (EnvDTE.DTE)session._serviceProvider.GetService(typeof(EnvDTE.DTE));
                _profilingProcess = null;
                _stopCommand.Enabled = false;
                _startCommand.Enabled = true;
                if (openReport && File.Exists(outPath)) {
                    dte.ItemOperations.OpenFile(outPath);
                }
            };

            session.AddProfile(outPath);

            process.StartProfiling(outPath);
            _profilingProcess = process;
            _stopCommand.Enabled = true;
            _startCommand.Enabled = false;
        }