nUpdate 5 · API reference

Everything your app calls, on one page.

The public API of nUpdate 5, from the update manager to your own installer window, the file formats and transfer plugins for nUpdate Administration, with examples for the types and main calls. Pick a type or filter by name; the guide on GitHub shows them in context.

enum · nUpdate · package nUpdate

AfterInstall

What happens to the application once the installer has been started. A package can ask for Restart or Close, overriding UpdateManager.DefaultAfterInstall.

Example
manager.DefaultAfterInstall = AfterInstall.KeepRunning; // a service that restarts itself

Values

Restart

The application is closed and started again after the update. The default of UpdateManager.DefaultAfterInstall.

Close

The application is closed and stays closed; the update dialogs tell the user so.

KeepRunning

The application keeps running; the installer waits for nothing. Only the application can choose it, not a package.

attribute · nUpdate · package nUpdate

ApplicationVersionAttribute

Declares the installed version of the application.

Example
// In any file of the application project, after the using directives:
[assembly: ApplicationVersion("2.1.0")]

Usage

[assembly: ApplicationVersion("1.0.0")]

Read by UpdateManager when its constructor gets no currentVersion; the constructor argument wins when both are given.

string Version { get; }

The version as written in the attribute.

enum · nUpdate.Updating · package nUpdate

ArgumentCondition

After which outcome the installer passes an InstallerArgument to the restarted application.

Values

Succeeded

Only after a successful update.

Failed

Only after a failed update.

Always

After every update. The default.

classes · nUpdate.Exceptions · package nUpdate

Exceptions

What the update steps throw besides HttpRequestException and OperationCanceledException. Each has the three constructors of an exception: without arguments, with a message, and with a message and an inner exception.

Example
try
{
    await manager.CheckForUpdatesAsync();
}
catch (HttpRequestException ex)
{
    Console.WriteLine($"The update server cannot be reached: {ex.Message}");
}
catch (InvalidFeedException ex)
{
    Console.WriteLine($"The update feed is broken: {ex.Message}");
}

Types

class InvalidFeedException : Exception

The feed cannot be parsed or is inconsistent, or names a signature algorithm nUpdate does not verify.

class UnsupportedFormatException : Exception

The feed or a package was written in a format this nUpdate does not read.

class InvalidPackageException : Exception

A downloaded package does not match the size or hash in the feed.

class · nUpdate.Updating · package nUpdate

InstallerArgument

A command line argument the installer passes to the application when it restarts it.

Example
manager.Arguments.Add(new InstallerArgument("--updated", ArgumentCondition.Succeeded));
manager.Arguments.Add(new InstallerArgument("--failed", ArgumentCondition.Failed));

// In Main of the restarted application:
if (args.Contains("--updated"))
    ShowWhatsNew();

Members

InstallerArgument(string value, ArgumentCondition when = ArgumentCondition.Always)

Add it to UpdateManager.Arguments.

string Value { get; }

The argument, quoted for the command line when needed.

ArgumentCondition When { get; }

After which outcome it is passed.

enum · nUpdate.Operations · package nUpdate

OperationArea

The parts of the system the operations of a package touch, as PackageFile.Touches lists them.

Example
var touchesRegistry = manager.AvailableUpdates
    .Select(p => p.FindFile(manager.Platform)!)
    .Any(f => f.Touches.Contains(OperationArea.Registry));

Values

Files

Deleting and renaming files.

Registry

Registry keys and values. Windows only.

Processes

Starting and stopping processes.

Services

Starting and stopping services. Windows only.

class · nUpdate.Updating · package nUpdate

PackageFile

The file of a version for one platform, as PackageInfo.Files lists it and PackageInfo.FindFile returns it.

Example
var file = package.FindFile(manager.Platform)!;
Console.WriteLine($"{file.Path}: {file.Size} bytes");
Console.WriteLine($"Touches: {string.Join(", ", file.Touches)}");

Properties

string Platform { get; set; }

The platform it is built for: a runtime identifier such as win-x64, an operating system (win, linux, osx) or any.

string Path { get; set; }

Where to download it: relative to the feed, such as packages/2.2.0/linux.zip, or an absolute URL for a mirror.

long Size { get; set; }

The size in bytes, checked after the download.

string Sha512 { get; set; }

The Base64 SHA-512 hash, checked after the download.

PackageSignature Signature { get; set; }

The RSA-PSS signature, checked by UpdateManager.VerifyAsync.

List<OperationArea> Touches { get; set; }

What the file's operations touch, so the dialog can tell the user before installing.

class · nUpdate.Updating · package nUpdate

PackageInfo

A version in the feed, as AvailableUpdates returns it.

Example
foreach (var package in manager.AvailableUpdates)
{
    var required = package.Necessary ? " (required)" : "";
    Console.WriteLine($"{package.Version} from {package.PublishedAt:d}{required}");
    Console.WriteLine(package.GetChangelog(CultureInfo.CurrentUICulture));
}

Properties

UpdateVersion Version { get; set; }

The version of the package.

DateTimeOffset PublishedAt { get; set; }

When it was published.

bool Necessary { get; set; }

Installed even when a newer version exists.

AfterInstall? AfterInstall { get; set; }

Restart or Close to override UpdateManager.DefaultAfterInstall, or null to leave it to the application. Set in nUpdate Administration.

Dictionary<string, string> Changelog { get; set; }

The changelog per culture name, such as en or de-DE.

List<UpdateVersion> UnsupportedVersions { get; set; }

Installed versions that must not install this one.

RolloutSettings Rollout { get; set; }

The conditions that decide which clients get it, matched any or all.

List<PackageFile> Files { get; set; }

One file per platform, with path, size, SHA-512 hash, signature and what its operations touch.

PackageStatistics? Statistics { get; set; }

Where downloads are reported, or null when the project has no statistics.

Methods

string GetChangelog(CultureInfo culture)

The changelog in the culture, else its parent culture, else English.

// de-CH, else de, else English
var changelog = package.GetChangelog(new CultureInfo("de-CH"));
PackageFile? FindFile(string runtimeIdentifier)

The file for a client: its runtime identifier, else its operating system, else any; null when none fits.

var file = package.FindFile("linux-arm64"); // linux-arm64, else linux, else any
Console.WriteLine(file?.Path); // packages/2.2.0/linux.zip

class · nUpdate.Updating · package nUpdate

PackageSignature

The signature of a PackageFile.

Properties

string Algorithm { get; set; }

rsa-pss-sha512, the only algorithm nUpdate 5 verifies.

string Value { get; set; }

The Base64 signature, made with the project's private key.

const string RsaPssSha512

rsa-pss-sha512, the algorithm of every signature nUpdate writes.

class · nUpdate.Updating · package nUpdate

PackageStatistics

Where the downloads of a package are counted, as the feed describes it. UpdateManager reports downloads there unless ReportDownloads is false.

Properties

string Url { get; set; }

The base URL of the statistics endpoint, relative to the feed or absolute.

bool Enabled { get; set; }

Whether downloads of this package are counted.

class · nUpdate.Updating · package nUpdate

RolloutCondition

A key and value a client must report, or must not report when negated, to receive a version. Values compare case-insensitively.

Members

RolloutCondition(string key, string value, bool negated = false)

Conditions are set in nUpdate Administration; the client only reads them. Also without arguments, for the JSON reader.

string Key { get; set; }

For example Region.

string Value { get; set; }

For example EU.

bool Negated { get; set; }

Whether a client with this value is excluded.

enum · nUpdate.Updating · package nUpdate

RolloutConditionMode

How the positive conditions of RolloutSettings combine.

Values

Any

The client must match at least one positive condition. The default.

All

The client must match every positive condition.

class · nUpdate.Updating · package nUpdate

RolloutSettings

Which clients receive a version, as PackageInfo.Rollout describes it. A version without conditions goes to everyone; a matching negated condition always excludes a client.

Example
foreach (var condition in package.Rollout.Conditions)
    Console.WriteLine($"{(condition.Negated ? "not " : "")}{condition.Key} = {condition.Value}");

Properties

RolloutConditionMode Mode { get; set; }

Whether a client must match any (default) or all of the positive conditions.

List<RolloutCondition> Conditions { get; set; }

The conditions, matched against UpdateManager.RolloutConditions.

enum · nUpdate.Updating · package nUpdate

Stability

The least stable versions a client installs. Each level includes the more stable ones.

Example
manager.MinimumStability = settings.WantsBetas ? Stability.Beta : Stability.Release;

Values

Release

Releases only. The default.

ReleaseCandidate

Release candidates (rc) and releases.

Beta

Betas, release candidates and releases.

Any

Everything, including alphas and labels nUpdate does not know.

class · nUpdate.Updating · package nUpdate

UpdateDownloadProgress

Progress of the download across all packages, reported by DownloadAsync.

Example
var progress = new Progress<UpdateDownloadProgress>(p =>
    Console.Write($"\r{p.BytesReceived / 1024} of {p.TotalBytesToReceive / 1024} KB"));
await manager.DownloadAsync(progress);

Creating

UpdateDownloadProgress(long bytesReceived, long totalBytesToReceive)

UpdateManager.DownloadAsync reports it; create one to test your progress display.

Properties

long BytesReceived { get; }

The bytes downloaded so far.

long TotalBytesToReceive { get; }

The size of all packages.

float Percentage { get; }

0 to 100.

class · nUpdate.Updating · package nUpdate

UpdateManager

Checks for, downloads, verifies and installs updates. Call the steps in order: CheckForUpdatesAsync, DownloadAsync, VerifyAsync, StartInstaller.

Example
using var manager = new UpdateManager(
    new Uri("https://example.com/updates/nupdate.json"), publicKey);
if (await manager.CheckForUpdatesAsync())
{
    await manager.DownloadAsync(progress);
    if (await manager.VerifyAsync())
        manager.StartInstaller(); // closes the app, installs, restarts it
}

Constructor

UpdateManager(Uri feedUri, string publicKey, CultureInfo? culture = null, UpdateVersion? currentVersion = null, UpdateManagerServices? services = null)

feedUri is the absolute URI of the project's nupdate.json, publicKey its PEM public key from nUpdate Administration. Without currentVersion, the [ApplicationVersion] of the entry assembly is used; culture defaults to English.

var manager = new UpdateManager(
    new Uri("https://example.com/updates/nupdate.json"),
    publicKey, // Overview > Copy source in nUpdate Administration
    CultureInfo.CurrentUICulture);
Uri FeedUri { get; }

The feed from the constructor. Also PublicKey.

void Dispose()

Disposes the HttpClient the manager created; one passed in through UpdateManagerServices stays open.

Update steps

Task<bool> CheckForUpdatesAsync(CancellationToken cancellationToken = default)

Downloads the feed and selects the packages for this client: the newest acceptable one plus every necessary one in between. true when there is something to install.

if (await manager.CheckForUpdatesAsync(cancellationToken))
    Console.WriteLine($"{manager.AvailableUpdates.Count} update(s) found");
Task DownloadAsync(IProgress<UpdateDownloadProgress>? progress = null, CancellationToken cancellationToken = default)

Downloads the selected packages into DownloadDirectory and checks each against the size and SHA-512 hash in the feed. Partial files are deleted on failure or cancellation.

var progress = new Progress<UpdateDownloadProgress>(p =>
    Console.Write($"\r{p.Percentage:0} %"));
await manager.DownloadAsync(progress, cancellationToken);
Task<bool> VerifyAsync(CancellationToken cancellationToken = default)

Checks every package's RSA-PSS signature and that its manifest names this project, version and platform. When one fails, all downloads are deleted and the result is false.

if (!await manager.VerifyAsync())
    Console.WriteLine("A package does not carry a valid signature and was deleted.");
bool StartInstaller()

Copies the installer to a temp folder, writes its options and starts it; then closes the application unless AfterInstall is KeepRunning. false when the user declined the UAC prompt.

if (!manager.StartInstaller())
    Console.WriteLine("Updating needs administrator rights."); // UAC declined
void DeleteDownloads()

Deletes the downloaded package files.

manager.DeleteDownloads(); // the user postponed the update

Which updates

Stability MinimumStability { get; set; }

The least stable versions this client installs. Release by default; Beta also installs release candidates and releases.

manager.MinimumStability = Stability.Beta; // betas, release candidates and releases
ISet<string> AcceptedPreReleaseLabels { get; }

Pre-release labels installed regardless of MinimumStability, such as nightly for 2.1.0-nightly.7.

manager.AcceptedPreReleaseLabels.Add("nightly"); // also offer 2.1.0-nightly.7
IDictionary<string, string> RolloutConditions { get; }

What this client is, such as Region = EU, matched against the rollout conditions of each package.

manager.RolloutConditions["Region"] = "EU";
manager.RolloutConditions["Ring"] = "early-adopters";
string Platform { get; }

The runtime identifier of the running process, such as win-x64. A version is offered when it has a file for it, for its operating system or for any.

Console.WriteLine(manager.Platform); // for example linux-arm64

Installer

AfterInstall DefaultAfterInstall { get; set; }

Restart (default), Close or KeepRunning, unless a package asks to restart the application or to leave it closed.

manager.DefaultAfterInstall = AfterInstall.Close;
AfterInstall AfterInstall { get; }

The outcome for AvailableUpdates: Close when one of them asks to leave the application closed, Restart when one asks to restart it, otherwise DefaultAfterInstall.

if (manager.AfterInstall == AfterInstall.Close)
    Console.WriteLine("Start the application again once the update has finished.");
IList<InstallerArgument> Arguments { get; }

Command line arguments for the restarted application, depending on the outcome.

manager.Arguments.Add(new InstallerArgument("--updated", ArgumentCondition.Succeeded));
string? InstallerPath { get; set; }

The installer to start. Defaults to the built-in one in nUpdate.Installer/<rid>/ next to the application. Its whole folder is copied.

manager.InstallerPath = OperatingSystem.IsWindows()
    ? Path.Combine(AppContext.BaseDirectory, "MyInstaller", "MyInstaller.exe")
    : Path.Combine(AppContext.BaseDirectory, "MyInstaller", "MyInstaller");
bool ShowInstallerWindow { get; set; }

true by default. Without a display the installer runs without a window anyway.

manager.ShowInstallerWindow = false; // a tray tool or a service
string? InstallerIcon { get; set; }

A PNG the installer window shows as its icon.

manager.InstallerIcon = Path.Combine(AppContext.BaseDirectory, "Assets", "app-256.png");
string? InstallerAccentColor { get; set; }

The accent colour of the installer window and the Avalonia dialogs, as #RRGGBB or #AARRGGBB.

manager.InstallerAccentColor = "#2E7D32";
bool RunInstallerAsAdmin { get; set; }

Ask for administrator rights through UAC. true by default; only on Windows.

manager.RunInstallerAsAdmin = false; // installed per user, no UAC prompt
string? ApplicationExecutablePath { get; set; }

The absolute path of the executable the installer restarts; its folder is the one that is updated. Taken from the running process, single-file builds included. Set it when that fails; an empty or relative path throws ArgumentException.

manager.ApplicationExecutablePath = Environment.ProcessPath;
string ApplicationName { get; set; }

The product name the download folder is named after and the installer shows; the product name of the entry assembly by default.

const string InstallerFolderName

nUpdate.Installer, the folder next to the executable that holds the built-in installer, one sub folder per runtime identifier. Also BuiltInInstallerName, its file name without .exe.

Network, texts and statistics

TimeSpan HttpTimeout { get; set; }

The timeout of every request, 100 seconds by default.

manager.HttpTimeout = TimeSpan.FromSeconds(30);
IWebProxy? Proxy { get; set; }

A proxy for all requests. Set it before the first check.

manager.Proxy = new WebProxy("http://proxy.example.com:8080")
{
    Credentials = CredentialCache.DefaultCredentials,
};
ICredentials? HttpAuthenticationCredentials { get; set; }

For a feed behind HTTP authentication. Set it before the first check.

manager.HttpAuthenticationCredentials = new NetworkCredential("updates", "secret");
CultureInfo Culture { get; set; }

The language of the texts, falling back to the parent culture, then to English.

manager.Culture = new CultureInfo("de-CH"); // Swiss German texts
IDictionary<CultureInfo, string> TextFiles { get; }

Text files for further languages. Register them before setting Culture.

var french = new CultureInfo("fr-FR");
manager.TextFiles[french] =
    Path.Combine(AppContext.BaseDirectory, "Localization", "fr-FR.json");
manager.Culture = french;
UpdateTexts Texts { get; }

The texts of the current Culture, which the dialogs and the installer show. Setting Culture loads them anew, so change single texts afterwards.

bool ReportDownloads { get; set; }

Report downloads to the project's statistics. true by default; a failed report never fails the update.

manager.ReportDownloads = settings.AllowUsageStatistics;

Results

IReadOnlyList<PackageInfo> AvailableUpdates { get; }

The packages the last check selected, in installation order.

foreach (var package in manager.AvailableUpdates)
    Console.WriteLine(package.Version);
long TotalDownloadSize { get; }

Their total size in bytes.

Console.WriteLine($"{manager.TotalDownloadSize / 1024.0 / 1024.0:0.0} MB");
IReadOnlyDictionary<UpdateVersion, string> DownloadedPackages { get; }

The downloaded package files by version.

string DownloadDirectory { get; }

Where the packages are downloaded: <temp>/nUpdate/<application>.

UpdateVersion CurrentVersion { get; }

The installed version.

class · nUpdate.Updating · package nUpdate

UpdateManagerServices

The dependencies of UpdateManager, each with a production default. Replace them to test your update code without network or disk.

Example
using var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole());
var services = new UpdateManagerServices
{
    Logger = loggerFactory.CreateLogger("nUpdate"),
};
using var manager = new UpdateManager(feedUri, publicKey, services: services);

Properties

HttpClient? HttpClient { get; set; }

Your own client; otherwise the manager creates one from its proxy and credential settings.

var services = new UpdateManagerServices
{
    HttpClient = httpClientFactory.CreateClient("updates"),
};
IFileSystem FileSystem { get; set; }

The file system, from System.IO.Abstractions.

ILogger Logger { get; set; }

Receives what is not worth failing an update for, such as a statistics report that could not be delivered.

IApplicationTerminator ApplicationTerminator { get; set; }

Closes the application once the installer has started.

ISystemInformation SystemInformation { get; set; }

The operating system name and the runtime identifier.

IApplicationInfo ApplicationInfo { get; set; }

The product name, executable path and declared version of the application.

IProcessLauncher ProcessLauncher { get; set; }

Starts the installer, elevated on request.

IFilePermissions FilePermissions { get; set; }

The write check and Unix file modes on Linux and macOS.

class · nUpdate.Localization · package nUpdate

UpdateTexts

The texts of the dialogs and the installer, as UpdateManager.Texts. Every property has an English default, so a text file in UpdateManager.TextFiles may contain only some of them: a JSON object with these names, like en.json in the repository.

Example
manager.Culture = new CultureInfo("en");
manager.Texts.NoUpdatesTitle = "Aurora is up to date.";

Properties, with their English default

string Cancel { get; set; }

Cancel

string Close { get; set; }

Close

string Install { get; set; }

Install

string Searching { get; set; }

Searching for updates...

string NewUpdatesTitle { get; set; }

{0} new updates available.

string NewUpdateTitle { get; set; }

{0} new update available.

string NewUpdateInfo { get; set; }

New updates can be downloaded for {0}.

string AvailableVersions { get; set; }

Available versions: {0}

string CurrentVersion { get; set; }

Current version: {0}

string TotalSize { get; set; }

Total package size: {0}

string Changelog { get; set; }

Changelog:

string Touches { get; set; }

Accesses:

string TouchesRegistry { get; set; }

Registry

string TouchesFiles { get; set; }

File system

string TouchesProcesses { get; set; }

Processes

string TouchesServices { get; set; }

Services

string StaysClosedAfterUpdate { get; set; }

{0} stays closed after the update.

string NoUpdatesTitle { get; set; }

There are no new updates available.

string NoUpdatesInfo { get; set; }

The application is currently up-to-date.

string Downloading { get; set; }

Downloading updates...

string DownloadingInfo { get; set; }

Please wait while the available updates are\ndownloaded... ({0}%)

string DownloadError { get; set; }

Error while downloading the update packages.

string InstallerExtracting { get; set; }

Extracting files...

string InstallerCopying { get; set; }

Copying {0}...

string InstallerInitializingError { get; set; }

Error while initializing the installer.

string InstallerUpdatingError { get; set; }

Error while updating the application.

string InstallerFileInUse { get; set; }

The installer cannot overwrite the file '{0}' because it is being used by another process. Close the applications that block it and try again.

string RenamingFile { get; set; }

Renaming file \"{0}\" to \"{1}\"...

string DeletingFile { get; set; }

Deleting file \"{0}\"...

string CreatingRegistryKey { get; set; }

Creating registry subkey \"{0}\"...

string DeletingRegistryKey { get; set; }

Deleting registry subkey \"{0}\"...

string SettingRegistryValue { get; set; }

Setting value of \"{0}\" in the registry to \"{1}\"...

string DeletingRegistryValue { get; set; }

Deleting name-value-pair \"{0}\"...

string StartingProcess { get; set; }

Starting process \"{0}\"...

string TerminatingProcess { get; set; }

Terminating process \"{0}\"...

string StartingService { get; set; }

Starting service \"{0}\"...

string StoppingService { get; set; }

Stopping service \"{0}\"...

string WaitingForProcess { get; set; }

Waiting for \"{0}\" to exit...

string ProcessExitCode { get; set; }

\"{0}\" exited with code {1}.

string InstallerTitle { get; set; }

Updating {0}

string InstallerWaiting { get; set; }

Waiting for {0} to close...

string InstallerRetry { get; set; }

Retry

string InstallerSkip { get; set; }

Skip

string InstallerAbort { get; set; }

Abort

string InstallerLogFile { get; set; }

The log file contains the details: {0}

string SearchError { get; set; }

Error while searching for updates.

string VerificationError { get; set; }

Error while checking the package's signature.

string PackageNotFound { get; set; }

The package file couldn't be found.

string InvalidSignatureTitle { get; set; }

Invalid signature data found.

string InvalidSignatureInfo { get; set; }

nUpdate will cancel the installation of the update packages and delete them unrecoverably.

string InvalidSignatureData { get; set; }

The signature of the update package is not a valid RSA-signature.

string PackageFileNotFound { get; set; }

The update package of version \"{0}\" could not be found.

string NotEnoughDiskSpaceTitle { get; set; }

Not enough disk space.

string NotEnoughDiskSpaceInfo { get; set; }

You don't have enough disk space left on your drive and nUpdate is not able to download and install the available updates ({0}). Please free a minimum of {1} to make sure the updates can be downloaded and installed without any problems.

string InstallerNotFound { get; set; }

The update installer was not found at \"{0}\". Reference the nUpdate.UpdateInstaller.UI.Avalonia package or set InstallerPath to your own installer.

string NoWriteAccess { get; set; }

{0} cannot be updated because this user may not change the files in \"{1}\". Ask an administrator to install the update or to give you write access to the folder.

class · nUpdate.Updating · package nUpdate

UpdateVersion

A semantic version with an optional fourth number: 2.1.0, 2.1.0.4, 1.2.0-beta.1. ToString() returns its one canonical form.

Example
var beta = new UpdateVersion("2.1.0-beta.1");
Console.WriteLine(beta.Release);                      // 2.1.0
Console.WriteLine(beta < new UpdateVersion("2.1.0")); // True

Creating

UpdateVersion(string version)

Parses the canonical form and throws ArgumentException for anything else, such as 1.2 or 1.2b1.

UpdateVersion(int major, int minor, int build, int revision = 0)

A release version from its numbers.

var version = new UpdateVersion(2, 1, 0); // 2.1.0
static bool TryParse(string? version, out UpdateVersion? result)

Parses without throwing.

if (!UpdateVersion.TryParse(input, out var version))
    Console.WriteLine(UpdateVersion.FormatDescription); // how to write a version
static bool IsValid(string? version)

Whether the string is a version in the canonical form.

UpdateVersion(int major, int minor, int build, int revision, string? preRelease, string? buildMetadata)

A version with a pre-release label (beta.1) and build metadata (build.7) as SemVer 2.0 defines them; throws ArgumentException for anything else. Also without arguments, for 0.0.0.

const string FormatDescription

How to write a version, in a sentence for error messages.

Parts and comparison

int Major { get; }

Also Minor, Build and Revision.

string? PreRelease { get; }

The label, such as beta.1, or null for a release.

bool IsPreRelease { get; }

Whether the version has a label.

UpdateVersion Release { get; }

The version without its label and build metadata.

static bool operator <(UpdateVersion? left, UpdateVersion? right)

Ordered like SemVer: alpha < beta < rc < release; build metadata is ignored. Also >, <=, >=, == and !=.

static UpdateVersion Max(IEnumerable<UpdateVersion> versions)

The highest version. Also Min.

var newest = UpdateVersion.Max(manager.AvailableUpdates.Select(p => p.Version));
string? BuildMetadata { get; }

The metadata after +, such as build.7, or null. It plays no part in comparisons.

int CompareTo(UpdateVersion? other)

The order of the operators above. Also Equals(UpdateVersion?) and CompareTo(object?).

override string ToString()

The canonical form: three numbers, the fourth only when it is not 0, then the label and the metadata.

interface · nUpdate.Platform · package nUpdate

IApplicationInfo

Facts about the application, for UpdateManagerServices.ApplicationInfo. The default reads them from the entry assembly and the running process.

Members

string ProductName { get; }

The product name, used for the temp folders and shown by the installer.

string? ExecutablePath { get; }

The full path of the executable, or null when it cannot be determined.

string? DeclaredVersion { get; }

The version declared with ApplicationVersionAttribute, or null.

string UserAgentProduct { get; }

The assembly name and version used for the HTTP user agent.

int CurrentProcessId { get; }

The process the installer waits for.

interface · nUpdate.Platform · package nUpdate

IApplicationTerminator

Closes the application so the installer can replace its files, for UpdateManagerServices.ApplicationTerminator. The default calls Environment.Exit(0).

Example
// Let the application close cleanly instead of ending it with Environment.Exit.
sealed class GracefulTerminator(Action shutdown) : IApplicationTerminator
{
    public void Terminate() => shutdown();
}

Members

void Terminate()

Called by UpdateManager.StartInstaller once the installer has started, unless AfterInstall is KeepRunning.

interface · nUpdate.Platform · package nUpdate

IFilePermissions

File permissions as Linux and macOS know them, for UpdateManagerServices.FilePermissions.

Members

bool CanWrite(string directory)

Whether the current user may create and delete files in the folder; checked before the installer starts.

void SetMode(string path, int mode)

Sets the Unix permission bits, such as 0755 for the installer. Does nothing on Windows.

interface · nUpdate.Platform · package nUpdate

IProcessLauncher

Starts the installer, for UpdateManagerServices.ProcessLauncher.

Members

bool Start(string fileName, string arguments, bool elevated)

Starts the executable, through UAC when elevated (Windows only). false when the user declined the prompt; any other failure throws.

interface · nUpdate.Platform · package nUpdate

ISystemInformation

Facts about the machine, for UpdateManagerServices.SystemInformation.

Members

string OperatingSystemName { get; }

A display name such as Windows 11, sent with the download statistics.

string RuntimeIdentifier { get; }

The runtime identifier of the running process, such as win-x64; what UpdateManager.Platform returns.

interface · nUpdate.Ui · package nUpdate

IUpdateFlowPresenter

The dialogs an UpdateFlow shows. Every member is called on the thread that started the flow.

Example
sealed class ConsolePresenter(UpdateManager manager) : IUpdateFlowPresenter
{
    public Task<bool> RunSearchAsync(Func<CancellationToken, Task<bool>> search) =>
        search(CancellationToken.None);

    public Task ShowNoUpdatesAsync()
    {
        Console.WriteLine("You are up to date.");
        return Task.CompletedTask;
    }

    public Task<bool> ConfirmInstallAsync()
    {
        if (manager.AfterInstall == AfterInstall.Close) // the application does not start again after this update
            Console.WriteLine(string.Format(manager.Texts.StaysClosedAfterUpdate, manager.ApplicationName));
        Console.Write("Install the updates now? [y/N] ");
        return Task.FromResult(Console.ReadLine()?.Trim() == "y");
    }

    public Task RunDownloadAsync(
        Func<IProgress<UpdateDownloadProgress>, CancellationToken, Task> download)
    {
        var progress = new Progress<UpdateDownloadProgress>(p =>
            Console.Write($"\r{p.Percentage:0} %"));
        return download(progress, CancellationToken.None);
    }

    public Task ShowErrorAsync(UpdateErrorMessage message, Exception? exception)
    {
        Console.Error.WriteLine($"{message.Caption}: {message.Text}");
        return Task.CompletedTask;
    }
}

Members

Task<bool> RunSearchAsync(Func<CancellationToken, Task<bool>> search)

Shows the search while it runs; cancelling the dialog cancels the search.

Task ShowNoUpdatesAsync()

Tells the user that the application is up to date.

Task<bool> ConfirmInstallAsync()

Shows the updates with their changelog and, when UpdateManager.AfterInstall is Close, that the application stays closed (UpdateTexts.StaysClosedAfterUpdate); true to install them.

Task RunDownloadAsync(Func<IProgress<UpdateDownloadProgress>, CancellationToken, Task> download)

Shows the download with its progress; cancelling cancels it.

Task ShowErrorAsync(UpdateErrorMessage message, Exception? exception)

Shows an error, with the exception for a details view.

class · nUpdate.Ui · package nUpdate

UpdateErrorMessage

An error as the dialogs show it, passed to IUpdateFlowPresenter.ShowErrorAsync. The texts come from the client's language.

Example
// In your IUpdateFlowPresenter
public Task ShowErrorAsync(UpdateErrorMessage message, Exception? exception)
{
    Console.Error.WriteLine($"{message.Caption}: {message.Text}");
    return Task.CompletedTask;
}

Members

UpdateErrorMessage(string caption, string text)

The flow creates it; your presenter only shows it.

string Caption { get; }

What failed, such as the search or the download.

string Text { get; }

Why it failed.

class · nUpdate.Ui · package nUpdate

UpdateFlow

The update process behind the built-in dialogs. Drive it with your own dialogs through IUpdateFlowPresenter.

Example
var flow = new UpdateFlow(manager, new ConsolePresenter(manager)) { UseHiddenSearch = true };
var result = await flow.RunAsync();

Members

UpdateFlow(UpdateManager manager, IUpdateFlowPresenter presenter, IFileSystem? fileSystem = null)

The file system is used for the disk space check before the download.

bool UseHiddenSearch { get; set; }

Search without a dialog and show nothing when the application is up to date.

bool IsRunning { get; }

Whether a run is in progress.

Task<UpdateFlowResult> RunAsync(CancellationToken cancellationToken = default)

Runs the whole process once, showing every dialog through the presenter on the calling thread.

enum · nUpdate.Ui · package nUpdate

UpdateFlowResult

How a run of the update flow ended.

Example
switch (await updaterUI.RunAsync())
{
    case UpdateFlowResult.InvalidSignature:
        logger.LogWarning("An update package was not signed with our key.");
        break;
    case UpdateFlowResult.InsufficientDiskSpace:
        ScheduleRetry();
        break;
}

Values

InstallerStarted

The installer was started; the application is being closed when configured to.

NoUpdates

The application is up to date.

Declined

The user did not want to install the updates.

Cancelled

The user cancelled the search or the download.

InsufficientDiskSpace

The temp drive cannot hold the packages; the user was told how much to free.

InvalidSignature

A downloaded package did not carry a valid signature and was deleted.

ElevationDeclined

The user declined the UAC prompt of the installer.

Failed

A step failed; the error was shown to the user.

AlreadyRunning

Another run was still in progress; nothing happened.

class · nUpdate.UI.WindowsForms · .WPF · .Avalonia · package nUpdate.UI.*

UpdaterUI

Runs the whole update with the built-in dialogs. Create and use it on the UI thread.

Example
// Windows Forms: in the Shown event of the main form. WPF and Avalonia work the same.
var updaterUI = new UpdaterUI(manager, this) { UseHiddenSearch = true };
var result = await updaterUI.RunAsync();

Members

UpdaterUI(UpdateManager updateManager, Window? owner = null)

The owner is an IWin32Window in Windows Forms and a Window in WPF and Avalonia; the dialogs are modal to it.

bool UseHiddenSearch { get; set; }

Search in the background and say nothing when the application is up to date.

Task<UpdateFlowResult> RunAsync(CancellationToken cancellationToken = default)

Searches, asks, downloads, verifies and starts the installer.

if (await updaterUI.RunAsync() == UpdateFlowResult.InstallerStarted)
    return; // the application is about to close

class · nUpdate.Installer · package nUpdate

ApplicationOptions

The application that is updated, as InstallerOptions.Application.

Example
var application = Session.Options.Application;
Console.WriteLine($"{application.Name} in {application.ProgramDirectory}");

Properties

string Name { get; set; }

The name of the application, as in the window title.

string Directory { get; set; }

The folder of the application's executable.

string ExecutablePath { get; set; }

The executable the installer restarts.

string? Bundle { get; set; }

The macOS application bundle (…/MyApp.app) the executable lives in, or null.

string ProgramDirectory { get; }

What %program% and the Program root stand for: the bundle when there is one, else Directory.

Console.WriteLine(options.Application.ProgramDirectory); // /Applications/Aurora.app

class · nUpdate.Installer · package nUpdate

HostOptions

The running application and what happens to it, as InstallerOptions.Host.

Properties

int? ProcessId { get; set; }

The process the installer waits for before it replaces files, or null when the application keeps running.

AfterInstall AfterInstall { get; set; }

What happens to the application after the update: UpdateManager.AfterInstall, which a package can set to Restart or Close.

static class · nUpdate.UpdateInstaller · package nUpdate.UpdateInstaller

InstallerHost

The entry point of every installer executable, the built-in one and yours.

Example
// Program.cs of your installer
[STAThread]
static int Main(string[] args) =>
    InstallerHost.Run(args, session => new MyWindow(session));

Members

static int Run(string[] args, Func<InstallerSession, IProgressReporter> createWindow, InstallerServices? services = null)

Reads the options, shows your window (or none without a display, or when it fails), installs and returns the exit code.

const int Succeeded = 0

Also Failed (1) and CouldNotStart (2) when the options cannot be read.

const string LogFileName = "install.log"

Written next to the options file in the installer's temp folder.

class · nUpdate.Installer · package nUpdate

InstallerOptions

Everything the installer needs to run. UpdateManager.StartInstaller writes it as installer-options.json next to the installer, whose only argument is its path; an installer window reads it as InstallerSession.Options.

Example
// In your installer window (a WindowProgressReporter): what this update is about
var options = Session.Options;
// Texts["WindowTitle"] is "Updating {0}", so this is "Updating Aurora":
var title = options.Text(InstallerText.WindowTitle, options.Application.Name);
var waitsForTheApp = options.Host.ProcessId is not null;
var icon = options.Ui.IconPath; // null: show your own

Contents

List<InstallerPackage> Packages { get; set; }

The downloaded package files, oldest version first. Version and operations come from the manifest inside each package.

ApplicationOptions Application { get; set; }

The application that is updated.

HostOptions Host { get; set; }

The running application and what happens to it.

List<InstallerArgument> Arguments { get; set; }

The arguments for the restarted application, from UpdateManager.Arguments.

InstallerUiOptions Ui { get; set; }

How the installer presents itself.

int Format { get; set; }

The version of this document, CurrentFormat (2). An installer refuses options of a format it does not read.

Texts

Dictionary<string, string> Texts { get; set; }

The installer's texts in the application's language, keyed by InstallerText names, such as "WindowTitle": "Updating {0}". UpdateManager fills it from its Texts.

string Text(InstallerText key, params object[] arguments)

Looks the key's name up in Texts, takes the English default when it is missing, and fills in the arguments with string.Format. Also without arguments, for texts without placeholders.

// Texts["Copying"] is "Copying {0}...", so this is "Copying Aurora.dll...":
var status = options.Text(InstallerText.Copying, "Aurora.dll");

class · nUpdate.Installer · package nUpdate

InstallerPackage

A downloaded package file, as InstallerOptions.Packages lists it.

Properties

string Path { get; set; }

The full path of the downloaded zip.

class · nUpdate.UpdateInstaller · package nUpdate.UpdateInstaller

InstallerServices

The limits of an installer run. Pass them to InstallerHost.Run, for example for an application that takes long to close.

Example
var services = new InstallerServices
{
    HostExitTimeout = TimeSpan.FromMinutes(5), // an application that takes long to close
    MaxLockedFileAttempts = 10,
};
var exitCode = InstallerHost.Run(args, session => new MyWindow(session), services);

Limits

TimeSpan HostExitTimeout { get; set; }

How long to wait for the application to exit before continuing anyway; 2 minutes.

int MaxLockedFileAttempts { get; set; }

How often a file in use is tried before the update is aborted; 5.

class · nUpdate.UpdateInstaller · package nUpdate.UpdateInstaller

InstallerSession

What an installer window gets from InstallerHost.

Example
var options = session.Options;
// Texts["WindowTitle"] with the name filled in: "Updating Aurora"
var title = options.Text(InstallerText.WindowTitle, options.Application.Name);
var log = session.LogFilePath; // for error messages

Creating

InstallerSession(InstallerOptions options, string? logFilePath)

InstallerHost creates the session for your window. Create one yourself to show the window without an update, for example while you design it.

Properties

InstallerOptions Options { get; }

The application, the packages, the window options and the translated texts; see InstallerOptions.

string? LogFilePath { get; }

The install.log of this run, for error messages.

enum · nUpdate.Installer · package nUpdate

InstallerText

The keys of the installer's texts in InstallerOptions.Texts. Each value below shows the English text; {0} and {1} are filled in by InstallerOptions.Text.

Example
var retry = options.Text(InstallerText.RetryButton);           // Retry
var copying = options.Text(InstallerText.Copying, "Aurora.dll"); // Copying Aurora.dll...

Progress

ExtractingFiles

Extracting files...

Copying

Copying {0}...

WaitingForApplication

Waiting for {0} to close...

Operations

FileDeleting

Deleting file "{0}"...

FileRenaming

Renaming file "{0}" to "{1}"...

RegistrySubKeyCreate

Creating registry subkey "{0}"...

RegistrySubKeyDelete

Deleting registry subkey "{0}"...

RegistryValueDelete

Deleting name-value-pair "{0}"...

RegistryValueSet

Setting value of "{0}" in the registry to "{1}"...

ProcessStart

Starting process "{0}"...

ProcessStop

Terminating process "{0}"...

ProcessWaiting

Waiting for "{0}" to exit...

ProcessExitCodeError

"{0}" exited with code {1}.

ServiceStart

Starting service "{0}"...

ServiceStop

Stopping service "{0}"...

Window

WindowTitle

Updating {0}

FileInUseError

The installer cannot overwrite the file '{0}' because it is being used by another process. Close the applications that block it and try again.

RetryButton

Retry

SkipButton

Skip

AbortButton

Abort

CloseButton

Close

UpdatingErrorCaption

Error while updating the application.

InitializingErrorCaption

Error while initializing the installer.

LogFileHint

The log file contains the details: {0}

class · nUpdate.Installer · package nUpdate

InstallerUiOptions

How the installer presents itself, as InstallerOptions.Ui. Filled from the window settings of UpdateManager.

Example
// In your installer window (a WindowProgressReporter)
var icon = Session.Options.Ui.IconPath;      // the application's PNG, or null
var accent = Session.Options.Ui.AccentColor; // such as "#2E7D32", or null

Properties

bool ShowWindow { get; set; }

Whether to show a window, from UpdateManager.ShowInstallerWindow. Without a display there is none anyway.

string? IconPath { get; set; }

The PNG the window shows as its icon, a copy of UpdateManager.InstallerIcon, or null for the nUpdate icon.

string? AccentColor { get; set; }

The accent colour as #RRGGBB or #AARRGGBB, from UpdateManager.InstallerAccentColor, or null for the default.

interface · nUpdate.Installer · package nUpdate

IProgressReporter

The user interface of the installer, as InstallerHost.Run expects it from your window factory. Derive from WindowProgressReporter instead of implementing it yourself: it handles the threads.

Members

void Initialize()

Shows the UI on the main thread and blocks until Terminate. Throws when the UI cannot be shown.

void ReportUnpackingProgress(float progress, string currentFile)

A file was copied; progress is 0 to 100. Called from the engine's thread.

void ReportOperationProgress(float progress, string currentOperation)

An operation ran, or what the installer is doing now.

LockedFileDecision ReportLockedFile(string filePath, int attempt)

A file to replace is in use; asked again with the next attempt after Retry.

void Fail(Exception exception)

The update failed, or it is in place but the application could not be restarted. May block until the user has read it.

void Terminate()

The installer is done; unblocks Initialize.

enum · nUpdate.Installer · package nUpdate

LockedFileDecision

What the installer does with a file another process holds open; the answer a window gives to AskAboutLockedFile.

Example
protected override void AskAboutLockedFile(
    string filePath, Action<LockedFileDecision> answer) =>
    answer(LockedFileDecision.Skip); // keep the old file and go on

Values

Retry

Try to replace the file again. After five attempts the update is aborted.

Skip

Leave the existing file untouched and continue.

Abort

Fail the update.

abstract class · nUpdate.UpdateInstaller · package nUpdate.UpdateInstaller

WindowProgressReporter

The base of an installer window. It hands every report to your UI thread, waits for answers, and throws when the window is gone, so the installer continues without it.

Example
// A minimal WPF window; samples/CustomInstaller is a complete one.
sealed class MyWindow(InstallerSession session) : WindowProgressReporter(session)
{
    private readonly ProgressBar _bar = new() { Maximum = 100, Height = 20 };
    private Window? _window;

    protected override void RunWindow(Action shown)
    {
        _window = new Window { Title = Session.Options.Application.Name };
        _window.Content = _bar;
        _window.Loaded += (_, _) => shown();
        _window.ShowDialog();
    }

    protected override void Post(Action action) =>
        _window!.Dispatcher.InvokeAsync(action);

    protected override void ShowProgress(float progress, string text) =>
        _bar.Value = progress;

    protected override void AskAboutLockedFile(
        string filePath, Action<LockedFileDecision> answer) =>
        answer(LockedFileDecision.Retry);

    protected override void ShowError(Exception exception, Action closed)
    {
        MessageBox.Show(_window!, exception.Message);
        closed();
    }

    protected override void Finish() => _window!.Close();
}

Members

protected WindowProgressReporter(InstallerSession session)

Pass the session that InstallerHost.Run hands to your factory.

InstallerSession Session { get; }

The options and the log path of this run.

To implement

protected abstract void RunWindow(Action shown)

Shows the window, calls shown once it is open and returns when it has closed.

protected abstract void Post(Action action)

Runs an action on the UI thread.

protected abstract void ShowProgress(float progress, string text)

0 to 100, and what the installer is doing.

protected abstract void AskAboutLockedFile(string filePath, Action<LockedFileDecision> answer)

Retry, Skip or Abort for a file another process holds open.

protected abstract void ShowError(Exception exception, Action closed)

Shows the error and calls closed once the user has read it.

protected abstract void Finish()

Closes the window.

Called by the installer

void Initialize()

Opens the window through RunWindow and returns when it has closed.

void ReportUnpackingProgress(float progress, string currentFile)

Shows the progress through ShowProgress. Also ReportOperationProgress.

LockedFileDecision ReportLockedFile(string filePath, int attempt)

Asks through AskAboutLockedFile and waits for the answer.

void Fail(Exception exception)

Shows the error through ShowError and waits until the user has closed it.

void Terminate()

Closes the window through Finish.

void Dispose()

Releases the wait handles. InstallerHost calls these members; your window implements the protected ones above.

abstract class · nUpdate.Operations · package nUpdate

Operation

The base of the operations in a package manifest: an action the installer performs before or after it copies the files. nUpdate Administration writes them and the installer runs them; in JSON, type names the kind.

Example
var migrate = new StartProcessOperation
{
    Path = "%program%/migrate.exe",
    WaitForExit = true,
    FailOnError = true, // a failed migration fails the update
};
Console.WriteLine(migrate.Area);            // Processes
Console.WriteLine(migrate.RequiresWindows); // False

Properties

string Type { get; }

The JSON discriminator, such as deleteFiles.

OperationArea Area { get; }

The part of the system the operation touches.

bool RunBeforeFileReplacement { get; set; }

Whether the operation runs before the files are copied; otherwise after.

bool RequiresWindows { get; }

Whether the operation exists only on Windows: registry and service operations. Packages for other platforms cannot contain them.

Static members

static bool IsWindowsOnly(OperationArea area)

Whether the operations of an area exist only on Windows.

static IReadOnlyDictionary<string, Type> Types { get; }

Every operation class by its discriminator.

classes · nUpdate.Operations · package nUpdate

Operations

The ten kinds of Operation, one class each. Paths may contain the placeholders %program%, %appdata%, %temp% and %desktop%, which the installer expands on the client. Each class has a constant TypeName, its discriminator in JSON.

Example
var operations = new List<Operation>
{
    new DeleteFilesOperation
    {
        Directory = "%program%",
        Files = { "legacy.dll" },
        RunBeforeFileReplacement = true,
    },
    new TerminateProcessOperation { ProcessName = "aurora-helper" },
    new SetRegistryValuesOperation
    {
        Key = @"HKEY_CURRENT_USER\Software\Aurora",
        Values = { RegistryValue.String("Theme", "dark") },
    },
};

DeleteFilesOperation

class DeleteFilesOperation : Operation

Deletes files from a directory. In JSON deleteFiles.

string Directory { get; set; }

The directory, such as %program%/plugins.

List<string> Files { get; set; }

The names of the files in it.

RenameFileOperation

class RenameFileOperation : Operation

Renames one file. In JSON renameFile.

string Path { get; set; }

The file.

string NewName { get; set; }

Its new name.

CreateRegistryKeysOperation

class CreateRegistryKeysOperation : Operation

Creates sub keys below a registry key. Windows only. In JSON createRegistryKeys.

string Key { get; set; }

The key, such as HKEY_CURRENT_USER\Software\Aurora.

List<string> SubKeys { get; set; }

The sub keys to create below it.

DeleteRegistryKeysOperation

class DeleteRegistryKeysOperation : Operation

Deletes sub keys below a registry key. Windows only. In JSON deleteRegistryKeys.

string Key { get; set; }

The key.

List<string> SubKeys { get; set; }

The sub keys to delete, with everything below them.

SetRegistryValuesOperation

class SetRegistryValuesOperation : Operation

Sets values of a registry key. Windows only. In JSON setRegistryValues.

string Key { get; set; }

The key.

List<RegistryValue> Values { get; set; }

The values, each a RegistryValue.

DeleteRegistryValuesOperation

class DeleteRegistryValuesOperation : Operation

Deletes values of a registry key. Windows only. In JSON deleteRegistryValues.

string Key { get; set; }

The key.

List<string> Names { get; set; }

The names of the values.

StartProcessOperation

class StartProcessOperation : Operation

Starts a process. In JSON startProcess.

string Path { get; set; }

The executable.

string Arguments { get; set; }

Its command line.

bool WaitForExit { get; set; }

Whether the installer waits until the process has exited before it continues.

bool FailOnError { get; set; }

Whether an exit code other than 0 fails the update. Only with WaitForExit.

TerminateProcessOperation

class TerminateProcessOperation : Operation

Terminates every process with a name. In JSON terminateProcess.

string ProcessName { get; set; }

The process name.

StartServiceOperation

class StartServiceOperation : Operation

Starts a Windows service. In JSON startService.

string ServiceName { get; set; }

The service.

List<string> Arguments { get; set; }

The arguments the service gets.

StopServiceOperation

class StopServiceOperation : Operation

Stops a Windows service. In JSON stopService.

string ServiceName { get; set; }

The service.

class · nUpdate.Packaging · package nUpdate

PackageManifest

The manifest.json at the root of every package file: whose package it is, its version and platform, and what the installer does besides copying files. UpdateManager.VerifyAsync checks that it names your project and the version the feed promised.

Example
{
  "format": 1,
  "projectId": "5f1e4a8c-3b2d-4c6e-9f10-0123456789ab",
  "version": "2.1.0",
  "platform": "win-x64",
  "createdAt": "2026-10-10T12:00:00+00:00",
  "operations": [
    {
      "type": "deleteFiles",
      "directory": "%program%",
      "files": [
        "legacy.dll"
      ],
      "runBeforeFileReplacement": true
    },
    {
      "type": "startProcess",
      "path": "%program%/migrate.exe",
      "arguments": "",
      "waitForExit": true,
      "failOnError": true,
      "runBeforeFileReplacement": false
    }
  ],
  "codeSignatures": {}
}

Properties

int Format { get; set; }

The version of the document, CurrentFormat (1). nUpdate refuses another format with UnsupportedFormatException.

Guid ProjectId { get; set; }

The project the package belongs to.

UpdateVersion Version { get; set; }

The version the package installs.

string Platform { get; set; }

The platform of the package file: any, an operating system such as linux, or a runtime identifier such as osx-arm64.

DateTimeOffset CreatedAt { get; set; }

When nUpdate Administration built the package.

List<Operation> Operations { get; set; }

The operations, in the order they run.

Dictionary<string, Dictionary<string, string>> CodeSignatures { get; set; }

The macOS code signature attributes of files in the package, by entry name (Program/Contents/MacOS/App.dll) and attribute name, as Base64. A zip cannot hold them, so the installer sets them on the installed files.

IReadOnlyList<OperationArea> Touches { get; }

The areas the operations touch, for the feed's touches; not written to the file.

enum · nUpdate.Packaging · package nUpdate

PackageRoot

The folders a package copies files into on the client. The top-level folders of a package file are named after them, such as Program/ and AppData/.

Values

Program

The application's folder; on macOS the whole .app bundle when the application runs from one.

AppData

The user's configuration folder: %AppData% on Windows, $XDG_CONFIG_HOME or ~/.config on Linux and macOS.

Temp

The temp folder.

Desktop

The user's desktop.

class · nUpdate.Operations · package nUpdate

RegistryValue

One value of a SetRegistryValuesOperation. The type of Value follows Kind: string for strings, long for DWORD and QWORD, string[] for multi-strings and byte[] for binary values.

Example
var values = new List<RegistryValue>
{
    RegistryValue.String("Theme", "dark"),
    RegistryValue.DWord("Launches", 3),
    RegistryValue.MultiString("RecentFiles", "a.aur", "b.aur"),
};

Creating

RegistryValue(string name, RegistryValueKind kind, object? value)

Throws ArgumentException when the value does not fit the kind; a DWORD takes a long from int.MinValue to uint.MaxValue.

static RegistryValue String(string name, string value)

Also ExpandString.

static RegistryValue DWord(string name, long value)

Also QWord.

static RegistryValue MultiString(string name, params string[] values)

A list of strings.

static RegistryValue Binary(string name, byte[] value)

Raw bytes.

Properties

string Name { get; }

The value's name; an empty name is the key's default value.

RegistryValueKind Kind { get; }

The data type.

object? Value { get; }

The data, typed by the kind.

enum · nUpdate.Operations · package nUpdate

RegistryValueKind

The data type of a RegistryValue.

Values

String

REG_SZ, text. In JSON string.

ExpandString

REG_EXPAND_SZ, text with environment variables that Windows expands. In JSON expandString.

DWord

REG_DWORD, 32 bits. In JSON dword.

QWord

REG_QWORD, 64 bits. In JSON qword.

MultiString

REG_MULTI_SZ, a list of strings. In JSON multiString.

Binary

REG_BINARY, raw bytes. In JSON binary.

class · nUpdate.Updating · package nUpdate

UpdateFeed

The nupdate.json document nUpdate Administration writes next to the packages/ folder: every package a project has published. UpdateManager reads it; AvailableUpdates is what it found there for this client.

Example
{
  "format": 1,
  "projectId": "5f1e4a8c-3b2d-4c6e-9f10-0123456789ab",
  "packages": [
    {
      "version": "2.1.0",
      "publishedAt": "2026-10-10T12:00:00+00:00",
      "necessary": false,
      "afterInstall": null,
      "changelog": {
        "en": "Faster start-up.",
        "de": "Schnellerer Start."
      },
      "unsupportedVersions": [],
      "rollout": {
        "mode": "any",
        "conditions": []
      },
      "files": [
        {
          "platform": "win-x64",
          "path": "packages/2.1.0/win-x64.zip",
          "size": 7340032,
          "sha512": "9b71d224bd62f378...",
          "signature": {
            "algorithm": "rsa-pss-sha512",
            "value": "MEUCIQ..."
          },
          "touches": [
            "files"
          ]
        }
      ],
      "statistics": {
        "url": "statistics/",
        "enabled": true
      }
    }
  ]
}

Properties

const string FileName

nupdate.json.

int Format { get; set; }

The version of the document, CurrentFormat (1). nUpdate refuses another format, and the updates.json of nUpdate 3 and 4, with UnsupportedFormatException.

Guid ProjectId { get; set; }

The project the feed belongs to.

List<PackageInfo> Packages { get; set; }

Every published package as a PackageInfo, in any order.

interface · nUpdate.Administration.TransferInterface · package nUpdate.Administration.TransferInterface

ITransferProvider

Uploads, lists and deletes the files of a project on its server, for a transfer plugin. Remote paths are relative to TransferSettings.Directory and use /; an empty path is that directory itself. A provider keeps one connection open until DisposeAsync.

Example
public async Task UploadFileAsync(string localPath, string remotePath,
    IProgress<TransferProgress>? progress = null, CancellationToken cancellationToken = default)
{
    var size = new FileInfo(localPath).Length;
    await using var file = File.OpenRead(localPath);
    await _bucket.PutAsync(_settings.Directory + "/" + remotePath, file, cancellationToken);
    progress?.Report(new TransferProgress(size, size));
}

Connection

Task ConnectAsync(CancellationToken cancellationToken = default)

Connects and signs in. Throws TransferException on failure, or UntrustedServerException for a certificate or host key the user has not trusted yet.

Files and directories

Task<bool> FileExistsAsync(string remotePath, CancellationToken cancellationToken = default)

Also DirectoryExistsAsync.

Task<IReadOnlyList<ServerItem>> ListAsync(string remotePath, bool recursive, CancellationToken cancellationToken = default)

The items in a directory, or below it.

Task CreateDirectoryAsync(string remotePath, CancellationToken cancellationToken = default)

Creates the directory and any missing parents.

Task DeleteFileAsync(string remotePath, CancellationToken cancellationToken = default)

Deletes a file; a missing file is no error.

Task DeleteDirectoryAsync(string remotePath, CancellationToken cancellationToken = default)

Deletes a directory with everything below it; a missing directory is no error.

Task RenameAsync(string remotePath, string newRemotePath, CancellationToken cancellationToken = default)

Renames or moves a file or directory.

Transfers

Task UploadFileAsync(string localPath, string remotePath, IProgress<TransferProgress>? progress = null, CancellationToken cancellationToken = default)

Uploads a file, reporting TransferProgress. Also DownloadFileAsync.

interface · nUpdate.Administration.TransferInterface · package nUpdate.Administration.TransferInterface

ITransferProviderFactory

Creates the providers of a transfer plugin. nUpdate Administration gets it from the plugin's service provider, see ServiceProviderAttribute.

Example
[assembly: ServiceProvider(typeof(BucketPlugin))]

public sealed class BucketPlugin : IServiceProvider, ITransferProviderFactory
{
    public IReadOnlyCollection<TransferProtocol> SupportedProtocols { get; } =
        [TransferProtocol.Plugin];

    public object? GetService(Type serviceType) =>
        serviceType == typeof(ITransferProviderFactory) ? this : null;

    public ITransferProvider Create(TransferSettings settings,
        TransferCredentials credentials) => new BucketProvider(settings, credentials);
}

Members

IReadOnlyCollection<TransferProtocol> SupportedProtocols { get; }

The protocols the factory handles.

ITransferProvider Create(TransferSettings settings, TransferCredentials credentials)

A provider for a project's settings and secrets.

class · nUpdate.Administration.TransferInterface · package nUpdate.Administration.TransferInterface

ProxySettings

An HTTP proxy for a project's transfers. Its password is in TransferCredentials.ProxyPassword.

Properties

string Address { get; set; }

The proxy, such as http://proxy.example.com:8080.

string? Username { get; set; }

The user name, or null for a proxy without sign-in.

class · nUpdate.Administration.TransferInterface · package nUpdate.Administration.TransferInterface

ServerItem

A file or directory on the server, as ITransferProvider.ListAsync returns it.

Members

ServerItem(string name, string fullPath, long size, DateTimeOffset? modified, ServerItemType itemType)

Throws ArgumentNullException for a missing name or path.

string Name { get; }

The name, such as win-x64.zip.

string FullPath { get; }

The remote path, such as packages/2.1.0/win-x64.zip.

long Size { get; }

The size in bytes.

DateTimeOffset? Modified { get; }

When it last changed, if the server says.

enum · nUpdate.Administration.TransferInterface · package nUpdate.Administration.TransferInterface

ServerItemType

What a ServerItem is.

Values

Directory

A directory.

File

A file.

Other

Anything else, such as a link.

attribute · nUpdate.Administration.TransferInterface · package nUpdate.Administration.TransferInterface

ServiceProviderAttribute

Marks the service provider of a transfer plugin assembly. nUpdate Administration loads the assembly a project names in TransferSettings.PluginAssemblyPath, creates the type and asks it for an ITransferProviderFactory.

Example
[assembly: ServiceProvider(typeof(BucketPlugin))]

Members

ServiceProviderAttribute(Type serviceType)

Throws ArgumentException unless the type implements IServiceProvider.

Type ServiceType { get; }

The service provider's type; it needs a parameterless constructor.

class · nUpdate.Administration.TransferInterface · package nUpdate.Administration.TransferInterface

TransferCredentials

The secrets a provider needs, decrypted with the project password for the run and never stored this way.

Properties

string? Password { get; set; }

The password of the server account.

string? SftpKeyPassphrase { get; set; }

The passphrase of TransferSettings.SftpPrivateKeyPath.

string? ProxyPassword { get; set; }

The password for ProxySettings.

classes · nUpdate.Administration.TransferInterface · package nUpdate.Administration.TransferInterface

Transfer exceptions

What a provider throws when a transfer fails. nUpdate Administration shows the message to the user. Both have the three constructors of an exception: without arguments, with a message, and with a message and an inner exception.

Example
throw new UntrustedServerException(
    $"The host key of {settings.Host} is not trusted yet.", fingerprint, "ssh-ed25519");

Types

class TransferException : Exception

A transfer failed. Write the message for the user.

class UntrustedServerException : TransferException

The server presented a certificate or host key the user has not trusted yet; nUpdate Administration asks whether to trust it.

UntrustedServerException(string message, string fingerprint, string subject)

With what the user decides on.

string? Fingerprint { get; }

The SHA-256 fingerprint the user can trust. Also Subject, a description of the certificate or key.

class · nUpdate.Administration.TransferInterface · package nUpdate.Administration.TransferInterface

TransferProgress

The progress of one file transfer.

Members

TransferProgress(long bytesTransferred, long totalBytes)

Throws ArgumentOutOfRangeException for negative values.

long BytesTransferred { get; }

The bytes so far. Also TotalBytes.

double Percentage { get; }

0 to 100; 0 while the total is unknown.

enum · nUpdate.Administration.TransferInterface · package nUpdate.Administration.TransferInterface

TransferProtocol

How a project uploads its files.

Values

Ftp

Plain FTP.

FtpsExplicit

FTP upgraded to TLS after connecting (AUTH TLS, usually port 21).

FtpsImplicit

FTP over TLS from the first byte (usually port 990).

Sftp

SFTP over SSH (usually port 22).

Plugin

A provider from a plugin assembly, see ServiceProviderAttribute.

class · nUpdate.Administration.TransferInterface · package nUpdate.Administration.TransferInterface

TransferSettings

Where and how a project uploads its files. The secrets are in TransferCredentials.

Server

TransferProtocol Protocol { get; set; }

Sftp by default.

string Host { get; set; }

The server. Also Port, 22 by default.

string Username { get; set; }

The account.

string Directory { get; set; }

The remote directory that corresponds to the update URL; / by default.

ProxySettings? Proxy { get; set; }

An HTTP proxy, or null.

Per protocol

bool UsePassiveMode { get; set; }

FTP: the client opens the data connection; true by default.

string? TrustedCertificateFingerprint { get; set; }

FTPS: the SHA-256 fingerprint of a server certificate the user chose to trust.

string? SftpPrivateKeyPath { get; set; }

SFTP: a private key file, instead of or in addition to the password.

string? TrustedHostKeyFingerprint { get; set; }

SFTP: the SHA-256 fingerprint of the server's host key, learned on the first connection.

string? PluginAssemblyPath { get; set; }

Plugin: the assembly with the ServiceProviderAttribute.