예제 #1
0
        /// <summary>
        /// This is called on F5 to return the list of debug targets. What we return depends on the type
        /// of project.
        /// </summary>
        private async Task <DebugLaunchSettings> GetConsoleTargetForProfile(ILaunchProfile resolvedProfile, DebugLaunchOptions launchOptions,
                                                                            bool useCmdShell)
        {
            var settings = new DebugLaunchSettings(launchOptions);

            string executable, arguments;

            string projectFolder     = Path.GetDirectoryName(UnconfiguredProject.FullPath);
            var    configuredProject = await GetConfiguredProjectForDebugAsync().ConfigureAwait(false);

            // If no working directory specified in the profile, we default to the one returned from GetRunnableProjectInformationAsync (if running
            // the project), or the project folder.
            string defaultWorkingDir = projectFolder;

            // Is this profile just running the project? If so we ignore the exe
            if (IsRunProjectCommand(resolvedProfile))
            {
                // Can't run a class library directly
                if (await GetIsClassLibraryAsync().ConfigureAwait(false))
                {
                    throw new Exception(VSResources.ProjectNotRunnableDirectly);
                }

                // Get the executable to run, the arguments and the default working directory
                var runData = await GetRunnableProjectInformationAsync(configuredProject).ConfigureAwait(false);

                executable = runData.Item1;
                arguments  = runData.Item2;
                if (!string.IsNullOrWhiteSpace(runData.Item3))
                {
                    defaultWorkingDir = runData.Item3;
                }

                if (!string.IsNullOrWhiteSpace(resolvedProfile.CommandLineArgs))
                {
                    arguments = arguments + " " + resolvedProfile.CommandLineArgs;
                }
            }
            else
            {
                executable = resolvedProfile.ExecutablePath;
                arguments  = resolvedProfile.CommandLineArgs;
            }

            string workingDir;

            if (string.IsNullOrWhiteSpace(resolvedProfile.WorkingDirectory))
            {
                workingDir = defaultWorkingDir;
            }
            else
            {
                // If the working directory is not rooted we assume it is relative to the project directory
                workingDir = TheFileSystem.GetFullPath(Path.Combine(projectFolder, resolvedProfile.WorkingDirectory.Replace("/", "\\")));
            }

            // IF the executable is not rooted, we want to make is relative to the workingDir unless is doesn't contain
            // any path elements. In that case we are going to assume it is in the current directory of the VS process, or on
            // the environment path. If we can't find it, we just launch it as before.
            if (!string.IsNullOrWhiteSpace(executable))
            {
                executable = executable.Replace("/", "\\");
                if (Path.GetPathRoot(executable) == "\\")
                {
                    // Root of current drive
                    executable = TheFileSystem.GetFullPath(executable);
                }
                else if (!Path.IsPathRooted(executable))
                {
                    if (executable.Contains("\\"))
                    {
                        // Combine with the working directory used by the profile
                        executable = TheFileSystem.GetFullPath(Path.Combine(workingDir, executable));
                    }
                    else
                    {
                        // Try to resolve against the current working directory (for compat) and failing that, the environment path.
                        var exeName  = executable.EndsWith(".exe", StringComparison.OrdinalIgnoreCase)? executable : executable + ".exe";
                        var fullPath = TheFileSystem.GetFullPath(exeName);
                        if (TheFileSystem.FileExists(fullPath))
                        {
                            executable = fullPath;
                        }
                        else
                        {
                            fullPath = GetFullPathOfExeFromEnvironmentPath(exeName);
                            if (fullPath != null)
                            {
                                executable = fullPath;
                            }
                        }
                    }
                }
            }

            // Now validate the executable path and working directory exist
            ValidateSettings(executable, workingDir, resolvedProfile.Name);
            GetExeAndArguments(useCmdShell, executable, arguments, out string finalExecutable, out string finalArguments);

            // Apply environment variables.
            if (resolvedProfile.EnvironmentVariables != null && resolvedProfile.EnvironmentVariables.Count > 0)
            {
                foreach (var kvp in resolvedProfile.EnvironmentVariables)
                {
                    settings.Environment[kvp.Key] = kvp.Value;
                }
            }

            settings.Executable            = finalExecutable;
            settings.Arguments             = finalArguments;
            settings.CurrentDirectory      = workingDir;
            settings.LaunchOperation       = DebugLaunchOperation.CreateProcess;
            settings.LaunchDebugEngineGuid = await GetDebuggingEngineAsync(configuredProject).ConfigureAwait(false);

            if (resolvedProfile.NativeDebuggingIsEnabled())
            {
                settings.AdditionalDebugEngines.Add(DebuggerEngines.NativeOnlyEngine);
            }

            if (settings.Environment.Count > 0)
            {
                settings.LaunchOptions = settings.LaunchOptions | DebugLaunchOptions.MergeEnvironment;
            }

            return(settings);
        }
        private async Task <DebugLaunchSettings> GetConsoleTargetForProfile(ILaunchProfile resolvedProfile, DebugLaunchOptions launchOptions, bool validateSettings)
        {
            var settings = new DebugLaunchSettings(launchOptions);

            string executable, arguments;

            string            projectFolder     = Path.GetDirectoryName(_project.FullPath);
            ConfiguredProject configuredProject = await GetConfiguredProjectForDebugAsync();

            // If no working directory specified in the profile, we default to output directory. If for some reason the output directory
            // is not specified, fall back to the project folder.
            string defaultWorkingDir = await GetOutputDirectoryAsync(configuredProject);

            if (string.IsNullOrEmpty(defaultWorkingDir))
            {
                defaultWorkingDir = projectFolder;
            }
            else
            {
                if (!Path.IsPathRooted(defaultWorkingDir))
                {
                    defaultWorkingDir = _fileSystem.GetFullPath(Path.Combine(projectFolder, defaultWorkingDir));
                }

                // If the directory at OutDir doesn't exist, fall back to the project folder
                if (!_fileSystem.DirectoryExists(defaultWorkingDir))
                {
                    defaultWorkingDir = projectFolder;
                }
            }

            // Is this profile just running the project? If so we ignore the exe
            if (IsRunProjectCommand(resolvedProfile))
            {
                // Get the executable to run, the arguments and the default working directory
                Tuple <string, string, string> runData = await GetRunnableProjectInformationAsync(configuredProject, validateSettings);

                executable = runData.Item1;
                arguments  = runData.Item2;
                if (!string.IsNullOrWhiteSpace(runData.Item3))
                {
                    defaultWorkingDir = runData.Item3;
                }

                if (!string.IsNullOrWhiteSpace(resolvedProfile.CommandLineArgs))
                {
                    arguments = arguments + " " + resolvedProfile.CommandLineArgs;
                }
            }
            else
            {
                executable = resolvedProfile.ExecutablePath;
                arguments  = resolvedProfile.CommandLineArgs;
            }

            string workingDir;

            if (string.IsNullOrWhiteSpace(resolvedProfile.WorkingDirectory))
            {
                workingDir = defaultWorkingDir;
            }
            else
            {
                // If the working directory is not rooted we assume it is relative to the project directory
                workingDir = _fileSystem.GetFullPath(Path.Combine(projectFolder, resolvedProfile.WorkingDirectory.Replace("/", "\\")));
            }

            // IF the executable is not rooted, we want to make is relative to the workingDir unless is doesn't contain
            // any path elements. In that case we are going to assume it is in the current directory of the VS process, or on
            // the environment path. If we can't find it, we just launch it as before.
            if (!string.IsNullOrWhiteSpace(executable))
            {
                executable = executable.Replace("/", "\\");
                if (Path.GetPathRoot(executable) == "\\")
                {
                    // Root of current drive
                    executable = _fileSystem.GetFullPath(executable);
                }
                else if (!Path.IsPathRooted(executable))
                {
                    if (executable.Contains("\\"))
                    {
                        // Combine with the working directory used by the profile
                        executable = _fileSystem.GetFullPath(Path.Combine(workingDir, executable));
                    }
                    else
                    {
                        // Try to resolve against the current working directory (for compat) and failing that, the environment path.
                        string exeName  = executable.EndsWith(".exe", StringComparison.OrdinalIgnoreCase) ? executable : executable + ".exe";
                        string fullPath = _fileSystem.GetFullPath(exeName);
                        if (_fileSystem.FileExists(fullPath))
                        {
                            executable = fullPath;
                        }
                        else
                        {
                            fullPath = GetFullPathOfExeFromEnvironmentPath(exeName);
                            if (fullPath != null)
                            {
                                executable = fullPath;
                            }
                        }
                    }
                }
            }

            if (validateSettings)
            {
                ValidateSettings(executable, workingDir, resolvedProfile.Name);
            }

            // Apply environment variables.
            if (resolvedProfile.EnvironmentVariables != null && resolvedProfile.EnvironmentVariables.Count > 0)
            {
                foreach ((string key, string value) in resolvedProfile.EnvironmentVariables)
                {
                    settings.Environment[key] = value;
                }
            }

            settings.LaunchOperation       = DebugLaunchOperation.CreateProcess;
            settings.LaunchDebugEngineGuid = await GetDebuggingEngineAsync(configuredProject);

            if (resolvedProfile.NativeDebuggingIsEnabled())
            {
                settings.AdditionalDebugEngines.Add(DebuggerEngines.NativeOnlyEngine);
            }

            if (settings.Environment.Count > 0)
            {
                settings.LaunchOptions |= DebugLaunchOptions.MergeEnvironment;
            }

            bool useCmdShell = false;

            if (await IsConsoleAppAsync())
            {
                if (await IsIntegratedConsoleEnabledAsync())
                {
                    settings.LaunchOptions |= DebugLaunchOptions.IntegratedConsole;
                }

                useCmdShell = UseCmdShellForConsoleLaunch(resolvedProfile, settings.LaunchOptions);
            }

            GetExeAndArguments(useCmdShell, executable, arguments, out string finalExecutable, out string finalArguments);

            settings.Executable       = finalExecutable;
            settings.Arguments        = finalArguments;
            settings.CurrentDirectory = workingDir;

            return(settings);
        }
        /// <summary>
        /// This is called on F5 to return the list of debug targets. What we return depends on the type
        /// of project.
        /// </summary>
        private async Task <DebugLaunchSettings> GetConsoleTargetForProfile(ILaunchProfile resolvedProfile, DebugLaunchOptions launchOptions,
                                                                            bool useCmdShell)
        {
            var settings = new DebugLaunchSettings(launchOptions);

            string executable, arguments;

            string projectFolder     = Path.GetDirectoryName(UnconfiguredProject.FullPath);
            var    configuredProject = await GetConfiguredProjectForDebugAsync().ConfigureAwait(false);

            // If no working directory specified in the profile, we default to the one returned from GetRunnableProjectInformationAsync (if running
            // the project), or the project folder.
            string defaultWorkingDir = projectFolder;

            // Is this profile just running the project? If so we ignore the exe
            if (IsRunProjectCommand(resolvedProfile))
            {
                // Can't run a class library directly
                if (await GetIsClassLibraryAsync().ConfigureAwait(false))
                {
                    throw new Exception(VSResources.ProjectNotRunnableDirectly);
                }

                // Get the executable to run, the arguments and the default working directory
                var runData = await GetRunnableProjectInformationAsync(configuredProject).ConfigureAwait(false);

                executable = runData.Item1;
                arguments  = runData.Item2;
                if (!string.IsNullOrWhiteSpace(runData.Item3))
                {
                    defaultWorkingDir = runData.Item3;
                }

                if (!string.IsNullOrWhiteSpace(resolvedProfile.CommandLineArgs))
                {
                    arguments = arguments + " " + resolvedProfile.CommandLineArgs;
                }
            }
            else
            {
                executable = resolvedProfile.ExecutablePath;
                arguments  = resolvedProfile.CommandLineArgs;
            }

            string workingDir;

            if (string.IsNullOrWhiteSpace(resolvedProfile.WorkingDirectory))
            {
                workingDir = defaultWorkingDir;
            }
            else
            {
                // If the working directory is not rooted we assume it is relative to the project directory
                if (Path.IsPathRooted(resolvedProfile.WorkingDirectory))
                {
                    workingDir = resolvedProfile.WorkingDirectory;
                }
                else
                {
                    workingDir = Path.GetFullPath(Path.Combine(projectFolder, resolvedProfile.WorkingDirectory));
                }
            }

            // IF the executable is not rooted, we want to make is relative to the workingDir unless is doesn't contain
            // any path elements. In that case we are going to assume it is on the path
            if (!string.IsNullOrWhiteSpace(executable))
            {
                if (!Path.IsPathRooted(executable) && executable.IndexOf(Path.DirectorySeparatorChar) != -1)
                {
                    executable = Path.GetFullPath(Path.Combine(workingDir, executable));
                }
            }

            // Now validate the executable path and working directory exist
            ValidateSettings(executable, workingDir, resolvedProfile.Name);
            GetExeAndArguments(useCmdShell, executable, arguments, out string finalExecutable, out string finalArguments);


            // Apply environment variables.
            if (resolvedProfile.EnvironmentVariables != null && resolvedProfile.EnvironmentVariables.Count > 0)
            {
                foreach (var kvp in resolvedProfile.EnvironmentVariables)
                {
                    settings.Environment[kvp.Key] = kvp.Value;
                }
            }

            settings.Executable            = finalExecutable;
            settings.Arguments             = finalArguments;
            settings.CurrentDirectory      = workingDir;
            settings.LaunchOperation       = DebugLaunchOperation.CreateProcess;
            settings.LaunchDebugEngineGuid = await GetDebuggingEngineAsync(configuredProject).ConfigureAwait(false);

            if (resolvedProfile.NativeDebuggingIsEnabled())
            {
                settings.AdditionalDebugEngines.Add(DebuggerEngines.NativeOnlyEngine);
            }

            settings.LaunchOptions = launchOptions | DebugLaunchOptions.StopDebuggingOnEnd;
            if (settings.Environment.Count > 0)
            {
                settings.LaunchOptions = settings.LaunchOptions | DebugLaunchOptions.MergeEnvironment;
            }

            return(settings);
        }