public async Task InstallVersion(VirtualFile setup, VirtualDirectory tempDirectory, IProgressNotifier parentProgress = null) { VirtualDirectory destination = tempDirectory.Directory(Guid.NewGuid().ToByteString()); using (IProgressNotifier progressNotifier = parentProgress?.Spawn(installationSteps.Count() + 1, "Installing version")) { await fileUnpackService.Unpack(setup, destination, progressNotifier).ConfigureAwait(false); foreach (IInstallationStep installationStep in installationSteps) { await installationStep.Install(destination, progressNotifier).ConfigureAwait(false); } await ReplaceApplication().ConfigureAwait(false); } async Task ReplaceApplication() { userInterface.WriteInformation("Replace current version with new version"); if (environmentService.Platform != OSPlatform.Windows) { await destination.CopyToAsync(fileSystem.GetDirectory(environmentService.AssemblyDirectory)).ConfigureAwait(false); tempDirectory.Delete(); } else { VirtualFile batchFile = tempDirectory.File("copy_version.bat"); Assembly currentAssembly = Assembly.GetAssembly(GetType()); using (Stream batchResourceStream = currentAssembly.GetManifestResourceStream("PlcNext.Common.Installation.copy_version.bat")) using (Stream batchFileStream = batchFile.OpenWrite()) { batchResourceStream?.CopyTo(batchFileStream); } processManager.StartProcess(batchFile.FullName, $"\"{destination.FullName}\" \"{environmentService.AssemblyDirectory}\" " + $"\"{tempDirectory.FullName}\" \"{binariesLocator.GetExecutable("application").Name}\"", userInterface, null, showOutput: false, showError: false, killOnDispose: false); } } }
public async Task Install(VirtualDirectory newVersionDirectory, IProgressNotifier parentProgress) { executionContext.WriteInformation("Migrating settings"); VirtualFile executable = GetExecutable(); IEnumerable <string> availableSettings = (await GetAvailableSettings().ConfigureAwait(false)).ToArray(); string[] migratableSettings = availableSettings.Where(settingsProvider.HasSetting) .ToArray(); await Migrate().ConfigureAwait(false); string[] nonMigratableSettings = settingsProvider.GetSettingKeys() .Except(availableSettings) .ToArray(); if (nonMigratableSettings.Any()) { executionContext.WriteInformation("The following settings could not be migrated and are lost:"); executionContext.WriteInformation(string.Join(", ", nonMigratableSettings)); } async Task Migrate() { using (IProgressNotifier progress = parentProgress?.Spawn(migratableSettings.Count() + 1)) { foreach (string setting in migratableSettings) { progress?.TickIncrement(message: $"Migrate '{setting}'"); string value = settingsProvider.GetSettingValue(setting); if (string.IsNullOrEmpty(value)) { await ExecuteCommand($"set setting \"{setting}\" --clear --no-sdk-exploration").ConfigureAwait(false); } else { await ExecuteCommand($"set setting \"{setting}\" \"{settingsProvider.GetSettingValue(setting)}\" --no-sdk-exploration").ConfigureAwait(false); } } } } VirtualFile GetExecutable() { VirtualFile result = binariesLocator.GetExecutable("application", newVersionDirectory.FullName); if (result == null) { throw new FormattableException($"No executable found in directory {newVersionDirectory.FullName} to migrate settings."); } return(result); } async Task <IEnumerable <string> > GetAvailableSettings() { string command = "get setting --all"; StringBuilderUserInterface userInterface = await ExecuteCommand(command).ConfigureAwait(false); JObject settings = JObject.Parse(userInterface.Information); IEnumerable <string> result = settings.Properties().Select(p => p.Name); return(result); } async Task <StringBuilderUserInterface> ExecuteCommand(string executableCommand) { StringBuilderUserInterface ui = new StringBuilderUserInterface(executionContext, writeInformation: true, writeError: true); IProcess process = processManager.StartProcess(executable.FullName, executableCommand, ui); await process.WaitForExitAsync().ConfigureAwait(false); string error = ui.Error; if (!string.IsNullOrEmpty(error)) { throw new SettingsMigrationException(string.Format(CultureInfo.InvariantCulture, ExceptionTexts.SettingsMigrationProcessError, $"{executable.FullName} {executableCommand}", error)); } return(ui); } }