Пример #1
0
 private static void OnAppcastDownloadFinished(Appcast appcast)
 {
     try
     {
         AppcastDownloadFinished?.Invoke(appcast);
     }
     catch (Exception exp)
     {
         OnLogMessage("Internal error: " + exp.Message);
     }
 }
Пример #2
0
 private static void OnNewUpdateAvailable(Appcast appcast)
 {
     try
     {
         NewUpdateAvailable?.Invoke(appcast);
     }
     catch
     {
         // ignore all
     }
 }
Пример #3
0
        /// <summary>
        /// Skip current version
        /// IMPORTANT: Should be used ONLY in case of own implementation GUI for user iteraction
        /// </summary>
        public static void SkipThisVersion()
        {
            Appcast ac = __CurrentAppcast;

            if (ac != null)
            {
                __VersionToSkip = ac.Version;
                WriteRegistry();
            }

            Cancel();
        }
Пример #4
0
        static void _downloader_DownloadFinished(bool isCanceled, Exception ex)
        {
            try
            {
                lock (Locker)
                {
                    ContinueEvent.Reset();

                    OnDownloadFinished(isCanceled, ex);
                    if (isCanceled || ex != null)
                    {
                        LastCheckTime = DateTime.Now;
                        WriteRegistry();

                        DeleteTempFile();
                        __Downloader = null;
                    }

                    // start installer
                    if (__Downloader != null &&
                        !string.IsNullOrEmpty(__Downloader.DestinationFilePath) &&
                        !string.IsNullOrEmpty(__Downloader.SourceFilePath)
                        )
                    {
                        // waiting for call 'Continue()/Cancel()' function
                        ContinueEvent.WaitOne();

                        if (__IsCancelled)
                        {
                            DeleteTempFile();
                        }
                        else
                        {
                            __TmpFile = Path.Combine(Path.GetDirectoryName(__Downloader.DestinationFilePath), Path.GetFileName(__Downloader.SourceFilePath));

                            if (File.Exists(__TmpFile))
                            {
                                File.Delete(__TmpFile);
                            }

                            // set correct extenfion
                            File.Move(__Downloader.DestinationFilePath, __TmpFile);
                            WriteRegistry();

                            // Check DSA signature
                            if (string.IsNullOrEmpty(__OpenSslPath) == false && __DsaPublicKey != null)
                            {
                                Appcast appcast = __CurrentAppcast;
                                if (appcast == null)
                                {
                                    OnError(new UpdaterExceptionSignatureError());
                                    return;
                                }

                                if (CheckSignature(__TmpFile, appcast.Signature) == false)
                                {
                                    OnError(new UpdaterExceptionSignatureError());
                                    return;
                                }
                            }

                            // start installer!
                            Process.Start(__TmpFile);
                        }
                    }

                    LastCheckTime = DateTime.Now;
                    WriteRegistry();
                }
            }
            finally
            {
                __CurrentAppcast   = null;
                __Downloader       = null;
                IsUpdateInProgress = false;
            }
        }
Пример #5
0
        /// <summary>
        /// Perform Update
        /// </summary>
        /// <param name="isManualCheck">TRUE - user iteraction (called by user manually)
        /// In this case, we should ignore "versionToSkip" property
        /// </param>
        /// <param name="checkInBackground"> Do not show "Checking for updates ..." dialog </param>
        private static void DoCheckUpdate(bool isManualCheck = false, bool checkInBackground = false)
        {
            lock (Locker)
            {
                bool isUpdateReady = false;
                try
                {
                    IsUpdateInProgress = true;

                    __CurrentAppcast = null;
                    __IsCancelled    = false;
                    ContinueEvent.Reset();

                    // check if downloading not finished
                    if (__Downloader != null)
                    {
                        return;
                    }

                    // delete rubbish from previous session
                    DeleteTempFile();

                    if (checkInBackground == false)
                    {
                        OnCheckingForUpdate();
                    }

                    // read latest appcast
                    try
                    {
                        if (isManualCheck && !string.IsNullOrEmpty(AppcastFilePathForManualUpdate))
                        {
                            // Appcast files for automatic and manual updates are divided.
                            //
                            // If appcast file for manual update is available AND version of manual update is newer - we should use appcast with manual update.
                            // Othervise - we are using 'original' appcast file for automatic updates.
                            try
                            {
                                Appcast manualAppcast             = null;
                                bool    isManualAppcastDownloaded = false;
                                Task.Run(() =>
                                {
                                    try { manualAppcast = Appcast.Read(AppcastFilePathForManualUpdate); }
                                    catch { manualAppcast = null; }
                                    finally { isManualAppcastDownloaded = true; }
                                });

                                var defaultAppcast = Appcast.Read(AppcastFilePath);
                                SpinWait.SpinUntil(() => isManualAppcastDownloaded == true, 3000);

                                if (manualAppcast != null && defaultAppcast != null && CompareVersions(defaultAppcast.Version, manualAppcast.Version))
                                {
                                    __CurrentAppcast = manualAppcast;
                                }
                                else
                                {
                                    __CurrentAppcast = defaultAppcast;
                                }
                            }
                            catch { } // ignore all
                        }

                        if (__CurrentAppcast == null)
                        {
                            __CurrentAppcast = Appcast.Read(AppcastFilePath);
                        }
                    }
                    catch (UpdaterExceptionAppcastDownload ex)
                    {
                        if (isManualCheck)
                        {
                            OnError(ex);
                        }
                        //OnNothingToUpdate();
                        return;
                    }
                    catch (Exception)
                    {
                        if (isManualCheck)
                        {
                            OnNothingToUpdate();
                        }
                        return;
                    }
                    finally
                    {
                        LastCheckTime = DateTime.Now;
                        WriteRegistry();
                    }

                    // if called function Cancel()
                    OnAppcastDownloadFinished(__CurrentAppcast);

                    // if called function Cancel()
                    if (__IsCancelled)
                    {
                        return;
                    }

                    // check if we should skip this version
                    if (string.IsNullOrEmpty(__VersionToSkip) == false &&
                        __CurrentAppcast.Version.Equals(__VersionToSkip))
                    {
                        return;
                    }

                    if (!CompareVersions(__CurrentAppcast.Version))
                    {
                        if (isManualCheck)
                        {
                            OnNothingToUpdate();
                        }
                        return;
                    }

                    // Notification about new update
                    OnNewUpdateAvailable(__CurrentAppcast);

                    // waiting for call 'Continue()/Cancel()/SkipThisVersion()' function
                    ContinueEvent.WaitOne();

                    LastCheckTime = DateTime.Now;
                    WriteRegistry();

                    // if called function Cancel()
                    if (__IsCancelled)
                    {
                        return;
                    }

                    // check if we should skip this version
                    // if was called function SkipThisVersion()
                    if (string.IsNullOrEmpty(__VersionToSkip) == false &&
                        __CurrentAppcast.Version.Equals(__VersionToSkip))
                    {
                        return;
                    }

                    isUpdateReady = true;
                }
                finally
                {
                    if (isUpdateReady == false)
                    {
                        __CurrentAppcast   = null;
                        IsUpdateInProgress = false;
                    }
                }

                // delete rubbish from previous session
                DeleteTempFile();

                __TmpFile = Path.GetTempFileName();
                WriteRegistry();

                // save current appcast
                __Downloader                   = new Downloader(__CurrentAppcast.UpdateLink, __TmpFile);
                __Downloader.Downloaded       += _downloader_Downloaded;
                __Downloader.DownloadFinished += _downloader_DownloadFinished;
                __Downloader.Download();
            }
        }
Пример #6
0
        /// <summary>
        /// Download and read appcast
        /// </summary>
        /// <param name="appcastPath"></param>
        /// <returns></returns>
        internal static Appcast Read(string appcastPath)
        {
            XmlDocument myXmlDocument = new XmlDocument();

            try
            {
                myXmlDocument.Load(appcastPath);
            }
            catch (Exception ex)
            {
                throw new UpdaterExceptionAppcastDownload("Error loading appcast file.\n" + ex.Message + "\n\nPlease, check internet connection", ex);
            }

            try
            {
                XPathNavigator      navigator = myXmlDocument.CreateNavigator();
                XmlNamespaceManager xmlns     = new XmlNamespaceManager(navigator.NameTable);

                const string sparkleNamespaceUrl = "http://www.andymatuschak.org/xml-namespaces/sparkle";
                xmlns.AddNamespace("sparkle", sparkleNamespaceUrl);

                if (myXmlDocument.DocumentElement == null)
                {
                    throw new UpdaterExceptionAppcastDownload("Error loading appcast file.");
                }

                Appcast appcast = new Appcast();

                XmlNode releaseNotesNode = myXmlDocument.DocumentElement.SelectSingleNode("/rss/channel/item/sparkle:releaseNotesLink", xmlns);
                if (releaseNotesNode != null)
                {
                    string rn = releaseNotesNode.InnerText.Trim();
                    if (!string.IsNullOrEmpty(rn))
                    {
                        appcast.ReleaseNotesLink = releaseNotesNode.InnerText.Trim();
                    }
                }

                XmlNode enclosureNode = myXmlDocument.DocumentElement.SelectSingleNode("/rss/channel/item/enclosure");
                if (enclosureNode == null || enclosureNode.Attributes == null)
                {
                    throw new UpdaterExceptionAppcastParsing("Not found information about update");
                }

                XmlAttribute urlAttr = enclosureNode.Attributes["url"];

                XmlAttribute versionAttr      = enclosureNode.Attributes["sparkle:version"];
                XmlAttribute lengthAttr       = enclosureNode.Attributes["length"];
                XmlAttribute dsaSignatureAttr = enclosureNode.Attributes["sparkle:dsaSignature"];

                if (urlAttr == null)
                {
                    throw new UpdaterExceptionAppcastParsing("Update link not defined");
                }
                if (versionAttr == null)
                {
                    throw new UpdaterExceptionAppcastParsing("Version not defined");
                }
                if (!Uri.IsWellFormedUriString(urlAttr.InnerText.Trim(), UriKind.RelativeOrAbsolute))
                {
                    throw new UpdaterExceptionAppcastParsing("Update link error");
                }

                appcast.UpdateLink = urlAttr.InnerText.Trim();
                appcast.Version    = versionAttr.InnerText.Trim();

                UInt32 length;
                if (lengthAttr != null && UInt32.TryParse(lengthAttr.InnerText.Trim(), out length))
                {
                    appcast.Length = length;
                }

                appcast.Signature = dsaSignatureAttr.InnerText.Trim();

                return(appcast);
            }
            catch (Exception ex)
            {
                throw new UpdaterExceptionAppcastParsing("Error parsing appcast file", ex);
            }
        }