Exemplo n.º 1
0
        internal static async Task CheckForUpdate()
        {
            string oldExeFile = ExecutableFile + ".old";

            // We booted successfully so we can now remove old exe file
            if (File.Exists(oldExeFile))
            {
                try {
                    File.Delete(oldExeFile);
                } catch (Exception e) {
                    Logging.LogGenericException(e);
                    return;
                }
            }

            if (GlobalConfig.UpdateChannel == GlobalConfig.EUpdateChannel.Unknown)
            {
                return;
            }

            string releaseURL = GithubReleaseURL;

            if (GlobalConfig.UpdateChannel == GlobalConfig.EUpdateChannel.Stable)
            {
                releaseURL += "/latest";
            }

            string response = null;

            Logging.LogGenericInfo("Checking new version...");
            for (byte i = 0; i < WebBrowser.MaxRetries && string.IsNullOrEmpty(response); i++)
            {
                response = await WebBrowser.UrlGetToContent(releaseURL).ConfigureAwait(false);
            }

            if (string.IsNullOrEmpty(response))
            {
                Logging.LogGenericWarning("Could not check latest version!");
                return;
            }

            GitHub.ReleaseResponse releaseResponse;
            if (GlobalConfig.UpdateChannel == GlobalConfig.EUpdateChannel.Stable)
            {
                try {
                    releaseResponse = JsonConvert.DeserializeObject <GitHub.ReleaseResponse>(response);
                } catch (JsonException e) {
                    Logging.LogGenericException(e);
                    return;
                }
            }
            else
            {
                List <GitHub.ReleaseResponse> releases;
                try {
                    releases = JsonConvert.DeserializeObject <List <GitHub.ReleaseResponse> >(response);
                } catch (JsonException e) {
                    Logging.LogGenericException(e);
                    return;
                }

                if (releases == null || releases.Count == 0)
                {
                    Logging.LogGenericWarning("Could not check latest version!");
                    return;
                }

                releaseResponse = releases[0];
            }

            if (string.IsNullOrEmpty(releaseResponse.Tag))
            {
                Logging.LogGenericWarning("Could not check latest version!");
                return;
            }

            Version newVersion = new Version(releaseResponse.Tag);

            Logging.LogGenericInfo("Local version: " + Version + " | Remote version: " + newVersion);

            if (Version.CompareTo(newVersion) >= 0)               // If local version is the same or newer than remote version
            {
                if (AutoUpdatesTimer == null && GlobalConfig.AutoUpdates)
                {
                    Logging.LogGenericInfo("ASF will automatically check for new versions every 24 hours");
                    AutoUpdatesTimer = new Timer(
                        async e => await CheckForUpdate().ConfigureAwait(false),
                        null,
                        TimeSpan.FromDays(1),                        // Delay
                        TimeSpan.FromDays(1)                         // Period
                        );
                }
                return;
            }

            if (!GlobalConfig.AutoUpdates)
            {
                Logging.LogGenericInfo("New version is available!");
                Logging.LogGenericInfo("Consider updating yourself!");
                await Utilities.SleepAsync(5000).ConfigureAwait(false);

                return;
            }

            // Auto update logic starts here
            if (releaseResponse.Assets == null)
            {
                Logging.LogGenericWarning("Could not proceed with update because that version doesn't include assets!");
                return;
            }

            GitHub.Asset binaryAsset = null;
            foreach (var asset in releaseResponse.Assets)
            {
                if (string.IsNullOrEmpty(asset.Name) || !asset.Name.Equals(ExecutableName))
                {
                    continue;
                }

                binaryAsset = asset;
                break;
            }

            if (binaryAsset == null)
            {
                Logging.LogGenericWarning("Could not proceed with update because there is no asset that relates to currently running binary!");
                return;
            }

            if (string.IsNullOrEmpty(binaryAsset.DownloadURL))
            {
                Logging.LogGenericWarning("Could not proceed with update because download URL is empty!");
                return;
            }

            Logging.LogGenericInfo("Downloading new version...");
            Stream newExe = await WebBrowser.UrlGetToStream(binaryAsset.DownloadURL).ConfigureAwait(false);

            if (newExe == null)
            {
                Logging.LogGenericWarning("Could not download new version!");
                return;
            }

            // We start deep update logic here
            string newExeFile = ExecutableFile + ".new";

            // Firstly we create new exec
            try {
                using (FileStream fileStream = File.Open(newExeFile, FileMode.Create)) {
                    await newExe.CopyToAsync(fileStream).ConfigureAwait(false);
                }
            } catch (Exception e) {
                Logging.LogGenericException(e);
                return;
            }

            // Now we move current -> old
            try {
                File.Move(ExecutableFile, oldExeFile);
            } catch (Exception e) {
                Logging.LogGenericException(e);
                try {
                    // Cleanup
                    File.Delete(newExeFile);
                } catch { }
                return;
            }

            // Now we move new -> current
            try {
                File.Move(newExeFile, ExecutableFile);
            } catch (Exception e) {
                Logging.LogGenericException(e);
                try {
                    // Cleanup
                    File.Move(oldExeFile, ExecutableFile);
                    File.Delete(newExeFile);
                } catch { }
                return;
            }

            Logging.LogGenericInfo("Update process is finished! ASF will now restart itself...");
            await Utilities.SleepAsync(5000);

            Restart();
        }