public override async Task<IReadOnlyList<IDebugLaunchSettings>> QueryDebugTargetsAsync(DebugLaunchOptions launchOptions) { var settings = new DebugLaunchSettings(launchOptions); // The properties that are available via DebuggerProperties are determined by the property XAML files in your project. settings.Executable = @"C:\Users\Igal\AppData\Roaming\scriptcs\scriptcs.exe"; settings.Arguments = @"D:\code\ScriptCSApp5\ScriptCSApp5\app.csx"; settings.LaunchOperation = DebugLaunchOperation.CreateProcess; return new IDebugLaunchSettings[] { settings }; }
public override async Task<IReadOnlyList<IDebugLaunchSettings>> QueryDebugTargetsAsync(DebugLaunchOptions launchOptions) { var settings = new DebugLaunchSettings(launchOptions); // The properties that are available via DebuggerProperties are determined by the property XAML files in your project. var debuggerProperties = await this.DebuggerProperties.GetXSharpDebuggerPropertiesAsync(); settings.CurrentDirectory = await debuggerProperties.XSharpDebuggerWorkingDirectory.GetEvaluatedValueAtEndAsync(); settings.Executable = await debuggerProperties.XSharpDebuggerCommand.GetEvaluatedValueAtEndAsync(); settings.Arguments = await debuggerProperties.XSharpDebuggerCommandArguments.GetEvaluatedValueAtEndAsync(); settings.LaunchOperation = DebugLaunchOperation.CreateProcess; // TODO: Specify the right debugger engine settings.LaunchDebugEngineGuid = DebuggerEngines.ManagedOnlyEngine; return new IDebugLaunchSettings[] { settings }; }
public override async Task<IReadOnlyList<IDebugLaunchSettings>> QueryDebugTargetsAsync(DebugLaunchOptions launchOptions) { var settings = new DebugLaunchSettings(launchOptions); // The properties that are available via DebuggerProperties are determined by the property XAML files in your project. var debuggerProperties = await this.DebuggerProperties.GetLuaDebuggerPropertiesAsync(); settings.Executable = await debuggerProperties.LocalDebuggerCommand.GetEvaluatedValueAtEndAsync(); if (settings.Executable == null) { var generalProperties = await this.DebuggerProperties.GetConfigurationGeneralPropertiesAsync(); settings.Executable = await generalProperties.TargetPath.GetEvaluatedValueAtEndAsync(); } settings.Arguments = await debuggerProperties.LocalDebuggerCommandArguments.GetEvaluatedValueAtEndAsync(); settings.CurrentDirectory = await debuggerProperties.LocalDebuggerWorkingDirectory.GetEvaluatedValueAtEndAsync(); settings.LaunchOperation = DebugLaunchOperation.CreateProcess; settings.LaunchDebugEngineGuid = new Guid(Microsoft.VisualStudio.Debugger.Lua.EngineConstants.EngineId);// DebuggerEngines.NativeOnlyEngine; return new IDebugLaunchSettings[] { settings }; }
public override Task<IReadOnlyList<IDebugLaunchSettings>> QueryDebugTargetsAsync(DebugLaunchOptions launchOptions) { var targets = new List<IDebugLaunchSettings>(); if (Session.IsHostRunning) { uint pid = RDebugPortSupplier.GetProcessId(Session.Id); var target = new DebugLaunchSettings(launchOptions) { LaunchOperation = DebugLaunchOperation.AlreadyRunning, PortSupplierGuid = DebuggerGuids.PortSupplier, PortName = RDebugPortSupplier.PortName, LaunchDebugEngineGuid = DebuggerGuids.DebugEngine, ProcessId = (int)pid, Executable = RDebugPortSupplier.GetExecutableForAttach(pid), }; targets.Add(target); } return Task.FromResult((IReadOnlyList<IDebugLaunchSettings>)targets); }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public override async Task<IReadOnlyList<IDebugLaunchSettings>> QueryDebugTargetsAsync (DebugLaunchOptions launchOptions) { LoggingUtils.PrintFunction (); IDebugLauncher debugLauncher = null; DebugLaunchSettings debugLaunchSettings = new DebugLaunchSettings (launchOptions); try { debugLauncher = GetDebugLauncher (ServiceProvider); debugLauncher.PrepareLaunch (); Dictionary<string, string> projectProperties = await DebuggerProperties.ProjectPropertiesToDictionary (); projectProperties.Add ("ConfigurationGeneral.ProjectDir", Path.GetDirectoryName (DebuggerProperties.GetConfiguredProject ().UnconfiguredProject.FullPath)); LaunchConfiguration launchConfig = debugLauncher.GetLaunchConfigurationFromProjectProperties (projectProperties); LaunchProps [] launchProps = debugLauncher.GetLaunchPropsFromProjectProperties (projectProperties); if (launchOptions.HasFlag (DebugLaunchOptions.NoDebug)) { debugLaunchSettings = (DebugLaunchSettings) debugLauncher.StartWithoutDebugging ((int) launchOptions, launchConfig, launchProps, projectProperties); } else { debugLaunchSettings = (DebugLaunchSettings) debugLauncher.StartWithDebugging ((int) launchOptions, launchConfig, launchProps, projectProperties); } } catch (Exception e) { HandleExceptionDialog (e, debugLauncher); } return new IDebugLaunchSettings [] { debugLaunchSettings }; }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public override async Task<IReadOnlyList<IDebugLaunchSettings>> QueryDebugTargetsAsync (DebugLaunchOptions launchOptions) { LoggingUtils.PrintFunction (); IDebugLauncher debugLauncher = null; DebugLaunchSettings debugLaunchSettings = new DebugLaunchSettings (launchOptions); try { debugLauncher = GetDebugLauncher (ServiceProvider); debugLauncher.PrepareLaunch (); Dictionary<string, string> projectProperties = await DebuggerProperties.ProjectPropertiesToDictionary (); projectProperties.Add ("ConfigurationGeneral.ProjectDir", Path.GetDirectoryName (DebuggerProperties.GetConfiguredProject ().UnconfiguredProject.FullPath)); LaunchConfiguration launchConfig = debugLauncher.GetLaunchConfigurationFromProjectProperties (projectProperties); LaunchProps [] launchProps = debugLauncher.GetLaunchPropsFromProjectProperties (projectProperties); if (launchOptions.HasFlag (DebugLaunchOptions.NoDebug)) { debugLaunchSettings = (DebugLaunchSettings) debugLauncher.StartWithoutDebugging ((int) launchOptions, launchConfig, launchProps, projectProperties); } else { debugLaunchSettings = (DebugLaunchSettings) debugLauncher.StartWithDebugging ((int) launchOptions, launchConfig, launchProps, projectProperties); } } catch (Exception e) { LoggingUtils.HandleException (e); string description = string.Format ("[{0}] {1}", e.GetType (), e.Message); description += "\nStack trace:\n" + e.StackTrace; if (debugLauncher != null) { LoggingUtils.RequireOk (debugLauncher.GetConnectionService ().LaunchDialogUpdate (description, true)); } VsShellUtilities.ShowMessageBox (ServiceProvider, description, "Android++ Debugger", OLEMSGICON.OLEMSGICON_CRITICAL, OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST); } return new IDebugLaunchSettings [] { debugLaunchSettings }; }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public object StartWithoutDebugging(int launchOptions, LaunchConfiguration launchConfig, LaunchProps [] launchProps, IDictionary<string, string> projectProperties) { LoggingUtils.PrintFunction (); if (launchConfig == null) { throw new ArgumentNullException ("launchConfig"); } if (launchProps == null) { throw new ArgumentNullException ("launchProps"); } if (projectProperties == null) { throw new ArgumentNullException ("projectProperties"); } try { // // Refresh ADB service and evaluate a list of connected devices or emulators. // AndroidAdb.Refresh (); AndroidDevice debuggingDevice = GetPrioritisedConnectedDevice (); if (debuggingDevice == null) { throw new InvalidOperationException ("No device/emulator found or connected. Check status using \"adb devices\"."); } // // Construct VS launch settings to debug or attach to the specified target application. // launchOptions |= (int) DebugLaunchOptions.Silent; DebugLaunchSettings nonDebuglaunchSettings = new DebugLaunchSettings ((DebugLaunchOptions) launchOptions); nonDebuglaunchSettings.LaunchDebugEngineGuid = new Guid ("8310DAF9-1043-4C8E-85A0-FF68896E1922"); nonDebuglaunchSettings.PortSupplierGuid = new Guid ("3AEE417F-E5F9-4B89-BC31-20534C99B7F5"); nonDebuglaunchSettings.PortName = debuggingDevice.ID; nonDebuglaunchSettings.Options = launchConfig.ToString (); nonDebuglaunchSettings.Executable = launchConfig ["TargetApk"]; nonDebuglaunchSettings.LaunchOperation = DebugLaunchOperation.Custom; return nonDebuglaunchSettings; } catch (Exception e) { LoggingUtils.HandleException (e); throw; } }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public object StartWithDebugging(int launchOptions, LaunchConfiguration launchConfig, LaunchProps [] launchProps, IDictionary<string, string> projectProperties) { LoggingUtils.PrintFunction (); if (launchConfig == null) { throw new ArgumentNullException ("launchConfig"); } if (launchProps == null) { throw new ArgumentNullException ("launchProps"); } if (projectProperties == null) { throw new ArgumentNullException ("projectProperties"); } try { // // Refresh ADB service and evaluate a list of connected devices or emulators. // AndroidAdb.Refresh (); AndroidDevice debuggingDevice = GetPrioritisedConnectedDevice (); if (debuggingDevice == null) { throw new InvalidOperationException ("No device/emulator found or connected. Check status using \"adb devices\"."); } // // Enforce required device/emulator properties. // foreach (LaunchProps prop in launchProps) { debuggingDevice.Shell ("setprop", string.Format (CultureInfo.InvariantCulture, "{0} {1}", prop.Item1, prop.Item2)); } // // Construct VS launch settings to debug or attach to the specified target application. // bool shouldAttach = false; #if false AndroidProcess [] debuggingDeviceProcesses = debuggingDevice.GetProcesses (); foreach (AndroidProcess process in debuggingDeviceProcesses) { if (process.Name.Equals (applicationPackageName)) { shouldAttach = true; break; } } #endif launchOptions |= (int) DebugLaunchOptions.Silent; DebugLaunchSettings debugLaunchSettings = new DebugLaunchSettings ((DebugLaunchOptions) launchOptions); debugLaunchSettings.LaunchDebugEngineGuid = new Guid ("8310DAF9-1043-4C8E-85A0-FF68896E1922"); debugLaunchSettings.PortSupplierGuid = new Guid ("3AEE417F-E5F9-4B89-BC31-20534C99B7F5"); debugLaunchSettings.PortName = debuggingDevice.ID; debugLaunchSettings.Options = launchConfig.ToString (); if (shouldAttach) { debugLaunchSettings.Executable = launchConfig ["PackageName"]; debugLaunchSettings.LaunchOperation = DebugLaunchOperation.AlreadyRunning; } else { // // Determine whether the application is currently installed, and if it is; // check last modified date to ensure we don't re-installed unchanged binaries. // bool upToDateCheck = launchConfig ["UpToDateCheck"].Equals ("true"); bool appIsInstalled = false; bool appIsOutOfDate = true; if (upToDateCheck) { FileInfo targetApkFileInfo = new FileInfo (launchConfig ["TargetApk"]); try { string [] adbPmPathOutput = debuggingDevice.Shell ("pm", "path " + launchConfig ["PackageName"]).Replace ("\r", "").Split (new char [] { '\n' }, StringSplitOptions.RemoveEmptyEntries); foreach (string line in adbPmPathOutput) { if (line.StartsWith ("package:", StringComparison.OrdinalIgnoreCase)) { appIsInstalled = true; LoggingUtils.RequireOk (m_debugConnectionService.LaunchDialogUpdate (string.Format (CultureInfo.InvariantCulture, "'{0}' already installed on target '{1}'.", launchConfig ["PackageName"], debuggingDevice.ID), false)); string path = line.Substring ("package:".Length); // // Get the target device/emulator's UTC current time. // // This is done by specifying the '-u' argument to 'date'. Despite this though, // the returned string will always claim to be in GMT: // // i.e: "Fri Jan 9 14:35:23 GMT 2015" // DateTime debuggingDeviceUtcTime; try { string [] deviceDateOutput = debuggingDevice.Shell ("date", "-u").Replace ("\r", "").Split (new char [] { '\n' }, StringSplitOptions.RemoveEmptyEntries); string debuggingDeviceUtcTimestamp = deviceDateOutput [0]; string [] debuggingDeviceUtcTimestampComponents = debuggingDeviceUtcTimestamp.Split (new char [] { ' ' }, StringSplitOptions.RemoveEmptyEntries); debuggingDeviceUtcTimestampComponents [4] = "-00:00"; if (!DateTime.TryParseExact (string.Join (" ", debuggingDeviceUtcTimestampComponents), "ddd MMM d HH:mm:ss zzz yyyy", CultureInfo.InvariantCulture, DateTimeStyles.AllowWhiteSpaces, out debuggingDeviceUtcTime)) { break; } debuggingDeviceUtcTime = debuggingDeviceUtcTime.ToUniversalTime (); } catch (Exception e) { throw new InvalidOperationException ("Failed to evaluate device local time.", e); } // // Convert current device/emulator time to UTC, and probe the working machine's time too. // DateTime thisMachineUtcTime = DateTime.UtcNow; TimeSpan thisMachineUtcVersusDeviceUtc = debuggingDeviceUtcTime - thisMachineUtcTime; LoggingUtils.RequireOk (m_debugConnectionService.LaunchDialogUpdate (string.Format (CultureInfo.InvariantCulture, "Current UTC time on '{0}': {1}", debuggingDevice.ID, debuggingDeviceUtcTime.ToString ()), false)); LoggingUtils.RequireOk (m_debugConnectionService.LaunchDialogUpdate (string.Format (CultureInfo.InvariantCulture, "Current UTC time on '{0}': {1}", System.Environment.MachineName, thisMachineUtcTime.ToString ()), false)); LoggingUtils.RequireOk (m_debugConnectionService.LaunchDialogUpdate (string.Format (CultureInfo.InvariantCulture, "Difference in UTC time between '{0}' and '{1}': {2}", System.Environment.MachineName, debuggingDevice.ID, thisMachineUtcVersusDeviceUtc.ToString ()), false)); // // Check the last modified date; ls output currently uses this format: // // -rw-r--r-- system system 11533274 2015-01-09 13:47 com.example.native_activity-2.apk // DateTime lastModifiedTimestampDeviceLocalTime; try { string [] extendedLsOutput = debuggingDevice.Shell ("ls -l", path).Replace ("\r", "").Split (new char [] { '\n' }, StringSplitOptions.RemoveEmptyEntries); string [] extendedLsOutputComponents = extendedLsOutput [0].Split (new char [] { ' ' }, StringSplitOptions.RemoveEmptyEntries); string date = extendedLsOutputComponents [4]; string time = extendedLsOutputComponents [5]; if (!DateTime.TryParseExact (date + " " + time, "yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture, DateTimeStyles.AllowWhiteSpaces, out lastModifiedTimestampDeviceLocalTime)) { break; } } catch (Exception e) { throw new InvalidOperationException (string.Format (CultureInfo.InvariantCulture, "Failed to evaluate device local modified time of: {0}", path), e); } // // Calculate how long ago the APK was changed, according to the device's local time. // TimeSpan timeSinceLastModification = debuggingDeviceUtcTime - lastModifiedTimestampDeviceLocalTime; DateTime debuggingDeviceUtcTimeAtLastModification = debuggingDeviceUtcTime - timeSinceLastModification; DateTime thisMachineUtcTimeAtLastModification = thisMachineUtcTime - timeSinceLastModification; LoggingUtils.RequireOk (m_debugConnectionService.LaunchDialogUpdate (string.Format (CultureInfo.InvariantCulture, "'{0}' was last modified on '{1}' at: {2}.", launchConfig ["PackageName"], debuggingDevice.ID, debuggingDeviceUtcTimeAtLastModification.ToString ()), false)); LoggingUtils.RequireOk (m_debugConnectionService.LaunchDialogUpdate (string.Format (CultureInfo.InvariantCulture, "{0} (on {1}) was around {2} (on {3}).", debuggingDeviceUtcTimeAtLastModification.ToString (), debuggingDevice.ID, thisMachineUtcTimeAtLastModification.ToString (), System.Environment.MachineName), false)); LoggingUtils.RequireOk (m_debugConnectionService.LaunchDialogUpdate (string.Format (CultureInfo.InvariantCulture, "'{0}' was last modified on '{1}' at: {2}.", Path.GetFileName (targetApkFileInfo.FullName), System.Environment.MachineName, targetApkFileInfo.LastWriteTime.ToString ()), false)); if ((targetApkFileInfo.LastWriteTime + thisMachineUtcVersusDeviceUtc) > thisMachineUtcTimeAtLastModification) { LoggingUtils.RequireOk (m_debugConnectionService.LaunchDialogUpdate (string.Format (CultureInfo.InvariantCulture, "'{0}' was determined to be out-of-date. Reinstalling...", launchConfig ["PackageName"]), false)); } else { appIsOutOfDate = false; } break; } } } catch (Exception) { appIsInstalled = false; } } else { LoggingUtils.RequireOk (m_debugConnectionService.LaunchDialogUpdate ("Skipping up-to-date check.", false)); } if (!appIsInstalled || appIsOutOfDate) { LoggingUtils.RequireOk (m_debugConnectionService.LaunchDialogUpdate (string.Format (CultureInfo.InvariantCulture, "Installing '{0}' to '{1}'...", launchConfig ["PackageName"], debuggingDevice.ID), false)); InstallApplicationAsync (debuggingDevice, launchConfig); LoggingUtils.RequireOk (m_debugConnectionService.LaunchDialogUpdate (string.Format (CultureInfo.InvariantCulture, "'{0}' installed successfully.", launchConfig ["PackageName"]), false)); } else { LoggingUtils.RequireOk (m_debugConnectionService.LaunchDialogUpdate (string.Format (CultureInfo.InvariantCulture, "'{0}' on '{1}' is up-to-date. Skipping installation...", launchConfig ["PackageName"], debuggingDevice.ID), false)); } debugLaunchSettings.Executable = launchConfig ["TargetApk"]; debugLaunchSettings.LaunchOperation = DebugLaunchOperation.Custom; } return debugLaunchSettings; } catch (Exception e) { LoggingUtils.HandleException (e); throw; } }
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 (resolvedProfile.SqlDebuggingIsEnabled()) { settings.AdditionalDebugEngines.Add(DebuggerEngines.SqlEngine); } 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); settings.LaunchOptions = launchOptions | DebugLaunchOptions.StopDebuggingOnEnd; if (settings.Environment.Count > 0) { settings.LaunchOptions = settings.LaunchOptions | DebugLaunchOptions.MergeEnvironment; } 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> /// <returns><see langword="null"/> if the runnable project information is <see langword="null"/>. Otherwise, the debug launch settings.</returns> private async Task <DebugLaunchSettings?> GetConsoleTargetForProfile(ILaunchProfile resolvedProfile, DebugLaunchOptions launchOptions, bool validateSettings) { var settings = new DebugLaunchSettings(launchOptions); string?executable, arguments; string projectFolder = Path.GetDirectoryName(_project.UnconfiguredProject.FullPath) ?? string.Empty; ConfiguredProject?configuredProject = await GetConfiguredProjectForDebugAsync(); Assumes.NotNull(configuredProject); // 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 (string Command, string Arguments, string WorkingDirectory)? runnableProjectInfo = await GetRunnableProjectInformationAsync(configuredProject, validateSettings); if (runnableProjectInfo == null) { return(null); } string workingDirectory; (executable, arguments, workingDirectory) = runnableProjectInfo.Value; if (!string.IsNullOrWhiteSpace(workingDirectory)) { defaultWorkingDir = workingDirectory; } if (!string.IsNullOrWhiteSpace(resolvedProfile.CommandLineArgs)) { arguments = arguments + " " + resolvedProfile.CommandLineArgs; } } else { executable = resolvedProfile.ExecutablePath; arguments = resolvedProfile.CommandLineArgs; } string workingDir; if (Strings.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 (!Strings.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", StringComparisons.Paths) ? executable : executable + ".exe"; string fullPath = _fileSystem.GetFullPath(exeName); if (_fileSystem.FileExists(fullPath)) { executable = fullPath; } else { string?fullPathFromEnv = GetFullPathOfExeFromEnvironmentPath(exeName); if (fullPathFromEnv != null) { executable = fullPathFromEnv; } } } } } if (validateSettings) { ValidateSettings(executable, workingDir, resolvedProfile.Name); } // Apply environment variables. if (resolvedProfile.EnvironmentVariables?.IsEmpty == false) { foreach ((string key, string value) in resolvedProfile.EnvironmentVariables) { settings.Environment[key] = value; } } settings.LaunchOperation = DebugLaunchOperation.CreateProcess; settings.LaunchDebugEngineGuid = await GetDebuggingEngineAsync(configuredProject); if (resolvedProfile.IsNativeDebuggingEnabled()) { settings.AdditionalDebugEngines.Add(DebuggerEngines.NativeOnlyEngine); } if (resolvedProfile.IsSqlDebuggingEnabled()) { settings.AdditionalDebugEngines.Add(DebuggerEngines.SqlEngine); } 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; settings.Project = _unconfiguredProjectVsServices.VsHierarchy; if (resolvedProfile.IsRemoteDebugEnabled()) { settings.RemoteMachine = resolvedProfile.RemoteDebugMachine(); string?remoteAuthenticationMode = resolvedProfile.RemoteAuthenticationMode(); if (!Strings.IsNullOrEmpty(remoteAuthenticationMode)) { IRemoteAuthenticationProvider?remoteAuthenticationProvider = _remoteDebuggerAuthenticationService.FindProviderForAuthenticationMode(remoteAuthenticationMode); if (remoteAuthenticationProvider != null) { settings.PortSupplierGuid = remoteAuthenticationProvider.PortSupplierGuid; } } } // WebView2 debugging is only supported for Project and Executable commands if (resolvedProfile.IsJSWebView2DebuggingEnabled() && (IsRunExecutableCommand(resolvedProfile) || IsRunProjectCommand(resolvedProfile))) { // If JS Debugger is selected, we would need to change the launch debugger to that one settings.LaunchDebugEngineGuid = DebuggerEngines.JavaScriptForWebView2Engine; // Create the launch params needed for the JS debugger var debuggerLaunchOptions = new JObject( new JProperty("type", "pwa-msedge"), new JProperty("runtimeExecutable", finalExecutable), new JProperty("webRoot", workingDir), // We use the Working Directory debugging option as the WebRoot, to map the urls to files on disk new JProperty("useWebView", true), new JProperty("runtimeArgs", finalArguments) ); settings.Options = JsonConvert.SerializeObject(debuggerLaunchOptions); } return(settings); }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public object StartWithDebugging(int launchOptionsFlags, LaunchConfiguration launchConfig, LaunchProps [] launchProps, IDictionary <string, string> projectProperties) { LoggingUtils.PrintFunction(); try { // // Refresh ADB service and evaluate a list of connected devices or emulators. // AndroidAdb.Refresh(); AndroidDevice debuggingDevice = GetPriortisedConnectedDevice(); if (debuggingDevice == null) { throw new InvalidOperationException("No device/emulator found or connected. Check status via 'adb devices'."); } // // Enforce required device/emulator properties. // foreach (LaunchProps prop in launchProps) { debuggingDevice.Shell("setprop", string.Format("{0} {1}", prop.Item1, prop.Item2)); } // // Construct VS launch settings to debug or attach to the specified target application. // bool shouldAttach = false; #if false AndroidProcess [] debuggingDeviceProcesses = debuggingDevice.GetProcesses(); foreach (AndroidProcess process in debuggingDeviceProcesses) { if (process.Name.Equals(applicationPackageName)) { shouldAttach = true; break; } } #endif launchOptionsFlags |= (int)DebugLaunchOptions.Silent; DebugLaunchSettings debugLaunchSettings = new DebugLaunchSettings((DebugLaunchOptions)launchOptionsFlags); debugLaunchSettings.LaunchDebugEngineGuid = new Guid("8310DAF9-1043-4C8E-85A0-FF68896E1922"); debugLaunchSettings.PortSupplierGuid = new Guid("3AEE417F-E5F9-4B89-BC31-20534C99B7F5"); debugLaunchSettings.PortName = debuggingDevice.ID; debugLaunchSettings.Options = launchConfig.ToString(); if (shouldAttach) { debugLaunchSettings.Executable = launchConfig ["PackageName"]; debugLaunchSettings.LaunchOperation = DebugLaunchOperation.AlreadyRunning; } else { // // Determine whether the application is currently installed, and if it is; // check last modified date to ensure we don't re-installed unchanged binaries. // bool upToDateCheck = launchConfig ["UpToDateCheck"].Equals("true"); bool appIsInstalled = false; bool appIsOutOfDate = true; if (upToDateCheck) { FileInfo targetApkFileInfo = new FileInfo(launchConfig ["TargetApk"]); string [] adbPmPathOutput = debuggingDevice.Shell("pm", "path " + launchConfig ["PackageName"]).Replace("\r", "").Split(new char [] { '\n' }, StringSplitOptions.RemoveEmptyEntries); foreach (string line in adbPmPathOutput) { if (line.StartsWith("package:")) { appIsInstalled = true; LoggingUtils.RequireOk(m_debugConnectionService.LaunchDialogUpdate(string.Format("'{0}' already installed on target '{1}'.", launchConfig ["PackageName"], debuggingDevice.ID), false)); string path = line.Substring("package:".Length); // // Get the target device/emulator's UTC current time. // // This is done by specifying the '-u' argument to 'date'. Despite this though, // the returned string will always claim to be in GMT: // // i.e: "Fri Jan 9 14:35:23 GMT 2015" // DateTime debuggingDeviceUtcTime; try { string [] deviceDateOutput = debuggingDevice.Shell("date", "-u").Replace("\r", "").Split(new char [] { '\n' }, StringSplitOptions.RemoveEmptyEntries); string debuggingDeviceUtcTimestamp = deviceDateOutput [0]; string [] debuggingDeviceUtcTimestampComponents = debuggingDeviceUtcTimestamp.Split(new char [] { ' ' }, StringSplitOptions.RemoveEmptyEntries); debuggingDeviceUtcTimestampComponents [4] = "-00:00"; if (!DateTime.TryParseExact(string.Join(" ", debuggingDeviceUtcTimestampComponents), "ddd MMM d HH:mm:ss zzz yyyy", CultureInfo.InvariantCulture, DateTimeStyles.AllowWhiteSpaces, out debuggingDeviceUtcTime)) { break; } debuggingDeviceUtcTime = debuggingDeviceUtcTime.ToUniversalTime(); } catch (Exception e) { throw new InvalidOperationException("Failed to evaluate device local time.", e); } // // Convert current device/emulator time to UTC, and probe the working machine's time too. // DateTime thisMachineUtcTime = DateTime.UtcNow; TimeSpan thisMachineUtcVersusDeviceUtc = debuggingDeviceUtcTime - thisMachineUtcTime; LoggingUtils.RequireOk(m_debugConnectionService.LaunchDialogUpdate(string.Format("Current UTC time on '{0}': {1}", debuggingDevice.ID, debuggingDeviceUtcTime.ToString()), false)); LoggingUtils.RequireOk(m_debugConnectionService.LaunchDialogUpdate(string.Format("Current UTC time on '{0}': {1}", System.Environment.MachineName, thisMachineUtcTime.ToString()), false)); LoggingUtils.RequireOk(m_debugConnectionService.LaunchDialogUpdate(string.Format("Difference in UTC time between '{0}' and '{1}': {2}", System.Environment.MachineName, debuggingDevice.ID, thisMachineUtcVersusDeviceUtc.ToString()), false)); // // Check the last modified date; ls output currently uses this format: // // -rw-r--r-- system system 11533274 2015-01-09 13:47 com.example.native_activity-2.apk // DateTime lastModifiedTimestampDeviceLocalTime; try { string [] extendedLsOutput = debuggingDevice.Shell("ls -l", path).Replace("\r", "").Split(new char [] { '\n' }, StringSplitOptions.RemoveEmptyEntries); string [] extendedLsOutputComponents = extendedLsOutput [0].Split(new char [] { ' ' }, StringSplitOptions.RemoveEmptyEntries); string date = extendedLsOutputComponents [4]; string time = extendedLsOutputComponents [5]; if (!DateTime.TryParseExact(date + " " + time, "yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture, DateTimeStyles.AllowWhiteSpaces, out lastModifiedTimestampDeviceLocalTime)) { break; } } catch (Exception e) { throw new InvalidOperationException(string.Format("Failed to evaluate device local modified time of: {0}", path), e); } // // Calculate how long ago the APK was changed, according to the device's local time. // TimeSpan timeSinceLastModification = debuggingDeviceUtcTime - lastModifiedTimestampDeviceLocalTime; DateTime debuggingDeviceUtcTimeAtLastModification = debuggingDeviceUtcTime - timeSinceLastModification; DateTime thisMachineUtcTimeAtLastModification = thisMachineUtcTime - timeSinceLastModification; LoggingUtils.RequireOk(m_debugConnectionService.LaunchDialogUpdate(string.Format("'{0}' was last modified on '{1}' at: {2}.", launchConfig ["PackageName"], debuggingDevice.ID, debuggingDeviceUtcTimeAtLastModification.ToString()), false)); LoggingUtils.RequireOk(m_debugConnectionService.LaunchDialogUpdate(string.Format("{0} (on {1}) was around {2} (on {3}).", debuggingDeviceUtcTimeAtLastModification.ToString(), debuggingDevice.ID, thisMachineUtcTimeAtLastModification.ToString(), System.Environment.MachineName), false)); LoggingUtils.RequireOk(m_debugConnectionService.LaunchDialogUpdate(string.Format("'{0}' was last modified on '{1}' at: {2}.", Path.GetFileName(targetApkFileInfo.FullName), System.Environment.MachineName, targetApkFileInfo.LastWriteTime.ToString()), false)); if ((targetApkFileInfo.LastWriteTime + thisMachineUtcVersusDeviceUtc) > thisMachineUtcTimeAtLastModification) { LoggingUtils.RequireOk(m_debugConnectionService.LaunchDialogUpdate(string.Format("'{0}' was determined to be out-of-date. Reinstalling...", launchConfig ["PackageName"]), false)); } else { appIsOutOfDate = false; } break; } } } else { LoggingUtils.RequireOk(m_debugConnectionService.LaunchDialogUpdate("Skipping up-to-date check.", false)); } if (!appIsInstalled || appIsOutOfDate) { LoggingUtils.RequireOk(m_debugConnectionService.LaunchDialogUpdate(string.Format("Installing '{0}' to '{1}'...", launchConfig ["PackageName"], debuggingDevice.ID), false)); InstallApplicationAsync(debuggingDevice, launchConfig); LoggingUtils.RequireOk(m_debugConnectionService.LaunchDialogUpdate(string.Format("'{0}' installed successfully.", launchConfig ["PackageName"]), false)); } else { LoggingUtils.RequireOk(m_debugConnectionService.LaunchDialogUpdate(string.Format("'{0}' on '{1}' is up-to-date. Skipping installation...", launchConfig ["PackageName"], debuggingDevice.ID), false)); } debugLaunchSettings.Executable = launchConfig ["TargetApk"]; debugLaunchSettings.LaunchOperation = DebugLaunchOperation.Custom; } return(debugLaunchSettings); } catch (Exception e) { LoggingUtils.HandleException(e); throw; } }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public object StartWithoutDebugging(int launchOptions, LaunchConfiguration launchConfig, LaunchProps [] launchProps, IDictionary <string, string> projectProperties) { LoggingUtils.PrintFunction(); if (launchConfig == null) { throw new ArgumentNullException("launchConfig"); } if (launchProps == null) { throw new ArgumentNullException("launchProps"); } if (projectProperties == null) { throw new ArgumentNullException("projectProperties"); } try { // // Refresh ADB service and evaluate a list of connected devices or emulators. // AndroidAdb.Refresh(); AndroidDevice debuggingDevice = GetPrioritisedConnectedDevice(); if (debuggingDevice == null) { throw new InvalidOperationException("No device/emulator found or connected. Check status using \"adb devices\"."); } // // Construct VS launch settings to debug or attach to the specified target application. // launchOptions |= (int)DebugLaunchOptions.Silent; DebugLaunchSettings nonDebuglaunchSettings = new DebugLaunchSettings((DebugLaunchOptions)launchOptions); nonDebuglaunchSettings.LaunchDebugEngineGuid = new Guid("8310DAF9-1043-4C8E-85A0-FF68896E1922"); nonDebuglaunchSettings.PortSupplierGuid = new Guid("3AEE417F-E5F9-4B89-BC31-20534C99B7F5"); nonDebuglaunchSettings.PortName = debuggingDevice.ID; nonDebuglaunchSettings.Options = launchConfig.ToString(); nonDebuglaunchSettings.Executable = launchConfig ["TargetApk"]; nonDebuglaunchSettings.LaunchOperation = DebugLaunchOperation.Custom; return(nonDebuglaunchSettings); } catch (Exception e) { LoggingUtils.HandleException(e); throw; } }
public async Task <IReadOnlyList <IDebugLaunchSettings> > QueryDebugTargetsAsync( IAsyncProject project, DebugLaunchOptions launchOptions) { try { // Make sure we can find the target executable. var targetPath = await project.GetTargetPathAsync(); if (!_fileSystem.File.Exists(targetPath)) { Trace.WriteLine($"Unable to find target executable: {targetPath}"); _dialogUtil.ShowError(ErrorStrings.UnableToFindTargetExecutable(targetPath)); return(new IDebugLaunchSettings[] { }); } _metrics.UseNewDebugSessionId(); var actionRecorder = new ActionRecorder(_metrics); var targetFileName = await project.GetTargetFileNameAsync(); var gameletCommand = (targetFileName + " " + await project.GetGameletLaunchArgumentsAsync()).Trim(); var launchParams = new LaunchParams() { Cmd = gameletCommand, RenderDoc = await project.GetLaunchRenderDocAsync(), Rgp = await project.GetLaunchRgpAsync(), SurfaceEnforcementMode = await project.GetSurfaceEnforcementAsync(), VulkanDriverVariant = await project.GetVulkanDriverVariantAsync(), QueryParams = await project.GetQueryParamsAsync(), Endpoint = await project.GetEndpointAsync() }; if (_sdkVersion != null && !string.IsNullOrEmpty(_sdkVersion.ToString())) { launchParams.SdkVersion = _sdkVersion.ToString(); } if (!TrySetupQueries(project, actionRecorder, out SetupQueriesResult setupQueriesResult)) { return(new IDebugLaunchSettings[] { }); } launchParams.ApplicationName = setupQueriesResult.Application.Name; launchParams.ApplicationId = setupQueriesResult.Application.Id; if (setupQueriesResult.TestAccount != null) { launchParams.TestAccount = setupQueriesResult.TestAccount.Name; launchParams.TestAccountGamerName = setupQueriesResult.TestAccount.GamerStadiaName; } DeployOnLaunchSetting deployOnLaunchAsync = await project.GetDeployOnLaunchAsync(); launchParams.Account = _credentialManager.LoadAccount(); // TODO: Enable PlayerEndpoint Launches for non-internal usage in VS. if (launchParams.Endpoint == StadiaEndpoint.PlayerEndpoint && launchParams.Account != null && !launchParams.Account.EndsWith("@sparklingsunset.com") && !launchParams.Account.EndsWith("@subtlesunset.com")) { throw new NotImplementedException( "Player Endpoints are not yet supported, please select " + "Test Client in the Project Properties instead."); } // TODO: Enable launch on any endpoint for external accounts. if (launchParams.Endpoint == StadiaEndpoint.AnyEndpoint && launchParams.Account != null && !launchParams.Account.EndsWith("@sparklingsunset.com") && !launchParams.Account.EndsWith("@subtlesunset.com")) { throw new NotImplementedException( "Launch on any player endpoint is not supported yet, please select " + "another endpoint in the Project Properties instead."); } bool launchGameApiEnabled = _yetiVsiService.Options.LaunchGameApiFlow == LaunchGameApiFlow.ENABLED; IGameletSelector gameletSelector = _gameletSelectorFactory.Create(launchGameApiEnabled, actionRecorder); if (!gameletSelector.TrySelectAndPrepareGamelet( targetPath, deployOnLaunchAsync, setupQueriesResult.Gamelets, setupQueriesResult.TestAccount, launchParams.Account, out Gamelet gamelet)) { return(new IDebugLaunchSettings[] { }); } launchParams.GameletName = gamelet.Name; launchParams.PoolId = gamelet.PoolId; launchParams.GameletSdkVersion = gamelet.GameletVersions.DevToolingVersion; launchParams.GameletEnvironmentVars = await project.GetGameletEnvironmentVariablesAsync(); // Prepare for debug launch using these settings. var debugLaunchSettings = new DebugLaunchSettings(launchOptions); debugLaunchSettings.Environment["PATH"] = await project.GetExecutablePathAsync(); debugLaunchSettings.LaunchOperation = DebugLaunchOperation.CreateProcess; debugLaunchSettings.CurrentDirectory = await project.GetAbsoluteRootPathAsync(); if (!launchOptions.HasFlag(DebugLaunchOptions.NoDebug)) { var parameters = _paramsFactory.Create(); parameters.TargetIp = new SshTarget(gamelet).GetString(); parameters.DebugSessionId = _metrics.DebugSessionId; debugLaunchSettings.Options = _paramsFactory.Serialize(parameters); } IAction action = actionRecorder.CreateToolAction(ActionType.RemoteDeploy); bool isDeployed = _cancelableTaskFactory.Create( TaskMessages.DeployingExecutable, async task => { await _remoteDeploy.DeployGameExecutableAsync( project, new SshTarget(gamelet), task, action); task.Progress.Report(TaskMessages.CustomDeployCommand); await _remoteDeploy.ExecuteCustomCommandAsync(project, gamelet, action); }).RunAndRecord(action); if (!isDeployed) { return(new IDebugLaunchSettings[] { }); } if (launchOptions.HasFlag(DebugLaunchOptions.NoDebug)) { if (_gameLauncher.LaunchGameApiEnabled || launchParams.Endpoint == StadiaEndpoint.PlayerEndpoint || launchParams.Endpoint == StadiaEndpoint.AnyEndpoint) { IVsiGameLaunch launch = _gameLauncher.CreateLaunch(launchParams); if (launch != null) { debugLaunchSettings.Arguments = _launchCommandFormatter.CreateWithLaunchName( launchParams, launch.LaunchName); } else { Trace.WriteLine("Unable to retrieve launch name from the launch api."); return(new IDebugLaunchSettings[] { }); } } else { debugLaunchSettings.Arguments = _launchCommandFormatter.CreateFromParams(launchParams); } debugLaunchSettings.Executable = Path.Combine(Environment.SystemDirectory, YetiConstants.Command); debugLaunchSettings.LaunchOptions = DebugLaunchOptions.NoDebug | DebugLaunchOptions.MergeEnvironment; } else { if (_yetiVsiService.DebuggerOptions[DebuggerOption.SKIP_WAIT_LAUNCH] == DebuggerOptionState.DISABLED) { launchParams.Debug = true; } // TODO: This should really be the game_client executable, since // the args we pass are for game_client as well. We just need to find another // way to pass the game executable. debugLaunchSettings.Executable = targetPath; debugLaunchSettings.LaunchDebugEngineGuid = YetiConstants.DebugEngineGuid; debugLaunchSettings.Arguments = _launchCommandFormatter.EncodeLaunchParams(launchParams); debugLaunchSettings.LaunchOptions = DebugLaunchOptions.MergeEnvironment; } return(new IDebugLaunchSettings[] { debugLaunchSettings }); } catch (Exception e) { Trace.WriteLine(e.ToString()); _dialogUtil.ShowError(e.Message, e.ToString()); return(new IDebugLaunchSettings[] { }); } }
public override async Task <IReadOnlyList <IDebugLaunchSettings> > QueryDebugTargetsAsync(DebugLaunchOptions launchOptions) { var settings = new DebugLaunchSettings(launchOptions); // The properties that are available via DebuggerProperties are determined by the property XAML files in your project. var debuggerProperties = await this.DebuggerProperties.GetLlilumDebuggerPropertiesAsync(); string dir = await debuggerProperties.LlilumDebuggerWorkingDirectory.GetEvaluatedValueAtEndAsync(); string executable = await debuggerProperties.LlilumDebuggerCommand.GetEvaluatedValueAtEndAsync(); string gdbPath = await debuggerProperties.LlilumGdbPath.GetEvaluatedValueAtEndAsync(); string gdbArgs = await debuggerProperties.LlilumGdbArgs.GetEvaluatedValueAtEndAsync(); var gdbServer = await debuggerProperties.LlilumGdbServerOption.GetEvaluatedValueAtEndAsync(); settings.CurrentDirectory = dir; settings.Executable = executable; // If we are going to deploy with GDB load command, create a script that will also load the elf file string debugScript = DebuggerScriptContentFormat; var deployTool = await debuggerProperties.LlilumDeployTool.GetEvaluatedValueAtEndAsync(); if (string.Compare(deployTool, "gdbloadcommand", true) == 0) { debugScript = DebuggerLoadScriptContentFormat; } // Create the temporary file for passing to the debug engine string debuggerFile = CreateDebuggerFileIfNoneExist(dir, executable, gdbPath, gdbArgs, debugScript); settings.Options = string.Format(DebuggerOptionsFormat, debuggerFile); settings.LaunchOperation = DebugLaunchOperation.CreateProcess; settings.LaunchDebugEngineGuid = new Guid(Microsoft.MIDebugEngine.EngineConstants.EngineId); // Launch py_ocd to communicate with GDB string gdbServerPath = string.Empty; string gdbServerArgs = string.Empty; if (gdbServer.Equals("pyocd")) { gdbServerPath = await debuggerProperties.LlilumPyOcdPath.GetEvaluatedValueAtEndAsync(); gdbServerArgs = await debuggerProperties.LlilumPyOcdArgs.GetEvaluatedValueAtEndAsync(); } else if (gdbServer.Equals("openocd")) { gdbServerPath = await debuggerProperties.LlilumOpenOcdPath.GetEvaluatedValueAtEndAsync(); gdbServerArgs = await debuggerProperties.LlilumOpenOcdArgs.GetEvaluatedValueAtEndAsync(); } if (!string.IsNullOrWhiteSpace(gdbServerPath)) { // Even though we did it in deploy, do it here just in case we go straight to debug await LlilumHelpers.TryKillPyocdAsync(); await LlilumHelpers.TryKillOpenOcdAsync(); ProcessStartInfo start = new ProcessStartInfo(); start.FileName = gdbServerPath; start.Arguments = gdbServerArgs; start.UseShellExecute = false; start.RedirectStandardOutput = true; Process gdbServerProcess = Process.Start(start); } return(new IDebugLaunchSettings[] { settings }); }