/// <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); }