public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            StackPanel stackPanel = new StackPanel()
            {
                Orientation = Orientation.Horizontal
            };
            PackIconBase icon = null;
            string       text = "";

            ResourceManager resourceManager = new ResourceManager(typeof(Properties.Resources));

            GitHubRelease release = (GitHubRelease)value;

            switch (release.ReleaseTimeType)
            {
            case GitHubReleaseTimeTypes.OLD:
                icon = new PackIconMaterial()
                {
                    Kind = PackIconMaterialKind.History
                };
                text = resourceManager.GetString("DowngradeString");
                break;

            case GitHubReleaseTimeTypes.CURRENT:
                icon = new PackIconOcticons()
                {
                    Kind = PackIconOcticonsKind.Tools
                };
                text = resourceManager.GetString("RepairString");
                break;

            case GitHubReleaseTimeTypes.NEW:
                icon = new PackIconOcticons()
                {
                    Kind = PackIconOcticonsKind.DesktopDownload
                };
                text = resourceManager.GetString("UpgradeString");
                break;
            }

            icon.Width             = 20;
            icon.Height            = double.NaN;
            icon.Margin            = new System.Windows.Thickness(5, 0, 10, 0);
            icon.VerticalAlignment = System.Windows.VerticalAlignment.Center;
            stackPanel.Children.Add(icon);

            stackPanel.Children.Add(new TextBlock(new Run(text))
            {
                FontSize = 12, VerticalAlignment = System.Windows.VerticalAlignment.Center
            });

            return(stackPanel);
        }
Example #2
0
        //####################################################################################################################################################################

        /// <summary>
        /// Update the application to the given target release. This can also be a downgrade (lower version) or repair (same version).
        /// </summary>
        /// <param name="targetRelease">New version after update</param>
        public static async Task RunUpdate(GitHubRelease targetRelease)
        {
            WindowAssemblyInfo windowAssemblyInfo = System.Windows.Application.Current.Windows.OfType <MahApps.Metro.Controls.MetroWindow>().OfType <WindowAssemblyInfo>().FirstOrDefault();
            Version            targetVersion      = new Version(targetRelease.Version.ToString());

            try
            {
                UpdateStatus.FromVersion     = new SemVersion(new Version(AssemblyInfoHelperClass.AssemblyVersion));
                UpdateStatus.ToVersion       = targetRelease.Version;
                UpdateStatus.IsUpdateRunning = true;

                MessageDialogResult messageResult = await windowAssemblyInfo.ShowMessageAsync("Confirm update", "Do you really want to " + UpdateStatus.UpdateText + "?" + ((UpdateStatus.FromVersion > UpdateStatus.ToVersion) ? Environment.NewLine + Environment.NewLine + "For downgrades to lower versions, this update feature may not be available anymore! You have to download manually then!" : ""), MessageDialogStyle.AffirmativeAndNegative);

                if (messageResult == MessageDialogResult.Negative)
                {
                    UpdateStatus.IsUpdateRunning = false; return;
                }

                bool useBinaries = false, useInstaller = false;

                if (targetRelease.BinAsset != null && targetRelease.InstallerAsset == null)
                {
                    useBinaries = true;
                }                                                                                                           // If only bin asset exists, use this as update source
                else if (targetRelease.BinAsset == null && targetRelease.InstallerAsset != null)
                {
                    useInstaller = true;
                }                                                                                                           // If only installer asset exists, use the installer for update
                else if (targetRelease.BinAsset != null && targetRelease.InstallerAsset != null)                            // If both bin asset and installer asset exist, let the user choose the update source
                {
                    messageResult = await windowAssemblyInfo.ShowMessageAsync("Choose update source", "There are multiple options to update this version. Choose one of the options below.", MessageDialogStyle.AffirmativeAndNegative, new MetroDialogSettings()
                    {
                        AffirmativeButtonText = "Use binaries", NegativeButtonText = "Use installer", DefaultButtonFocus = MessageDialogResult.Affirmative
                    });

                    if (messageResult == MessageDialogResult.Affirmative)
                    {
                        useBinaries = true;
                    }
                    else
                    {
                        useInstaller = true;
                    }
                }

                // Decide which asset to download
                ReleaseAsset downloadAsset = (useBinaries ? targetRelease.BinAsset : (useInstaller ? targetRelease.InstallerAsset : null));
                if (downloadAsset == null)
                {
                    await windowAssemblyInfo.ShowMessageAsync("Release asset not found", "Asset for Release v" + targetVersion.ToString() + " not found on GitHub.");

                    UpdateStatus.IsUpdateRunning = false;
                    return;
                }

                // Delete and recreate the download folder
                string downloadFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), AssemblyInfoHelperClass.AssemblyTitle, targetVersion.ToString());
                if (Directory.Exists(downloadFolder))
                {
                    Directory.Delete(downloadFolder, true);
                }
                Directory.CreateDirectory(downloadFolder);

                // Download Assets; if download fails, try 10 times
                WebClient client = new WebClient();
                client.DownloadProgressChanged += (sender, args) => { UpdateStatus.UpdateProgress = args.ProgressPercentage; };
                string downloadFilePath = Path.Combine(downloadFolder, Path.GetFileName(downloadAsset.BrowserDownloadUrl));

                int failedDownloads = 0;
                do
                {
                    try
                    {
                        await client.DownloadFileTaskAsync(downloadAsset.BrowserDownloadUrl, downloadFilePath);

                        failedDownloads = -1;
                    }
                    catch (WebException) { failedDownloads++; }
                    catch (InvalidOperationException) { failedDownloads++; }
                } while (failedDownloads != -1 && failedDownloads < 10);

                if (failedDownloads != -1)
                {
                    await windowAssemblyInfo.ShowMessageAsync("Download failed", "Download from \"" + downloadAsset.BrowserDownloadUrl + "\" failed.");

                    UpdateStatus.IsUpdateRunning = false;
                    return;
                }

                // Extract zip files if asset is zip file
                if (Path.GetExtension(downloadFilePath) == ".zip")
                {
                    ZipFile.ExtractToDirectory(downloadFilePath, downloadFolder);
                    File.Delete(downloadFilePath);                                  // delete zip file after extraction
                }

                if (useBinaries)
                {
                    UpdateUtils.LaunchUpdater(downloadFolder, true);           // Launch an executable that will apply the update and restart the application afterwards
                }
                else if (useInstaller)
                {
                    if (!File.Exists(Path.Combine(downloadFolder, "Setup.exe")))
                    {
                        await windowAssemblyInfo.ShowMessageAsync("Setup.exe not found", "Installer must contain a Setup.exe file!");

                        UpdateStatus.IsUpdateRunning = false;
                        return;
                    }
                    Process.Start(Path.Combine(downloadFolder, "Setup.exe"));
                }

                if (useInstaller)
                {
                    await windowAssemblyInfo.ShowMessageAsync("Update", "To finish the update, the application is closed now. Please use the started installer to reinstall the application.", MessageDialogStyle.Affirmative);
                }
                else if (useBinaries)
                {
                    await windowAssemblyInfo.ShowMessageAsync("Update", "To finish the update, the application is closed now. This may take some time. After the update is finished, the application is restarted.", MessageDialogStyle.Affirmative);
                }

                Environment.Exit(0);                            // Terminate the running application so that the updater/installer can overwrite files
            }
            catch (Exception ex)
            {
                await windowAssemblyInfo?.ShowMessageAsync("Error while update", ex.Message);

                UpdateStatus.IsUpdateRunning = false;
            }
        }