Пример #1
0
        /// <summary>
        /// Starts the asynchronous update process.
        /// </summary>
        /// <exception cref="InvalidOperationException"><see cref="IsRunning"/> was true.</exception>
        public void Start()
        {
            // Check the current IsRunning state, and set it to true
            bool isAlreadyRunning;

            lock (_isRunningSync)
            {
                isAlreadyRunning = IsRunning;
                if (!isAlreadyRunning)
                {
                    _isRunning = true;
                }
            }

            // Throw an exception if the IsRunning was already true
            if (isAlreadyRunning)
            {
                throw new InvalidOperationException("The UpdateClient is already running.");
            }

            try
            {
                if (IsRunningChanged != null)
                {
                    IsRunningChanged(this);
                }
            }
            catch (NullReferenceException ex)
            {
                Debug.Fail(ex.ToString());
            }

            State = UpdateClientState.Initializing;

            // Create the objects
            _msr          = new MasterServerReader(Settings.LocalFileServerPath, Settings.LocalMasterServerPath);
            _fileReplacer = Settings.CreateOfflineFileReplacer();

            State = UpdateClientState.ReadingLiveVersion;

            // Start grabbing from the master server
            _msr.BeginReadVersion(MasterServerReader_Callback, this);
        }
Пример #2
0
        /// <summary>
        /// Starts the asynchronous update process.
        /// </summary>
        /// <exception cref="InvalidOperationException"><see cref="IsRunning"/> was true.</exception>
        public void Start()
        {
            // Check the current IsRunning state, and set it to true
            bool isAlreadyRunning;
            lock (_isRunningSync)
            {
                isAlreadyRunning = IsRunning;
                if (!isAlreadyRunning)
                    _isRunning = true;
            }

            // Throw an exception if the IsRunning was already true
            if (isAlreadyRunning)
                throw new InvalidOperationException("The UpdateClient is already running.");

            try
            {
                if (IsRunningChanged != null)
                    IsRunningChanged(this);
            }
            catch (NullReferenceException ex)
            {
                Debug.Fail(ex.ToString());
            }

            State = UpdateClientState.Initializing;

            // Create the objects
            _msr = new MasterServerReader(Settings.LocalFileServerPath, Settings.LocalMasterServerPath);
            _fileReplacer = Settings.CreateOfflineFileReplacer();

            State = UpdateClientState.ReadingLiveVersion;

            // Start grabbing from the master server
            _msr.BeginReadVersion(MasterServerReader_Callback, this);
        }
Пример #3
0
        /// <summary>
        /// The callback method for the <see cref="IMasterServerReader.BeginReadVersionFileList"/>.
        /// </summary>
        /// <param name="sender">The <see cref="IMasterServerReader"/> this event came from.</param>
        /// <param name="info">The information from the master server(s).</param>
        /// <param name="userState">An optional state object passed by the caller to supply information to the callback method
        /// from the method call.</param>
        void MasterServerReader_Callback_VersionFileList(IMasterServerReader sender, IMasterServerReadInfo info, object userState)
        {
            State = UpdateClientState.ReadingLiveVersionFileListDone;

            // Check for a valid VersionFileList
            if (string.IsNullOrEmpty(info.VersionFileListText))
            {
                const string errmsg =
                    "Could not get a valid VersionFileList file from the master servers for version `{0}` - download failed.";

                if (log.IsErrorEnabled)
                    log.ErrorFormat(errmsg, info.Version);

                if (MasterServerReaderError != null)
                    MasterServerReaderError(this, string.Format(errmsg, info.Version));

                HasErrors = true;
                return;
            }

            try
            {
                _versionFileList = VersionFileList.CreateFromString(info.VersionFileListText);
            }
            catch (Exception ex)
            {
                const string errmsg =
                    "Could not get a valid VersionFileList file from the master servers for version `{0}`. Exception: {1}";

                if (log.IsErrorEnabled)
                    log.ErrorFormat(errmsg, info.Version, ex);

                if (MasterServerReaderError != null)
                    MasterServerReaderError(this, string.Format(errmsg, info.Version, ex));

                HasErrors = true;
                return;
            }

            // Find the files to update
            var toUpdate = FindFilesToUpdate(_versionFileList);

            // If all file hashes match, then we are good to go
            if (toUpdate.Count() == 0)
            {
                CheckIfDownloadManagerComplete();
                return;
            }

            // There was one or more files to update, so start the updating...

            // Create the DownloadManager
            _dm = new DownloadManager(Settings.TargetPath, Settings.TempPath, info.Version);
            _dm.DownloadFinished += DownloadManager_DownloadFinished;
            _dm.FileMoveFailed += DownloadManager_FileMoveFailed;
            _dm.DownloadFailed += DownloadManager_DownloadFailed;
            _dm.Finished += DownloadManager_Finished;

            State = UpdateClientState.UpdatingFiles;

            // Add the sources to the DownloadManager
            var sources = info.DownloadSources.Select(x => x.Instantiate());
            _dm.AddSources(sources);

            // Enqueue the files that need to be downloaded
            _dm.Enqueue(toUpdate);
        }
Пример #4
0
        /// <summary>
        /// The callback method for the <see cref="IMasterServerReader.BeginReadVersion"/>.
        /// </summary>
        /// <param name="sender">The <see cref="IMasterServerReader"/> this event came from.</param>
        /// <param name="info">The information from the master server(s).</param>
        /// <param name="userState">An optional state object passed by the caller to supply information to the callback method
        /// from the method call.</param>
        void MasterServerReader_Callback(IMasterServerReader sender, IMasterServerReadInfo info, object userState)
        {
            State = UpdateClientState.ReadingLiveVersionDone;

            // Check for errors
            if (info.Error != null)
            {
                HasErrors = true;

                // Raise error event
                try
                {
                    if (MasterServerReaderError != null)
                        MasterServerReaderError(this, info.Error);
                }
                catch (NullReferenceException ex)
                {
                    Debug.Fail(ex.ToString());
                }

                // Change the state
                State = UpdateClientState.Completed;

                // Set to not running
                lock (_isRunningSync)
                {
                    Debug.Assert(_isRunning);

                    _isRunning = false;

                    try
                    {
                        if (IsRunningChanged != null)
                            IsRunningChanged(this);
                    }
                    catch (NullReferenceException ex)
                    {
                        Debug.Fail(ex.ToString());
                    }
                }

                return;
            }

            // Set the found live version
            LiveVersion = info.Version;

            // Check if the live version equals our version and, if so, there is no need to continue with the update process
            var currentVersion = Settings.GetCurrentVersion();
            if (currentVersion.HasValue && currentVersion.Value == LiveVersion.Value)
            {
                // Change the state
                State = UpdateClientState.Completed;

                // Set to not running
                lock (_isRunningSync)
                {
                    Debug.Assert(_isRunning);

                    _isRunning = false;

                    try
                    {
                        if (IsRunningChanged != null)
                            IsRunningChanged(this);
                    }
                    catch (NullReferenceException ex)
                    {
                        Debug.Fail(ex.ToString());
                    }
                }

                return;
            }

            // Grab the VersionFileList
            State = UpdateClientState.ReadingLiveVersionFileList;

            _msr.BeginReadVersionFileList(MasterServerReader_Callback_VersionFileList, info.Version, this);
        }
Пример #5
0
        /// <summary>
        /// Runs the clean-up routines.
        /// </summary>
        void Cleanup()
        {
            State = UpdateClientState.CleaningUp;

            // Delete files from the update process
            try
            {
                if (_versionFileList != null)
                {
                    if (Directory.Exists(Settings.TargetPath))
                    {
                        var ffc = FileFilterHelper.CreateCollection(_versionFileList.Filters);
                        if (ffc.Count > 0)
                        {
                            var pathTrimLen = Settings.TargetPath.Length;
                            if (!Settings.TargetPath.EndsWith(Path.DirectorySeparatorChar.ToString()) &&
                                !Settings.TargetPath.EndsWith(Path.AltDirectorySeparatorChar.ToString()))
                                pathTrimLen++;

                            var files = Directory.GetFiles(Settings.TargetPath);
                            foreach (var f in files)
                            {
                                var relativePath = f.Substring(pathTrimLen);

                                try
                                {
                                    if (_versionFileList.ContainsFile(relativePath))
                                        continue;

                                    if (ffc.IsMatch("\\" + relativePath))
                                    {
                                        if (log.IsDebugEnabled)
                                            log.DebugFormat(
                                                "Skipping deleting outdated client file `{0}` - matches one or more delete skip filters.",
                                                f);
                                        continue;
                                    }

                                    if (log.IsInfoEnabled)
                                        log.InfoFormat("Deleting outdated client file: {0}", f);

                                    File.Delete(f);
                                }
                                catch (Exception ex)
                                {
                                    const string errmsg =
                                        "Unexpected error while checking if file `{0}` should be deleted. Exception: {1}";
                                    if (log.IsErrorEnabled)
                                        log.ErrorFormat(errmsg, f, ex);
                                    Debug.Fail(string.Format(errmsg, f, ex));
                                }
                            }
                        }
                    }
                }
                else
                {
                    const string errmsg = "_versionFileList was null, but wasn't expected to be.";
                    if (log.IsErrorEnabled)
                        log.Error(errmsg);
                    Debug.Fail(errmsg);
                }
            }
            catch (Exception ex)
            {
                const string errmsg = "Failed to delete old files. Exception: {0}";
                if (log.IsErrorEnabled)
                    log.ErrorFormat(errmsg, ex);
                Debug.Fail(string.Format(errmsg, ex));
            }

            // Delete temp files
            try
            {
                if (Directory.Exists(Settings.TempPath))
                {
                    var tempFiles = Directory.GetFiles(Settings.TempPath);

                    // Delete each file individually first, even though Directory.Delete can do this, just to make sure that
                    // we delete as much as we possibly can if there are errors
                    foreach (var f in tempFiles)
                    {
                        try
                        {
                            if (log.IsDebugEnabled)
                                log.DebugFormat("Deleting temp file `{0}`.", f);
                            File.Delete(f);
                        }
                        catch (Exception ex)
                        {
                            const string errmsg = "Failed to delete temporary file `{0}`. Exception: {1}";
                            Debug.Fail(string.Format(errmsg, f, ex));
                        }
                    }

                    // Delete the directory
                    if (log.IsDebugEnabled)
                        log.DebugFormat("Deleting directory `{0}`.", Settings.TempPath);
                    Directory.Delete(Settings.TempPath, true);
                }
            }
            catch (Exception ex)
            {
                const string errmsg = "Failed to delete temp files from path `{0}`. Exception: {1}";
                if (log.IsErrorEnabled)
                    log.ErrorFormat(errmsg, Settings.TempPath, ex);
                Debug.Fail(string.Format(errmsg, Settings.TempPath, ex));
            }
        }
Пример #6
0
        /// <summary>
        /// Checks if the downloading with the <see cref="DownloadManager"/> has been completed.
        /// </summary>
        void CheckIfDownloadManagerComplete()
        {
            // If the download manager is null, then skip checking it
            if (_dm != null)
            {
                if (!_dm.IsDisposed)
                {
                    // Do not continue if items are still enqueued for download
                    if (_dm.QueueCount > 0)
                    {
                        const string errmsg = "CheckIfDownloadManagerComplete() called, but items still in the download queue?";
                        if (log.IsWarnEnabled)
                            log.Warn(errmsg);
                        Debug.Fail(errmsg);
                        return;
                    }

                    // Clean up
                    try
                    {
                        _dm.Dispose();
                    }
                    catch (Exception ex)
                    {
                        const string errmsg = "Failed to dispose DownloadManager `{0}`. Reason: {1}";
                        if (log.IsWarnEnabled)
                            log.WarnFormat(errmsg, _dm, ex);
                        Debug.Fail(string.Format(errmsg, _dm, ex));
                    }
                }

                _dm = null;
            }

            // Abort if HasErrors is true
            if (HasErrors)
            {
                State = UpdateClientState.Completed;
                return;
            }

            // Clean up
            Cleanup();

            // If done, update the version
            TrySetClientVersionToLive();

            // Change the state
            State = UpdateClientState.Completed;

            // Set to not running
            lock (_isRunningSync)
            {
                Debug.Assert(_isRunning);

                _isRunning = false;

                try
                {
                    if (IsRunningChanged != null)
                        IsRunningChanged(this);
                }
                catch (NullReferenceException ex)
                {
                    Debug.Fail(ex.ToString());
                }
            }
        }
Пример #7
0
 void _uc_StateChanged(UpdateClient sender, UpdateClientState oldState, UpdateClientState newState)
 {
     LogLine("State changed: " + newState);
 }
Пример #8
0
        /// <summary>
        /// The callback method for the <see cref="IMasterServerReader.BeginReadVersionFileList"/>.
        /// </summary>
        /// <param name="sender">The <see cref="IMasterServerReader"/> this event came from.</param>
        /// <param name="info">The information from the master server(s).</param>
        /// <param name="userState">An optional state object passed by the caller to supply information to the callback method
        /// from the method call.</param>
        void MasterServerReader_Callback_VersionFileList(IMasterServerReader sender, IMasterServerReadInfo info, object userState)
        {
            State = UpdateClientState.ReadingLiveVersionFileListDone;

            // Check for a valid VersionFileList
            if (string.IsNullOrEmpty(info.VersionFileListText))
            {
                const string errmsg =
                    "Could not get a valid VersionFileList file from the master servers for version `{0}` - download failed.";

                if (log.IsErrorEnabled)
                {
                    log.ErrorFormat(errmsg, info.Version);
                }

                if (MasterServerReaderError != null)
                {
                    MasterServerReaderError(this, string.Format(errmsg, info.Version));
                }

                HasErrors = true;
                return;
            }

            try
            {
                _versionFileList = VersionFileList.CreateFromString(info.VersionFileListText);
            }
            catch (Exception ex)
            {
                const string errmsg =
                    "Could not get a valid VersionFileList file from the master servers for version `{0}`. Exception: {1}";

                if (log.IsErrorEnabled)
                {
                    log.ErrorFormat(errmsg, info.Version, ex);
                }

                if (MasterServerReaderError != null)
                {
                    MasterServerReaderError(this, string.Format(errmsg, info.Version, ex));
                }

                HasErrors = true;
                return;
            }

            // Find the files to update
            var toUpdate = FindFilesToUpdate(_versionFileList);

            // If all file hashes match, then we are good to go
            if (toUpdate.Count() == 0)
            {
                CheckIfDownloadManagerComplete();
                return;
            }

            // There was one or more files to update, so start the updating...

            // Create the DownloadManager
            _dm = new DownloadManager(Settings.TargetPath, Settings.TempPath, info.Version);
            _dm.DownloadFinished += DownloadManager_DownloadFinished;
            _dm.FileMoveFailed   += DownloadManager_FileMoveFailed;
            _dm.DownloadFailed   += DownloadManager_DownloadFailed;
            _dm.Finished         += DownloadManager_Finished;

            State = UpdateClientState.UpdatingFiles;

            // Add the sources to the DownloadManager
            var sources = info.DownloadSources.Select(x => x.Instantiate());

            _dm.AddSources(sources);

            // Enqueue the files that need to be downloaded
            _dm.Enqueue(toUpdate);
        }
Пример #9
0
        /// <summary>
        /// The callback method for the <see cref="IMasterServerReader.BeginReadVersion"/>.
        /// </summary>
        /// <param name="sender">The <see cref="IMasterServerReader"/> this event came from.</param>
        /// <param name="info">The information from the master server(s).</param>
        /// <param name="userState">An optional state object passed by the caller to supply information to the callback method
        /// from the method call.</param>
        void MasterServerReader_Callback(IMasterServerReader sender, IMasterServerReadInfo info, object userState)
        {
            State = UpdateClientState.ReadingLiveVersionDone;

            // Check for errors
            if (info.Error != null)
            {
                HasErrors = true;

                // Raise error event
                try
                {
                    if (MasterServerReaderError != null)
                    {
                        MasterServerReaderError(this, info.Error);
                    }
                }
                catch (NullReferenceException ex)
                {
                    Debug.Fail(ex.ToString());
                }

                // Change the state
                State = UpdateClientState.Completed;

                // Set to not running
                lock (_isRunningSync)
                {
                    Debug.Assert(_isRunning);

                    _isRunning = false;

                    try
                    {
                        if (IsRunningChanged != null)
                        {
                            IsRunningChanged(this);
                        }
                    }
                    catch (NullReferenceException ex)
                    {
                        Debug.Fail(ex.ToString());
                    }
                }

                return;
            }

            // Set the found live version
            LiveVersion = info.Version;

            // Check if the live version equals our version and, if so, there is no need to continue with the update process
            var currentVersion = Settings.GetCurrentVersion();

            if (currentVersion.HasValue && currentVersion.Value == LiveVersion.Value)
            {
                // Change the state
                State = UpdateClientState.Completed;

                // Set to not running
                lock (_isRunningSync)
                {
                    Debug.Assert(_isRunning);

                    _isRunning = false;

                    try
                    {
                        if (IsRunningChanged != null)
                        {
                            IsRunningChanged(this);
                        }
                    }
                    catch (NullReferenceException ex)
                    {
                        Debug.Fail(ex.ToString());
                    }
                }

                return;
            }

            // Grab the VersionFileList
            State = UpdateClientState.ReadingLiveVersionFileList;

            _msr.BeginReadVersionFileList(MasterServerReader_Callback_VersionFileList, info.Version, this);
        }
Пример #10
0
        /// <summary>
        /// Runs the clean-up routines.
        /// </summary>
        void Cleanup()
        {
            State = UpdateClientState.CleaningUp;

            // Delete files from the update process
            try
            {
                if (_versionFileList != null)
                {
                    if (Directory.Exists(Settings.TargetPath))
                    {
                        var ffc = FileFilterHelper.CreateCollection(_versionFileList.Filters);
                        if (ffc.Count > 0)
                        {
                            var pathTrimLen = Settings.TargetPath.Length;
                            if (!Settings.TargetPath.EndsWith(Path.DirectorySeparatorChar.ToString()) &&
                                !Settings.TargetPath.EndsWith(Path.AltDirectorySeparatorChar.ToString()))
                            {
                                pathTrimLen++;
                            }

                            var files = Directory.GetFiles(Settings.TargetPath);
                            foreach (var f in files)
                            {
                                var relativePath = f.Substring(pathTrimLen);

                                try
                                {
                                    if (_versionFileList.ContainsFile(relativePath))
                                    {
                                        continue;
                                    }

                                    if (ffc.IsMatch("\\" + relativePath))
                                    {
                                        if (log.IsDebugEnabled)
                                        {
                                            log.DebugFormat(
                                                "Skipping deleting outdated client file `{0}` - matches one or more delete skip filters.",
                                                f);
                                        }
                                        continue;
                                    }

                                    if (log.IsInfoEnabled)
                                    {
                                        log.InfoFormat("Deleting outdated client file: {0}", f);
                                    }

                                    File.Delete(f);
                                }
                                catch (Exception ex)
                                {
                                    const string errmsg =
                                        "Unexpected error while checking if file `{0}` should be deleted. Exception: {1}";
                                    if (log.IsErrorEnabled)
                                    {
                                        log.ErrorFormat(errmsg, f, ex);
                                    }
                                    Debug.Fail(string.Format(errmsg, f, ex));
                                }
                            }
                        }
                    }
                }
                else
                {
                    const string errmsg = "_versionFileList was null, but wasn't expected to be.";
                    if (log.IsErrorEnabled)
                    {
                        log.Error(errmsg);
                    }
                    Debug.Fail(errmsg);
                }
            }
            catch (Exception ex)
            {
                const string errmsg = "Failed to delete old files. Exception: {0}";
                if (log.IsErrorEnabled)
                {
                    log.ErrorFormat(errmsg, ex);
                }
                Debug.Fail(string.Format(errmsg, ex));
            }

            // Delete temp files
            try
            {
                if (Directory.Exists(Settings.TempPath))
                {
                    var tempFiles = Directory.GetFiles(Settings.TempPath);

                    // Delete each file individually first, even though Directory.Delete can do this, just to make sure that
                    // we delete as much as we possibly can if there are errors
                    foreach (var f in tempFiles)
                    {
                        try
                        {
                            if (log.IsDebugEnabled)
                            {
                                log.DebugFormat("Deleting temp file `{0}`.", f);
                            }
                            File.Delete(f);
                        }
                        catch (Exception ex)
                        {
                            const string errmsg = "Failed to delete temporary file `{0}`. Exception: {1}";
                            Debug.Fail(string.Format(errmsg, f, ex));
                        }
                    }

                    // Delete the directory
                    if (log.IsDebugEnabled)
                    {
                        log.DebugFormat("Deleting directory `{0}`.", Settings.TempPath);
                    }
                    Directory.Delete(Settings.TempPath, true);
                }
            }
            catch (Exception ex)
            {
                const string errmsg = "Failed to delete temp files from path `{0}`. Exception: {1}";
                if (log.IsErrorEnabled)
                {
                    log.ErrorFormat(errmsg, Settings.TempPath, ex);
                }
                Debug.Fail(string.Format(errmsg, Settings.TempPath, ex));
            }
        }
Пример #11
0
        /// <summary>
        /// Checks if the downloading with the <see cref="DownloadManager"/> has been completed.
        /// </summary>
        void CheckIfDownloadManagerComplete()
        {
            // If the download manager is null, then skip checking it
            if (_dm != null)
            {
                if (!_dm.IsDisposed)
                {
                    // Do not continue if items are still enqueued for download
                    if (_dm.QueueCount > 0)
                    {
                        const string errmsg = "CheckIfDownloadManagerComplete() called, but items still in the download queue?";
                        if (log.IsWarnEnabled)
                        {
                            log.Warn(errmsg);
                        }
                        Debug.Fail(errmsg);
                        return;
                    }

                    // Clean up
                    try
                    {
                        _dm.Dispose();
                    }
                    catch (Exception ex)
                    {
                        const string errmsg = "Failed to dispose DownloadManager `{0}`. Reason: {1}";
                        if (log.IsWarnEnabled)
                        {
                            log.WarnFormat(errmsg, _dm, ex);
                        }
                        Debug.Fail(string.Format(errmsg, _dm, ex));
                    }
                }

                _dm = null;
            }

            // Abort if HasErrors is true
            if (HasErrors)
            {
                State = UpdateClientState.Completed;
                return;
            }

            // Clean up
            Cleanup();

            // If done, update the version
            TrySetClientVersionToLive();

            // Change the state
            State = UpdateClientState.Completed;

            // Set to not running
            lock (_isRunningSync)
            {
                Debug.Assert(_isRunning);

                _isRunning = false;

                try
                {
                    if (IsRunningChanged != null)
                    {
                        IsRunningChanged(this);
                    }
                }
                catch (NullReferenceException ex)
                {
                    Debug.Fail(ex.ToString());
                }
            }
        }
Пример #12
0
 void _uc_StateChanged(UpdateClient sender, UpdateClientState oldState, UpdateClientState newState)
 {
     LogLine("State changed: " + newState);
 }