Пример #1
0
        /// <summary>
        ///   Called when a version check operation has been performed sucessfully.s
        /// </summary>
        /// <commondoc select='All/Methods/EventRaisers[@Params="+EventArgs"]/*' params='EventName=VersionCheckSuccessful' />
        protected virtual void OnVersionCheckSuccessful(VersionCheckSuccessfulEventArgs e)
        {
            if (e == null)
            {
                throw new ArgumentNullException();
            }

            this.VersionCheckSuccessful?.Invoke(this, e);
        }
Пример #2
0
        /// <summary>
        ///   Beings connecting to the update server asynchronously and raises either the <see cref="VersionCheckSuccessful" />
        ///   or <see cref="VersionCheckError" /> event when done.
        /// </summary>
        /// <remarks>
        ///   <para>
        ///     The download of the data is performed asynchronously by using a <see cref="BackgroundWorker" /> object. <br />
        ///     Multiple calls of this method at once can lead in a possible <see cref="NotSupportedException" />,
        ///     because one instance of this class is not able to handle multiple version check operations at the same time. <br />
        ///   </para>
        ///   <note type="implementnotes">
        ///     Use the <see cref="IsVersionChecking" /> property to check whether an aynchronous version check operation is
        ///     already in progress before calling this method multiple times.
        ///   </note>
        ///   <note type="implementnotes">
        ///     Use the <see cref="AbortVersionCheck" /> method to cancel an asynchronous version check operation.
        ///   </note>
        /// </remarks>
        /// <exception cref="WebException">
        ///   Error on connecting to server or downloading data or both <see cref="Update_UpdateInfoPage" /> and
        ///   <see cref="Update_UpdateInfoPageAlt" /> constants contain an invalid URL.
        /// </exception>
        /// <exception cref="InvalidOperationException">
        ///   Another asynchronous version check operation is already in progress by this instance.
        /// </exception>
        /// <commondoc select='IDisposable/Methods/All/*' />
        /// <seealso cref="VersionCheckSuccessful">VersionCheckSuccessful Event</seealso>
        /// <seealso cref="VersionCheckError">VersionCheckError Event</seealso>
        /// <seealso cref="IsVersionChecking">IsVersionChecking Property</seealso>
        /// <seealso cref="AbortVersionCheck">AbortVersionCheck Method</seealso>
        public void BeginVersionCheck()
        {
            if (this.IsDisposed)
            {
                throw new ObjectDisposedException("this");
            }
            if (this.IsVersionChecking)
            {
                throw new InvalidOperationException();
            }

            this.currentVersionCheckWorker = new BackgroundWorker();
            this.currentVersionCheckWorker.WorkerSupportsCancellation = true;
            this.currentVersionCheckWorker.DoWork += delegate(object sender, DoWorkEventArgs e) {
                if (e.Cancel)
                {
                    return;
                }

                var      arguments         = (Tuple <string[], Version>)e.Argument;
                string[] urlsToCheck       = arguments.Item1;
                Version  currentAppVersion = arguments.Item2;

                Exception error             = null;
                Version   mostRecentVersion = null;
                string    infoMessage       = null;
                string    criticalMessage   = null;

                // Work through all available servers to check for a new version.
                using (WebClient webClient = new WebClient()) {
                    for (int i = 0; i < urlsToCheck.Length; i++)
                    {
                        if (e.Cancel)
                        {
                            return;
                        }

                        try {
                            byte[] data = webClient.DownloadData(string.Format(CultureInfo.InvariantCulture, urlsToCheck[i], currentAppVersion));

                            using (MemoryStream dataStream = new MemoryStream(data)) {
                                XmlDocument versionCheckData = new XmlDocument();
                                versionCheckData.Load(dataStream);

                                if (versionCheckData.DocumentElement == null)
                                {
                                    throw new FormatException("The update site has returned invalid data.");
                                }

                                XmlNode newestVersionNode   = versionCheckData.DocumentElement["NewestVersion"];
                                XmlNode infoMessageNode     = versionCheckData.DocumentElement["InfoMessage"];
                                XmlNode criticalMessageNode = versionCheckData.DocumentElement["CriticalMessage"];
                                if ((newestVersionNode == null) || (criticalMessageNode == null))
                                {
                                    throw new FormatException("The update site has returned invalid data.");
                                }

                                Version versionNumberFromThisServer;
                                try {
                                    versionNumberFromThisServer = new Version(newestVersionNode.InnerText);
                                } catch (Exception exception) {
                                    throw new FormatException("The update site has returned invalid data.", exception);
                                }
                                // Make sure that this server didn't return an older version number than another server.
                                if ((mostRecentVersion != null) && (versionNumberFromThisServer < mostRecentVersion))
                                {
                                    continue;
                                }

                                mostRecentVersion = versionNumberFromThisServer;
                                criticalMessage   = criticalMessageNode.InnerText;
                                if (infoMessageNode != null)
                                {
                                    infoMessage = infoMessageNode.InnerText;
                                }
                            }
                        } catch (Exception exception) {
                            error = exception;
                        }
                    }
                }

                // We don't want to throw an Exception if we got the data we needed from at least one server.
                if (mostRecentVersion != null)
                {
                    error = null;
                }

                VersionCheckSuccessfulEventArgs successfulResultData = null;
                if (error == null)
                {
                    successfulResultData = new VersionCheckSuccessfulEventArgs((currentAppVersion < mostRecentVersion), mostRecentVersion, criticalMessage, infoMessage);
                }
                e.Result = new Tuple <Exception, VersionCheckSuccessfulEventArgs>(error, successfulResultData);
            };

            this.currentVersionCheckWorker.RunWorkerCompleted += delegate(object sender, RunWorkerCompletedEventArgs e) {
                try {
                    var result = (Tuple <Exception, VersionCheckSuccessfulEventArgs>)e.Result;

                    if (result.Item1 != null)
                    {
                        this.OnVersionCheckError(new ExceptionEventArgs(result.Item1));
                    }
                    else
                    {
                        this.OnVersionCheckSuccessful(result.Item2);
                    }
                } finally {
                    if (this.currentVersionCheckWorker != null)
                    {
                        this.currentVersionCheckWorker.Dispose();
                        this.currentVersionCheckWorker = null;
                    }
                }
            };

            this.currentVersionCheckWorker.RunWorkerAsync(new Tuple <string[], Version>(
                                                              new[] { UpdateManager.Update_UpdateInfoPage, UpdateManager.Update_UpdateInfoPageAlt },
                                                              (Version)this.Environment.AppVersion.Clone()));
        }