ProcessStartData CreateTailLogsProcessStartData(SshTarget target, uint remotePid) { // If the game process exits, give the tail process a chance to shut down gracefully. ProcessManager.ProcessStopHandler stopHandler = (process, reason) => { // Did the game process, i.e. the process with pid |remotePid|, exit? if (reason != ExitReason.ProcessExited && reason != ExitReason.DebuggerTerminated) { Trace.WriteLine("Game process did not exit, won't wait for tail process exit"); return; } // Give it a second to finish. bool exited = process.WaitForExit(TimeSpan.FromSeconds(1)); // Emit a log message to help tracking down issues, just in case. Trace.WriteLine($"Tail process {(exited ? "exited" : "did not exit")} gracefully"); }; var startInfo = ProcessStartInfoBuilder.BuildForSsh( $"tail --pid={remotePid} -n +0 -F -q /var/game/stdout /var/game/stderr", new List <string>(), target); return(new ProcessStartData("output tail", startInfo, monitorExit: false, outputToConsole: true, stopHandler: stopHandler)); }
ProcessStartData CreateLldbServerProcessStartData(SshTarget target) { string lldbServerCommand = string.Format( "{0} platform --listen 127.0.0.1:{1} --min-gdbserver-port={2} " + "--max-gdbserver-port={3}", Path.Combine(YetiConstants.LldbServerLinuxPath, YetiConstants.LldbServerLinuxExecutable), transportSession.GetRemoteDebuggerPort(), transportSession.GetReservedLocalAndRemotePort(), transportSession.GetReservedLocalAndRemotePort() + 1); List <string> lldbServerEnvironment = new List <string>(); if (yetiVSIService.DebuggerOptions[DebuggerOption.SERVER_LOGGING] == DebuggerOptionState.ENABLED) { string channels = "lldb default:posix default:gdb-remote default"; // gdb-server.log lldbServerEnvironment.Add( "LLDB_DEBUGSERVER_LOG_FILE=/usr/local/cloudcast/log/gdb-server.log"); lldbServerEnvironment.Add("LLDB_SERVER_LOG_CHANNELS=\\\"" + channels + "\\\""); // lldb-server.log lldbServerCommand += " --log-file=/usr/local/cloudcast/log/lldb-server.log " + "--log-channels=\\\"" + channels + "\\\""; } var startInfo = ProcessStartInfoBuilder.BuildForSsh( lldbServerCommand, lldbServerEnvironment, target); return(new ProcessStartData("lldb server", startInfo)); }
public void CreateKey(IAbsoluteFilePath outFile, bool overwrite = false) { if (outFile == null) { throw new ArgumentNullException(nameof(outFile)); } var privateFile = outFile + ".biprivatekey"; var publicFile = outFile + ".bikey"; if (!overwrite) { if (File.Exists(privateFile)) { throw new IOException("File exists: " + privateFile); } if (File.Exists(publicFile)) { throw new IOException("File exists: " + publicFile); } } var parentPath = outFile.ParentDirectoryPath; if (!parentPath.Exists) { throw new InvalidOperationException("Does not exist: " + parentPath + " of: " + outFile); } var startInfo = new ProcessStartInfoBuilder(_dsCreateKeyBin, BuildPathParameters(outFile.FileName)) { WorkingDirectory = parentPath }.Build(); ProcessExitResult(_processManager.LaunchAndGrabTool(startInfo)); }
// Queries the provided port (gamelet) for a list of running cores. On an error, a // TransportException will be thrown with the error code. public async Task <List <CoreListEntry> > GetCoreListAsync(SshTarget sshTarget) { // TODO: Find a more robust method of listing files on the gamelet. ProcessStartInfo processStartInfo = ProcessStartInfoBuilder.BuildForSsh( COMMAND, new List <string>(), sshTarget); return(await GetCoreListFromProcessStartInfoAsync(processStartInfo)); }
public async Task <List <ProcessListEntry> > GetBySshAsync(SshTarget target) { using (var process = remoteProcessFactory.Create( ProcessStartInfoBuilder.BuildForSsh(COMMAND, new List <string>(), target))) { return(await GetByProcessAsync(process)); } }
public async Task GetAsync(SshTarget target, string file, string destination, ICancelable task) { await ScpAsync(ProcessStartInfoBuilder.BuildForScpGet(file, target, destination), ProcessManager.CreateForCancelableTask(task)); // Notify client if operation was cancelled. task.ThrowIfCancellationRequested(); }
public async Task RunWithSuccessAsync(SshTarget target, string command) { var startInfo = ProcessStartInfoBuilder.BuildForSsh(command, new List <string>(), target); using (var process = remoteProcessFactory.Create(startInfo)) { await process.RunToExitWithSuccessAsync(); } }
public void BuildForSsh() { var startInfo = ProcessStartInfoBuilder.BuildForSsh( "test_command arg1 arg2", new List <string>(), new SshTarget("1.2.3.4:56")); Assert.AreEqual(GetSshPath(), startInfo.FileName); Assert.True(startInfo.Arguments.Contains( "[email protected] -p 56 -- \"test_command arg1 arg2\"")); Assert.True(startInfo.Arguments.Contains( $"-oUserKnownHostsFile=\"\"\"{GetKnownHostsPath()}\"\"\"")); }
void CreateFiles(string outFile, bool overwrite = false, int bits = SshKeyPair.DefaultBits, string type = SshKeyPair.DefaultType) { if (!overwrite && File.Exists(outFile)) { throw new IOException("File exists " + outFile); } var startInfo = new ProcessStartInfoBuilder(sshKeyGenBin, GetParameters(outFile, bits, type)).Build(); _processManager.LaunchAndGrabTool(startInfo); }
public virtual ProcessExitResultWithOutput LaunchAndGrabToolCmd(ProcessStartInfo info, string tool) { var startInfo = new ProcessStartInfoBuilder(Common.Paths.CmdExe, $"/C \"\"{info.FileName}\" {info.Arguments}\"") { WorkingDirectory = info.WorkingDirectory.ToAbsoluteDirectoryPathNullSafe() }.Build(); return(LaunchAndGrabTool(startInfo, tool)); }
public void BuildForScpGet_PathEndsInBackslash() { var startInfo = ProcessStartInfoBuilder.BuildForScpGet( "path/to/file", new SshTarget("1.2.3.4:56"), "path\\to\\outDir\\"); Assert.AreEqual(GetScpPath(), startInfo.FileName); Assert.True(startInfo.Arguments.Contains("-T")); Assert.True(startInfo.Arguments.Contains("-P 56")); StringAssert.Contains("[email protected]:\"'path/to/file'\" \"path\\to\\outDir\\\\\"", startInfo.Arguments); Assert.True(startInfo.Arguments.Contains( $"-oUserKnownHostsFile=\"\"\"{GetKnownHostsPath()}\"\"\"")); }
public void RunExtractPboWithParameters(IAbsoluteFilePath input, IAbsoluteDirectoryPath output, params string[] parameters) { if (!input.Exists) { throw new IOException("File doesn't exist: " + input); } var startInfo = new ProcessStartInfoBuilder(_extractPboBin, BuildParameters(input.ToString(), output.ToString(), parameters)).Build(); ProcessExitResult(_processManager.LaunchAndGrabTool(startInfo)); }
public void BuildForSshEnv() { var startInfo = ProcessStartInfoBuilder.BuildForSsh( "test_command arg1 arg2", new List <string>() { "VAR1=X", "VAR2=Y" }, new SshTarget("1.2.3.4:56")); Assert.AreEqual(GetSshPath(), startInfo.FileName); Assert.True(startInfo.Arguments.Contains( "[email protected] -p 56 -- \"VAR1=X VAR2=Y test_command arg1 arg2\"")); }
ProcessStartData CreateRgpPortForwardingProcessStartData(SshTarget target) { var ports = new List <ProcessStartInfoBuilder.PortForwardEntry>() { new ProcessStartInfoBuilder.PortForwardEntry { LocalPort = WorkstationPorts.RGP_LOCAL, RemotePort = WorkstationPorts.RGP_REMOTE, } }; var startInfo = ProcessStartInfoBuilder.BuildForSshPortForward(ports, target); return(new ProcessStartData("rgp port forwarding", startInfo)); }
protected static async Task BuildAndRunBatFile(IProcessManager pm, IAbsoluteDirectoryPath tmpFolder, IEnumerable <string> commands, bool asAdministrator = false, bool noisy = false) { var batFile = tmpFolder.GetChildFileWithName("install.bat"); var actualCommands = new[] { "chcp 65001" }.Concat(commands) .Concat(new[] { "echo finished" }) .Select(x => x == "" ? x : x + " >> install.log"); var commandBat = string.Join("\r\n", new[] { "", "echo starting > install.log" }.Concat(actualCommands) .Concat(new[] { "" })); var encoding = Encoding.UTF8; File.WriteAllText(batFile.ToString(), commandBat, encoding); if (Common.Flags.Verbose || noisy) { MainLog.Logger.Info("install.bat content:\n" + commandBat); } try { var pInfo = new ProcessStartInfoBuilder(batFile) { WorkingDirectory = tmpFolder //WindowStyle = ProcessWindowStyle.Minimized }.Build(); pInfo.CreateNoWindow = true; var basicLaunchInfo = new BasicLaunchInfo(pInfo) { StartMinimized = true }; var r = await(asAdministrator ? pm.LaunchElevatedAsync(basicLaunchInfo) : pm.LaunchAsync(basicLaunchInfo)); r.ConfirmSuccess(); } catch (Win32Exception ex) { if (ex.IsElevationCancelled()) { throw ex.HandleUserCancelled(); } throw; } var logFile = tmpFolder.GetChildFileWithName("install.log"); var output = File.ReadAllText(logFile.ToString(), encoding); if (Common.Flags.Verbose || noisy) { MainLog.Logger.Info("install.bat output:\n" + output); } }
public virtual string Gzip(IAbsoluteFilePath file, IAbsoluteFilePath dest = null, bool preserveFileNameAndModificationTime = true, ITProgress status = null) { if (file == null) { throw new ArgumentNullException(nameof(file)); } if (!(file.Exists)) { throw new ArgumentException("file.Exists"); } var defDest = (file + ".gz").ToAbsoluteFilePath(); if (dest == null) { dest = defDest; } var cmd = $"-f --best --rsyncable --keep \"{file}\""; if (!preserveFileNameAndModificationTime) { cmd = "-n " + cmd; } dest.RemoveReadonlyWhenExists(); var startInfo = new ProcessStartInfoBuilder(Common.Paths.ToolPath.GetChildFileWithName("gzip.exe"), cmd) { WorkingDirectory = file.ParentDirectoryPath }.Build(); var srcSize = file.FileInfo.Length; ProcessExitResultWithOutput ret; var predictedSize = srcSize * DefaultPredictedCompressionRatio; using (StatusProcessor.Conditional(defDest, status, (long)predictedSize)) ret = ProcessManager.LaunchAndGrabTool(startInfo, "Gzip pack"); if (Path.GetFullPath(dest.ToString()) != Path.GetFullPath(defDest.ToString())) { FileUtil.Ops.MoveWithRetry(defDest, dest); } return(ret.StandardOutput + ret.StandardError); }
ProcessStartData CreatePortForwardingProcessStartData(SshTarget target) { var ports = new List <ProcessStartInfoBuilder.PortForwardEntry>() { new ProcessStartInfoBuilder.PortForwardEntry { LocalPort = transportSession.GetLocalDebuggerPort(), RemotePort = transportSession.GetRemoteDebuggerPort(), }, new ProcessStartInfoBuilder.PortForwardEntry { // LLDB returns the GDB server port to the LLDB client, so the local // and remote port must match. LocalPort = transportSession.GetReservedLocalAndRemotePort(), RemotePort = transportSession.GetReservedLocalAndRemotePort(), } }; var startInfo = ProcessStartInfoBuilder.BuildForSshPortForward(ports, target); return(new ProcessStartData("lldb port forwarding", startInfo)); }
public virtual string GzipStdOut(IAbsoluteFilePath inputFile, IAbsoluteFilePath outputFile = null, bool preserveFileNameAndModificationTime = true, ITProgress status = null) { if (!(inputFile != null)) { throw new ArgumentException("inputFile != null"); } if (!(inputFile.Exists)) { throw new ArgumentException("inputFile.Exists"); } if (outputFile == null) { outputFile = (inputFile + ".gz").ToAbsoluteFilePath(); } var cmd = $"-f --best --rsyncable --keep --stdout \"{inputFile}\" > \"{outputFile}\""; if (!preserveFileNameAndModificationTime) { cmd = "-n " + cmd; } outputFile.RemoveReadonlyWhenExists(); var startInfo = new ProcessStartInfoBuilder(Common.Paths.ToolPath.GetChildFileWithName("gzip.exe"), cmd) { WorkingDirectory = Common.Paths.LocalDataPath }.Build(); var srcSize = inputFile.FileInfo.Length; ProcessExitResultWithOutput ret; var predictedSize = srcSize * DefaultPredictedCompressionRatio; using (StatusProcessor.Conditional(outputFile, status, (long)predictedSize)) ret = ProcessManager.LaunchAndGrabToolCmd(startInfo, "Gzip pack"); return(ret.StandardOutput + ret.StandardError); }
public void Launch(IProcessManager processManager) { if (Path == null) { throw new ArgumentNullException(nameof(Path)); } if (!(!String.IsNullOrWhiteSpace(Path))) { throw new ArgumentException("!String.IsNullOrWhiteSpace(Path)"); } //if (!UserSettings.Current.AppOptions.UseElevatedService) { var startInfo = new ProcessStartInfoBuilder(Path, Parameters) { WorkingDirectory = Path.ToAbsoluteFilePath().ParentDirectoryPath, //AsAdministrator = RunAsAdmin }.Build(); MainLog.Logger.Info("Launching external app: " + startInfo.Format()); processManager.StartAndForget(startInfo); //} else { // _wcfClient.Value.Updater_StartAndForget(Path, Parameters, System.IO.Path.GetDirectoryName(Path), RunAsAdmin); //} }
public void BuildForSshPortForward() { var ports = new List <ProcessStartInfoBuilder.PortForwardEntry>() { new ProcessStartInfoBuilder.PortForwardEntry() { LocalPort = 123, RemotePort = 234, }, new ProcessStartInfoBuilder.PortForwardEntry() { LocalPort = 567, RemotePort = 678, }, }; var startInfo = ProcessStartInfoBuilder.BuildForSshPortForward(ports, new SshTarget("1.2.3.4:56")); Assert.AreEqual(GetSshPath(), startInfo.FileName); Assert.True(startInfo.Arguments.Contains("-L123:localhost:234 -L567:localhost:678")); Assert.True(startInfo.Arguments.Contains("[email protected] -p 56")); Assert.True(startInfo.Arguments.Contains( $"-oUserKnownHostsFile=\"\"\"{GetKnownHostsPath()}\"\"\"")); }
public void SignFile(IAbsoluteFilePath file, IAbsoluteFilePath privateFile) { if (file == null) { throw new ArgumentNullException(nameof(file)); } if (!file.Exists) { throw new IOException("File doesn't exist: " + file); } if (!privateFile.Exists) { throw new IOException("File doesn't exist: " + privateFile); } var startInfo = new ProcessStartInfoBuilder(_dsSignFileBin, BuildPathParameters(privateFile.ToString(), file.ToString())) { WorkingDirectory = Common.Paths.StartPath }.Build(); ProcessExitResult(_processManager.LaunchAndGrabTool(startInfo)); }
async Task InvokeSnapApps([NotNull] List <ProcessStartInfoBuilder> allSnapAwareApps, TimeSpan cancelInvokeProcessesAfterTs, bool isInitialInstall, [NotNull] SemanticVersion semanticVersion, ILog logger = null, CancellationToken cancellationToken = default) { if (allSnapAwareApps == null) { throw new ArgumentNullException(nameof(allSnapAwareApps)); } if (semanticVersion == null) { throw new ArgumentNullException(nameof(semanticVersion)); } logger?.Info( $"Invoking {allSnapAwareApps.Count} processes. " + $"Timeout in {cancelInvokeProcessesAfterTs.TotalSeconds:F0} seconds."); var firstRunApplicationFilenames = new List <string>(); var invocationTasks = allSnapAwareApps.ForEachAsync(async x => { using var cts = new CancellationTokenSource(); cts.CancelAfter(cancelInvokeProcessesAfterTs); try { logger?.Debug(x.ToString()); var(exitCode, stdout) = await _snapOs.ProcessManager .RunAsync(x, cancellationToken) // Two cancellation tokens is intentional because of unit tests mocks. .WithCancellation(cts.Token); // Two cancellation tokens is intentional because of unit tests mocks. logger?.Debug($"Processed exited: {exitCode}. Exe: {x.Filename}. Stdout: {stdout}."); } catch (Exception ex) { logger?.ErrorException($"Exception thrown while running application: {x.Filename}. Arguments: {x.Arguments}", ex); } if (!isInitialInstall) { return; } firstRunApplicationFilenames.Add(x.Filename); }, 1 /* at a time */); await Task.WhenAll(invocationTasks); if (!isInitialInstall) { return; } firstRunApplicationFilenames.ForEach(filename => { var builder = new ProcessStartInfoBuilder(filename) .Add($"--snapx-first-run {semanticVersion.ToNormalizedString()}"); try { _snapOs.ProcessManager .StartNonBlocking(builder); } catch (Exception ex) { logger?.ErrorException($"Exception thrown while running 'first-run' application: {builder.Filename}. Arguments: {builder.Arguments}", ex); } }); }
static async Task <(bool success, bool canContinueIfError, string installerExeAbsolutePath)> BuildInstallerAsync([NotNull] ILog logger, [NotNull] ISnapOs snapOs, [NotNull] ISnapxEmbeddedResources snapxEmbeddedResources, [NotNull] ISnapPack snapPack, [NotNull] ISnapAppReader snapAppReader, [NotNull] ISnapAppWriter snapAppWriter, [NotNull] SnapApp snapApp, ICoreRunLib coreRunLib, [NotNull] string installersWorkingDirectory, string fullNupkgAbsolutePath, [NotNull] string releasesNupkgAbsolutePath, bool offline, CancellationToken cancellationToken) { if (logger == null) { throw new ArgumentNullException(nameof(logger)); } if (snapOs == null) { throw new ArgumentNullException(nameof(snapOs)); } if (snapxEmbeddedResources == null) { throw new ArgumentNullException(nameof(snapxEmbeddedResources)); } if (snapPack == null) { throw new ArgumentNullException(nameof(snapPack)); } if (snapAppReader == null) { throw new ArgumentNullException(nameof(snapAppReader)); } if (snapAppWriter == null) { throw new ArgumentNullException(nameof(snapAppWriter)); } if (snapApp == null) { throw new ArgumentNullException(nameof(snapApp)); } if (installersWorkingDirectory == null) { throw new ArgumentNullException(nameof(installersWorkingDirectory)); } if (releasesNupkgAbsolutePath == null) { throw new ArgumentNullException(nameof(releasesNupkgAbsolutePath)); } var installerPrefix = offline ? "offline" : "web"; var snapChannel = snapApp.GetCurrentChannelOrThrow(); logger.Info($"Preparing to build {installerPrefix} installer for channel: {snapChannel.Name}. Version: {snapApp.Version}."); var progressSource = new SnapProgressSource { Progress = percentage => { logger.Info($"Progress: {percentage}%."); } }; using var rootTempDir = snapOs.Filesystem.WithDisposableTempDirectory(installersWorkingDirectory); MemoryStream installerZipMemoryStream; MemoryStream warpPackerMemoryStream; string snapAppTargetRid; string warpPackerRid; string warpPackerArch; string installerFilename; string setupExtension; string setupIcon = null; var chmod = false; var changeSubSystemToWindowsGui = false; var installerIconSupported = false; if (snapOs.OsPlatform == OSPlatform.Windows) { warpPackerMemoryStream = snapxEmbeddedResources.WarpPackerWindows; warpPackerRid = "win-x64"; installerIconSupported = true; } else if (snapOs.OsPlatform == OSPlatform.Linux) { warpPackerMemoryStream = snapxEmbeddedResources.WarpPackerLinux; warpPackerRid = "linux-x64"; chmod = true; } else { throw new PlatformNotSupportedException(); } switch (snapApp.Target.Rid) { case "win-x64": installerZipMemoryStream = snapxEmbeddedResources.SetupWindows; warpPackerArch = "windows-x64"; snapAppTargetRid = "win-x64"; installerFilename = "Snap.Installer.exe"; changeSubSystemToWindowsGui = true; setupExtension = ".exe"; if (installerIconSupported && snapApp.Target.Icon != null) { setupIcon = snapApp.Target.Icon; } break; case "linux-x64": installerZipMemoryStream = snapxEmbeddedResources.SetupLinux; warpPackerArch = "linux-x64"; snapAppTargetRid = "linux-x64"; installerFilename = "Snap.Installer"; setupExtension = ".bin"; break; default: throw new PlatformNotSupportedException($"Unsupported rid: {snapApp.Target.Rid}"); } var repackageTempDir = snapOs.Filesystem.PathCombine(rootTempDir.WorkingDirectory, "repackage"); snapOs.Filesystem.DirectoryCreateIfNotExists(repackageTempDir); var rootTempDirWarpPackerAbsolutePath = snapOs.Filesystem.PathCombine(rootTempDir.WorkingDirectory, $"warp-packer-{warpPackerRid}.exe"); var installerRepackageAbsolutePath = snapOs.Filesystem.PathCombine(repackageTempDir, installerFilename); async Task BuildOfflineInstallerAsync() { if (fullNupkgAbsolutePath == null) { throw new ArgumentNullException(nameof(fullNupkgAbsolutePath)); } var repackageDirSnapAppDllAbsolutePath = snapOs.Filesystem.PathCombine(repackageTempDir, SnapConstants.SnapAppDllFilename); var repackageDirFullNupkgAbsolutePath = snapOs.Filesystem.PathCombine(repackageTempDir, "Setup.nupkg"); var repackageDirReleasesNupkgAbsolutePath = snapOs.Filesystem.PathCombine(repackageTempDir, snapOs.Filesystem.PathGetFileName(releasesNupkgAbsolutePath)); await using (installerZipMemoryStream) await using (warpPackerMemoryStream) { using var snapAppAssemblyDefinition = snapAppWriter.BuildSnapAppAssembly(snapApp); await using var snapAppDllDstMemoryStream = snapOs.Filesystem.FileWrite(repackageDirSnapAppDllAbsolutePath); await using var warpPackerDstStream = snapOs.Filesystem.FileWrite(rootTempDirWarpPackerAbsolutePath); using var zipArchive = new ZipArchive(installerZipMemoryStream, ZipArchiveMode.Read); snapAppAssemblyDefinition.Write(snapAppDllDstMemoryStream); progressSource.Raise(10); logger.Info("Extracting installer to temp directory."); zipArchive.ExtractToDirectory(repackageTempDir); progressSource.Raise(20); logger.Info("Copying assets to temp directory."); await Task.WhenAll( warpPackerMemoryStream.CopyToAsync(warpPackerDstStream, cancellationToken), snapOs.Filesystem.FileCopyAsync(fullNupkgAbsolutePath, repackageDirFullNupkgAbsolutePath, cancellationToken), snapOs.Filesystem.FileCopyAsync(releasesNupkgAbsolutePath, repackageDirReleasesNupkgAbsolutePath, cancellationToken)); if (installerIconSupported && setupIcon != null) { logger.Debug($"Writing installer icon: {setupIcon}."); var zipArchiveInstallerFilename = snapOs.Filesystem.PathCombine(repackageTempDir, installerFilename); var rcEditOptions = new RcEditOptions { Filename = zipArchiveInstallerFilename, IconFilename = setupIcon }; CommandRcEdit(rcEditOptions, coreRunLib, snapOs.Filesystem, logger); } } } async Task BuildWebInstallerAsync() { var repackageDirSnapAppDllAbsolutePath = snapOs.Filesystem.PathCombine(repackageTempDir, SnapConstants.SnapAppDllFilename); await using (installerZipMemoryStream) await using (warpPackerMemoryStream) { await using var warpPackerDstStream = snapOs.Filesystem.FileWrite(rootTempDirWarpPackerAbsolutePath); using var zipArchive = new ZipArchive(installerZipMemoryStream, ZipArchiveMode.Read); using var snapAppAssemblyDefinition = snapAppWriter.BuildSnapAppAssembly(snapApp); await using var snapAppDllDstMemoryStream = snapOs.Filesystem.FileWrite(repackageDirSnapAppDllAbsolutePath); snapAppAssemblyDefinition.Write(snapAppDllDstMemoryStream); progressSource.Raise(10); logger.Info("Extracting installer to temp directory."); zipArchive.ExtractToDirectory(repackageTempDir); progressSource.Raise(20); logger.Info("Copying assets to temp directory."); await Task.WhenAll( warpPackerMemoryStream.CopyToAsync(warpPackerDstStream, cancellationToken)); if (installerIconSupported && setupIcon != null) { logger.Debug($"Writing installer icon: {setupIcon}."); var zipArchiveInstallerFilename = snapOs.Filesystem.PathCombine(repackageTempDir, installerFilename); var rcEditOptions = new RcEditOptions { Filename = zipArchiveInstallerFilename, IconFilename = setupIcon }; CommandRcEdit(rcEditOptions, coreRunLib, snapOs.Filesystem, logger); } } } var installerFinalAbsolutePath = snapOs.Filesystem.PathCombine(installersWorkingDirectory, $"Setup-{snapAppTargetRid}-{snapApp.Id}-{snapChannel.Name}-{installerPrefix}{setupExtension}"); if (offline) { await BuildOfflineInstallerAsync(); } else { await BuildWebInstallerAsync(); } progressSource.Raise(50); var processStartInfoBuilder = new ProcessStartInfoBuilder(rootTempDirWarpPackerAbsolutePath) .Add($"--arch {warpPackerArch}") .Add($"--exec {installerFilename}") .Add($"--output {installerFinalAbsolutePath.ForwardSlashesSafe()}") .Add($"--input_dir {repackageTempDir.ForwardSlashesSafe()}"); if (chmod) { await snapOs.ProcessManager.ChmodExecuteAsync(rootTempDirWarpPackerAbsolutePath, cancellationToken); await snapOs.ProcessManager.ChmodExecuteAsync(installerRepackageAbsolutePath, cancellationToken); } logger.Info("Packaging installer."); var(exitCode, stdout) = await snapOs.ProcessManager.RunAsync(processStartInfoBuilder, cancellationToken); if (exitCode != 0) { logger.Error( $"Warp packer exited with error code: {exitCode}. Warp packer executable path: {rootTempDirWarpPackerAbsolutePath}. Stdout: {stdout}."); return(false, false, null); } progressSource.Raise(80); if (changeSubSystemToWindowsGui) { // NB! Unable to set icon on warped executable. Please refer to the following issue: // https://github.com/electron/rcedit/issues/70 var rcEditOptions = new RcEditOptions { ConvertSubSystemToWindowsGui = true, Filename = installerFinalAbsolutePath, //IconFilename = setupIcon }; CommandRcEdit(rcEditOptions, coreRunLib, snapOs.Filesystem, logger); } if (chmod) { await snapOs.ProcessManager.ChmodExecuteAsync(installerFinalAbsolutePath, cancellationToken); } progressSource.Raise(100); return(true, false, installerFinalAbsolutePath); }
void RunMakePbo(string parameters) { var startInfo = new ProcessStartInfoBuilder(_makePboBin, parameters).Build(); ProcessExitResult(_processManager.LaunchAndGrabTool(startInfo)); }