Skip to main content

Integrating Overview

Applies to
Windows
MacOS
Linux

To integrate Velopack into your application, you must initialise the Velopack as early as possible in app startup, and you should add update checking code somewhere.

For .NET applications, you should first install the Velopack Nuget Package.

Application Startup

Velopack requires you add some code to your application startup to handle hooks. This is because Velopack will run your main binary at certain stages of the install/update process with special arguments, to allow you to customise behavior. It expects your app to respond to these arguments in the right way and then exit as soon as possible.

The simplest/minimal way to handle this properly is to add the SDK startup code to your Main() method. This should be in the "main" binary (the one specified when packaging with --mainExe {exeName}).

static void Main(string[] args)
{
VelopackApp.Build().Run();
// ... your other startup code below
}

There are a variety of options / callbacks you can specify here to customise Velopack, for example:

static void Main(string[] args)
{
ILogger log = CreateLogger();
VelopackApp.Build()
.WithBeforeUninstallFastCallback((v) => {
// delete / clean up some files before uninstallation
})
.WithFirstRun((v) => {
MessageBox.Show("Thanks for installing my application!");
})
.Run(log);
}

The full list of options for VelopackApp is available here. You can also read more about how hooks work.

warning

A "FastCallback" requires that your application show no UI and exit quickly. When the callback returns, your application will exit. If you do not exit this callback quickly enough your process will be killed.

Configuring Updates

Updates can be accomplished by adding UpdateManager to your app:

private static async Task UpdateMyApp()
{
var mgr = new UpdateManager("https://the.place/you-host/updates");

// check for new version
var newVersion = await mgr.CheckForUpdatesAsync();
if (newVersion == null)
return; // no update available

// download new version
await mgr.DownloadUpdatesAsync(newVersion);

// install new version and restart app
mgr.ApplyUpdatesAndRestart(newVersion);
}
tip

Updates can be done silently in the background, or integrated into your application UI. It's always up to you.

You can host your update packages basically anywhere, here are a few examples:

  • Local directory:
    new UpdateManager("C:\Updates")
  • HTTP server, or S3, Azure Storage, etc:
    new UpdateManager("https://the.place/you-host/updates")
  • GitHub Releases:
    new UpdateManager(new GitHubSource("https://github.com/yourName/yourRepo")

There are a variety of built-in sources (eg. GithubSource, SimpleWebSource) you can use when checking for updates, but you can also build your own by deriving from IUpdateSource.

Check for updates

CheckForUpdatesAsync will read the provided update source for a releases.{channel}.json file to retrieve available updates (Read about channels). If there is an update available, a non-null UpdateInfo will be returned with some details about the update. You can also retrieve any release notes which were provided when the update was packaged.

There are also some options which can be passed in to UpdateManager to customise how updates are handled, eg. to allow things like switching channels.

Download updates

DownloadUpdatesAsync will attempt to download deltas (if available) and re-construct the latest full release. If there are no deltas available, or the delta reconstruction fails, the latest full release package will be downloaded instead. Note that if an option like AllowVersionDowngrade is specified, the downloaded version might be older than the currently executing version.

Apply updates

Once the update has downloaded, you have a few options available. Calling ApplyUpdatesAndRestart or ApplyUpdatesAndExit will exit your app, install any bootstrap prerequisites, install the update, and then optionally restart your app right away.

If you do not want to exit your app immediately, you can call WaitExitThenApplyUpdates instead, which will launch Update.exe and wait for 60 seconds before proceeding. If your app has not exited within 60 seconds it will be killed.

Lastly, if you do not call any of these "Apply" methods, when you re-launch your app, by default, Velopack will detect that there is a pending update and install it then. If you wish to disable this, you should call VelopackApp.Build().SetAutoApplyOnStartup(false).

tip

It is recommended that you use one of the functions which explicitly applies a package (eg. ApplyUpdatesAndRestart), and do not rely on the AutoApply behavior as a rule of thumb. The auto behavior will only apply a downloaded version if it is > the currently installed version, so will not work if trying to downgrade or switch channels, and if more than one instance of your process is running it could result in the update failing or those other processes being terminated.

How updates work

On Windows

In a typical Windows install the application structure will look like this:

%LocalAppData%
└── {packId}
├── current
│ ├── YourFile.dll
│ ├── sq.version
│ └── YourApp.exe
└── Update.exe

sq.version is a special file created by Velopack which contains some metadata about your currently installed application. During install/uninstall, the entire {packId} folder is replaced or removed. During updates, only the current folder is replaced. If you store settings in the same folder as your main binary, they will be erased during updates.

warning

Since current is replaced with the new version during updates, it's not safe to store settings, logs, etc in the current dir where your app lives. See Preserving Files for more info.

On Linux & Mac

On these platforms, the app is stored as a single (typically read-only) bundle like .app or .AppImage. The bundle is replaced during updates in a single atomic operation. If you have any files you wish to persist (settings, logs, etc) you must find a directory elsewhere on the filesystem to store these files.