Windows application updater library, similar to Sparkle and WinSparkle. The library checks for updates from a remote server or file-system, which inturn notifies the user of your apps' update and prompts an optional installation. This process can be executed periodically within your application with limited user interaction.
It is a win32 native stand-alone library without any non-system external dependencies, permitting both GUI and console interaction.
Due to minimal external dependencies supports MSVC 2008+ and OpenWatcom and run on Windows XP or greater. Other toolchains should be possible with minimal effort.
As the updater is downloading an installer from a remote location, security must be considered.
By default for data integrity the installer is signed using both MD5 and SHA hashes, for greater security installers can also be signed using a EdDSA and Ed25519 signature.
To prepare signing with EdDSA signatures, run keygen (from the package distribution), this action only needs to be performed once. Keygen shall generate both a private key and associated public key as pem style file images. The private key is required to sign an installer whereas the public key is used to verify.
keygen -K application_private.pem -k application_public.pem
These files should be stored securely in a non public location. If the private-key is lost, you wont be able to recover the key and shall be unable to issue new releases under the same key. A new key-pair and associated key-version shall need to generated.
It shall also display the public key encoded as a base64-encoded string, which is required to embed into your updater applications. The key files shall be needed when generating an application signature block.
Generating <private.pem> and <public.pem>
A key-pair has been generated and saved locally.
Add the following public-key into your updater application.
"VVAqoUagyW3ZfSt+7RfrGHFFY301CEkismrVJtxFjfU="
Rerunning keygen shall only load any local pem images and redisplay the public key.
To sign an installer, the SignTool application is run, for example
signtool -K application_private.pem -x 1 -v 0.0.1 \
-H https://github.com/user/repo~application.manifest application-installer-0.0.1.exe
The resulting signature block is exported that can then by cut & pasted into the application manifest, which you can value add to include a change notice related to the installer release.
<title></title>
<link></link>
<description></description>
<published>1745138422</published>
<pubDate>Sun, 20 Apr 2025 16:40:22 +0000</pubDate>
<enclosure url="https://github.com/user/repo~application.manifest"
os="windows"
name="application-installer-0.0.1.exe"
version="0.0.1"
length="4651716"
md5Signature="d2a2be2f3175c01b586eee68030bd61e"
shaSignature="a805501b9913b6efcf2981ab468b0007e687cde3"
edSignature="Liza1uN/dECOIk+Hffp6wMqoZ9IxPGGwF2Vn61L2/LzxkGoTRMnJd5zg+A2E7Sl0gCTN/3R3SPp52Lbvn5qGCA=="
edKeyVersion="1.1"
type="application/octet-stream" />
To simplifying application integration a customised version of signtool can be built. Using the provided application shim, default arguments can be provided stream-lining software management.
//
// signtool specialisation
//
#include "libappupdater/sign/signtoolshim.h" // SignToolShim()
int
main(int argc, char *argv[])
{
struct SignToolArgs args = {0};
args.hosturl = "https://github.com/user/repo~application.manifest";
return SignToolShim(argc, argv, &args);
}
<?xml version="1.0" encoding="utf-8"?>
<manifest>
<channel name="release">
<title>Application Change Channel</title>
<link>https://github.com/user/repo/release/latest</link>
<description>Most recent changes with links to updates.</description>
<language>en</language>
<item>
<title>Application 1.0.3, minor release</title>
<description><![CDATA[
<style media="screen" type="text/css">
body { font: 80%/1.5em Verdana, Tahoma, arial, Sans-serif; background: #ECECEA; color: #333; }
h1 { font: Bold 150% Verdana, 'Trebuchet MS', Sans-serif; color: #558C89; text-align: center; border-bottom: 1px solid #000000; }
h2 { font: Bold 120% Verdana, 'Trebuchet MS', Sans-serif; color: #74AFAD; border-width: 0px; }
p { margin: 0; padding: 10px 0 0 0; }
ul.a { list-style-type: circle; padding: 0px; margin: 0px; }
ul.b { list-style-type: square; padding: 0px; margin: 0px; }
</style>
<html><body>
<h1>Change Log</h1>
<p>
The major changes for this <i>application</i> release are listed below.
A more specific list of changes and fixes can be found in the detailed change log.
</p>
<ul>
<li>Updater 1.0.3 integration.</li>
</ul>
<body></html>
]]>
</description>
<published>1745138422</published>
<pubDate>Sun, 20 Apr 2025 16:40:22 +0000</pubDate>
<enclosure
url="https://github.com/user/repo~application.manifest"
os="windows"
name="application-installer-1.0.3.exe"
version="1.0.3"
length="4651716"
md5Signature="d2a2be2f3175c01b586eee68030bd61e"
shaSignature="a805501b9913b6efcf2981ab468b0007e687cde3"
edSignature="Liza1uN/dECOIk+Hffp6wMqoZ9IxPGGwF2Vn61L2/LzxkGoTRMnJd5zg+A2E7Sl0gCTN3R3SPp52Lbvn5qGCA=="
edKeyVersion="1.1"
type="application/octet-stream" />
</item>
</channel>
</manifest>
To build from source directly, you'll need to compile from a git checkout.
git clone https://github.com/adamyg/libappupdater
$ cd libappupdater
Note: Generally libappupdater would be a submodule within the application repo.
To compile the library, just open within Visual Studio one of bundled AutoUpdater.xxx.sln solutions (atching your corresponding compiler version) and build it. Alternatively run msbuild against the same solution.
msbuild AutoUpdater.vs160.sln /property:Configuration=Release
msbuild AutoUpdater.vs160.sln /property:Configuration=Debug
msbuild AutoUpdater.vs160.sln /property:Configuration=Release /p:Platform=x64
msbuild AutoUpdater.vs160.sln /property:Configuration=Debug /p:Platform=x64
Application integration can be achieved using several methods.
- As a stand-alone updater application; or
- embedded within the target application.
Working examples are provided as test applications. For following demonstrates one method
#include "libappupdater/update/updatetoolshim.h" // UpdaterToolShim()
#include "version.h" // VERSION_TAG, build-system version.
#include "public_key.h" // PUBLIC_KEY and KEY_VERSION, see: keygen
int
main(int argc, char *argv[])
{
struct UpdateToolArgs args = {0};
args.progtitle = "MyApplication updater";
args.appname = "MyApplication";
args.version = VERSION_TAG;
args.hosturl = "https://github.com/user/repo~application.manifest";
args.publickey = PUBLIC_KEY;
args.keyversion = KEY_VERSION;
return UpdateToolShim(argc, argv, &args);
}
#include "libappupdater/src/AutoUpdater.h" // AutoUpdater
#include "version.h" // VERSION_TAG, build-system version.
#include "public_key.h" // PUBLIC_KEY and KEY_VERSION, see: keygen
int
Application::CheckForUpdates()
{
AutoUpdater au;
// Note parameters stated either by:
// o Explicit run-time arguments; or
// o Application resource elements, alone-side VERSIONINFO information;
// see AutoConfig.h for further details.
//
au.EnableDialog();
au.AppName("MyApplication");
au.AppVersion(VERSION_TAG);
au.HostURL("https://github.com/user/repo~application.manifest");
au.PublicKey(PUBLIC_KEY, KEY_VERSION);
au.Execute(AutoUpdater::ExecuteAuto, true);
}
MIT License
libappupdater, Copyright (c) 2012 - 2025 Adam Young
https://github.com/adamyg/libappupdater
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.