diff --git a/AlwaysUpToDate/AlwaysUpToDate.csproj b/AlwaysUpToDate/AlwaysUpToDate.csproj index 30e7be7..abfee60 100644 --- a/AlwaysUpToDate/AlwaysUpToDate.csproj +++ b/AlwaysUpToDate/AlwaysUpToDate.csproj @@ -14,6 +14,7 @@ 1.0.0.4 1.0.0.4 Updater, AutoUpdate, Auto, C# + True diff --git a/AlwaysUpToDate/DownloadManager.cs b/AlwaysUpToDate/DownloadManager.cs index 3c14030..5e54ed9 100644 --- a/AlwaysUpToDate/DownloadManager.cs +++ b/AlwaysUpToDate/DownloadManager.cs @@ -13,22 +13,57 @@ using System.Xml.Serialization; namespace AlwaysUpToDate { + /// + /// Provides automatic update checking, downloading, verification, extraction, and application restart. + /// Periodically polls a remote XML manifest for new versions and manages the full update lifecycle. + /// public class Updater : IDisposable { + /// + /// Represents the method that will handle update progress notifications. + /// + /// The current phase of the update process. + /// The total number of items to process in this step, or if unknown. + /// The number of items processed so far in this step. + /// The progress percentage (0–100), or if is unknown. public delegate void UpdaterChangedHandler(UpdateStep step, long? totalItems, long itemsProcessed, double? progressPercentage); + /// + /// Occurs when progress is made during any phase of the update process. + /// public event UpdaterChangedHandler ProgressChanged; + /// + /// Represents the method that will handle notifications when a non-mandatory update is available. + /// + /// The version string of the available update. + /// An optional URL pointing to the changelog, or if not provided. public delegate void UpdateAvailableHandler(string version, string changelogUrl); + /// + /// Occurs when a non-mandatory update is available. Call to begin downloading. + /// public event UpdateAvailableHandler UpdateAvailable; + /// + /// Represents the method that will handle notifications when no update is available. + /// public delegate void NoUpdateAvailableHandler(); + /// + /// Occurs when the remote manifest version is not newer than the current assembly version. + /// public event NoUpdateAvailableHandler NoUpdateAvailable; + /// + /// Represents the method that will handle exceptions raised during the update process. + /// + /// The exception that occurred. public delegate void ExceptionHandler(Exception exception); + /// + /// Occurs when an exception is caught during update checking, downloading, extraction, or verification. + /// public event ExceptionHandler OnException; private static readonly XmlSerializer manifestSerializer = new XmlSerializer(typeof(UpdateManifest)); @@ -41,17 +76,29 @@ namespace AlwaysUpToDate private int updating; private bool disposed; + /// public Updater(TimeSpan interval, Uri updateInfoUri, bool onlyUpdateOnce = false) : this(interval, updateInfoUri?.ToString(), "./", onlyUpdateOnce) { } + + /// public Updater(TimeSpan interval, Uri updateInfoUri, string installPath = "./", bool onlyUpdateOnce = false) : this(interval, updateInfoUri?.ToString(), installPath, onlyUpdateOnce) { } + /// public Updater(TimeSpan interval, string updateInfoUrl, bool onlyUpdateOnce = false) : this(interval, updateInfoUrl, "./", onlyUpdateOnce) { } + /// + /// Initializes a new instance of the class. + /// + /// The interval between automatic update checks. Use to disable periodic checks. + /// The URL of the remote XML update manifest. + /// The local directory where the update will be extracted. Defaults to the current directory. + /// If , performs a single update check on without subscribing to the periodic timer. + /// or is . public Updater(TimeSpan interval, string updateInfoUrl, string installPath = "./", bool onlyUpdateOnce = false) { this.updateInfoUrl = updateInfoUrl ?? throw new ArgumentNullException(nameof(updateInfoUrl)); @@ -68,6 +115,10 @@ namespace AlwaysUpToDate } } + /// + /// Starts the updater. Performs an immediate update check and, if a periodic interval was configured, begins recurring checks. + /// + /// The updater has been disposed. public void Start() { ThrowIfDisposed(); @@ -79,12 +130,22 @@ namespace AlwaysUpToDate UpdateTimer_Elapsed(null, null); } + /// + /// Stops periodic update checking. Does not cancel an update that is already in progress. + /// + /// The updater has been disposed. public void Stop() { ThrowIfDisposed(); updateTimer.Stop(); } + /// + /// Downloads and installs the available update. This method is typically called from the handler. + /// If an update is already in progress or no update URL is available, the call is ignored. + /// + /// A task that represents the asynchronous update operation. + /// The updater has been disposed. public async Task Update() { ThrowIfDisposed(); @@ -387,12 +448,19 @@ namespace AlwaysUpToDate } } + /// + /// Releases all resources used by the . + /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } + /// + /// Releases the unmanaged resources used by the and optionally releases the managed resources. + /// + /// to release both managed and unmanaged resources; to release only unmanaged resources. protected virtual void Dispose(bool disposing) { if (!disposed) diff --git a/AlwaysUpToDate/UpdateInfo.cs b/AlwaysUpToDate/UpdateInfo.cs index ea789a3..863f3be 100644 --- a/AlwaysUpToDate/UpdateInfo.cs +++ b/AlwaysUpToDate/UpdateInfo.cs @@ -3,76 +3,138 @@ using System.Xml.Serialization; namespace AlwaysUpToDate { + /// + /// Represents the root element of an update manifest XML document. + /// [XmlRoot("updates")] public class UpdateManifest { + /// + /// Gets or sets the list of available update items, one per target OS. + /// [XmlElement("item")] public List Items { get; set; } = new List(); } + /// + /// Represents a single update entry in the manifest, targeting a specific OS. + /// public class UpdateItem { + /// + /// Gets or sets the target operating system for this update. + /// [XmlElement("os")] public TargetOS OS { get; set; } + /// + /// Gets or sets the version string of the update in X.X.X.X format. + /// [XmlElement("version")] public string Version { get; set; } + /// + /// Gets or sets the URL from which the update ZIP file can be downloaded. + /// [XmlElement("url")] public string DownloadUrl { get; set; } + /// + /// Gets or sets an optional URL pointing to a changelog for this update. + /// [XmlElement("changelog")] public string ChangelogUrl { get; set; } + /// + /// Gets or sets a value indicating whether this update is mandatory. + /// When , the update is downloaded and installed immediately without raising . + /// [XmlElement("mandatory")] public bool IsMandatory { get; set; } + /// + /// Gets or sets an optional checksum used to verify the integrity of the downloaded update. + /// [XmlElement("checksum")] public Checksum Checksum { get; set; } } + /// + /// Specifies the hash algorithm used for checksum verification of downloaded updates. + /// public enum HashAlgorithmType { + /// SHA-1 (default). [XmlEnum("sha1")] SHA1, + /// MD5. [XmlEnum("md5")] MD5, + /// SHA-256. [XmlEnum("sha256")] SHA256, + /// SHA-512. [XmlEnum("sha512")] SHA512, } + /// + /// Represents a checksum value and its associated hash algorithm for verifying download integrity. + /// public class Checksum { + /// + /// Gets or sets the hash algorithm used to compute the checksum. Defaults to . + /// [XmlAttribute("algorithm")] public HashAlgorithmType Algorithm { get; set; } + /// + /// Gets or sets the expected hex-encoded hash value of the downloaded file. + /// [XmlText] public string Value { get; set; } } + /// + /// Specifies the target operating system for an update item. + /// public enum TargetOS { + /// Microsoft Windows. [XmlEnum("windows")] Windows, + /// Apple macOS. [XmlEnum("macos")] MacOS, + /// Linux. [XmlEnum("linux")] Linux, } + /// + /// Describes the current phase of the update process, reported via . + /// public enum UpdateStep { + /// The update ZIP file is being downloaded. Progress is measured in bytes. Downloading, + + /// The downloaded file's checksum is being verified against the manifest. VerifyingChecksum, + + /// ZIP entries are being extracted to the install path. Progress is measured in entries. Extracting, + + /// Old files from the previous version are being deleted. Progress is measured in files. CleaningUp, + + /// The updated application is about to be launched. Restarting, } } \ No newline at end of file