コード例 #1
0
        /// <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));
        }