/// <summary> /// Installs the contents of the archive specified by<paramref name="downloadedFileName"/> /// according to the detected platform. /// </summary> /// <param name="downloadedFileName">The downloaded application files to install.</param> /// <param name="versionTag">The version tag corresponding to the selected release or /// the provided update zip file.</param> private async Task InstallOnPlatform(string downloadedFileName, string versionTag) { // Set the progress bar to "indeterminate" Dispatcher.UIThread.Post(() => { this.DownloadPercentage = 0; this.IsProgressIndeterminate = true; }); // Write the installation path to the config file so that // we can locate the installation later Log.Information($"Writing installation path to config file: \"{this.InstallationPath}\""); PathConf.ClientInstallPath = this.InstallationPath; // Check if client is running and kill it if necessary Log.Information($"Checking if client is running"); // On macOS, process names are truncated to 15 chararcters, // so we cannot match the full process name var procName = Path.GetFileNameWithoutExtension(_installer.GetClientExePath(this.InstallationPath)) .Substring(0, 15); Process[] processes = Process.GetProcesses() .Where(x => x.ProcessName.StartsWith(procName)).ToArray(); if (processes.Length > 0) { var clientProcess = processes[0]; Log.Warning($"Client is running, trying to kill it"); clientProcess.Kill(); // Since the below call to "WaitForExit()" could potentially block // forever if killing the client fails for some reason, we better // give an indication of what's going on in the UI and hopefully have the // user help out closing the client if our programmatic approach fails. Dispatcher.UIThread.Post(() => this.InstallStatus = _loc.GetLocalizationValue("InstallStatusWaitingForClientExit")); await Task.Run(() => clientProcess.WaitForExit()); Log.Information($"Client exited, continuing"); } else { Log.Information($"Client not running, continuing"); } // Set status "installing" in UI Dispatcher.UIThread.Post(() => this.InstallStatus = _loc.GetLocalizationValue("InstallStatusInstalling")); // Perform the actual installation Log.Information($"Launching installation"); try { await _installer.Install(downloadedFileName, this.InstallationPath, versionTag); } catch (Exception ex) { Log.Error($"Error during installation:\r\n{ex}"); SetErrorStatus(); return; } ((MainWindowViewModel)_mainWindow.DataContext).Content = new InstallationCompleteViewModel(_installer.GetClientExePath(this.InstallationPath)); }