Nefarius' nŏvīcĭus universal software updater agent for Windows.
vīcĭus is a self-contained C++20 executable acting as a software update agent for Microsoft Windows. It can be deployed alongside your product and will take care of periodically checking for newer versions online and notifying the user of pending updates. Its goal is to require the least amount of configuration to get it up and running while providing enough flexibility to be customized for various environments, if desired. It doesn't require any prerequisites being present on the target system and should be able to run on any recent Windows version.
Dealing with software update mechanics has been a steady companion for almost 10 years by now, so it's about time to learn from all the mistakes, hardships and shortcomings the various products used have put me through all this time 😅 If you want something done right, you gotta do it yourself 💪
- No backend application server required
All you need on the server-side to get going is a web host supporting delivering static JSON files and you're done. GitHub Pages would be a sufficient free hosting solution where you can upload to and deliver the updater configuration from. Take a look at the example server implementation if you wish to write your own backend service. - Self-contained
No need to worry if .NET or other runtimes are present on the target machines, everything it needs is delivered in a single Win32 executable. - (Almost) zero configuration
The bare minimum configuration can be provided by simply compiling in the server URL by adjusting theCustomizeMe.h
header file. This does not mean you need to maintain one build for every product you wanna support; you will get multi-tenancy out of the box by simply naming the resulting executable after the following scheme:manufacturer_product_Updater.exe
, e.g.nefarius_HidHide_Updater.exe
will build the server path ashttps://example.org/api/nefarius/HidHide/updates.json
(or however it is defined inCustomizeMe.h
) automatically!- All alternative, more sophisticated configuration options are described in the extended documentation.
- If you wish to completely avoid touching the cloned sources have a look at the optional includes.
- Sane defaults
We hate wasting time writing configuration files as much as the next person; most configuration options are either optional or have sane default fallback values you can depend on. - Self-updater
Sometimes just the updater process needs an update (e.g. security patches), not the entire product it is watching over. It can update itself if the server-provided instance version is higher than the locally running one. - Self-healing
If run in autostart when the user logs on, it can make sure that scheduled tasks and other supportive components are configured and working properly. - Low resource consumption
The updater process is only invoked on demand (at user logon and once per day via Task Scheduler) and doesn't keep running in the background. - Respects your time
Busy fragging in a game? We won't bother you with any popup windows until you're ready. - Powerful template engine included
Sometimes finding the local resource of interest to check the product version can be more challenging than just having a static, boring file path. You can use inja templates to build your own path resolving logic, all while never having to leave your JSON strings! - Expressive modern changelog support
Update summaries a.k.a. changelogs don't have to be boring slabs of text; Markdown is fully supported! The included fonts are also capable of rendering Fork Awesome icons and system-provided emojis! 🎉 🥳 🍕
- Windows 7 or later (x86, x86_64, ARM64)
- Note: currently anything below Windows 10 is untested and low priority
- An NTFS formatted volume
- An Internet connection
- Your software updates need to be packaged in one of the following ways:
- Some sort of setup engine like WiX/WixSharp, Inno Setup, Advanced Installer, NSIS or similar
- A self-extracting archive (7zip SFX, WinRAR SFX and alike)
- A ZIP archive containing portable software
Head over to the extended documentation for examples and detailed explanations.
You can get unsigned build snapshots here. Consider these Nightly-releases.
Signed stable releases will be provided on the repository releases page. Keep in mind though that those releases are built to use my own update infrastructure so in 99% of the cases you probably don't want to use them, at least not without a configuration file!
Set up Visual Studio 2022 or newer with the C++ Desktop Development workload.
To get binary compression to work upx has to be installed. You can do so via e.g.:
winget install upx
You do not have to touch the checked out sources if you wish to customize your build.
Assuming a manufacturer name Valkirie
and product name HandheldCompanion
, create the following folder structure and file .\include\Valkirie\HandheldCompanion\ViciusPostCustomizeMe.h
and override the server url in there like so:
#undef NV_API_URL_TEMPLATE
#define NV_API_URL_TEMPLATE "https://raw.githubusercontent.com/Valkirie/HandheldCompanion/main/Valkirie_HandheldCompanion_Updates.json"
Now you can build from the command line pointing the compiler to the directory of your header(s) like so:
msbuild .\src\vīcĭus.vcxproj /p:Configuration=Release /p:CustomIncludes="${PWD}\include\Valkirie\HandheldCompanion\" /p:UpdaterName=Valkirie_HandheldCompanion_Updater
This will produce the binary Valkirie_HandheldCompanion_Updater.exe
with the server URL of your custom header file baked into it!
You're of course free to put the custom header files anywhere on your system (like your own private repository), they do not need to be put under the project root directory.
For more details check the issue tracker.
Non-exhaustive list of things open or in-progress...
- Add silent update option
- Docs
- Types
- Implementation (see #15)
- Add message box dialog if the user launches the updater with no args
- Standard text if we are up to date
- Inform if Betas are available
- Localization
- Add Authenticode signature checks (see #7)
- Crypto primitives
- Model types
- Business logic
- Design Beta-Release support
-
WizardPage::MultipleVersionsOverview
-
- Make app icon customizable
- Add "Light" theme
- Support closing and restarting applications before and after the main update
- Support running prerequisites installation before main update
- Support running the update as Administrator
- Implement machine-wide registration Currently only the user executing the updater will run registrations, which is sufficient for most cases
- Postpone update dialog popping up if the product is currently in use
- Allow using a HTTP proxy address via configuration
- Add SAL annotations
Expand me!
- Make UI DPI-aware
- Finalize UI design
-
WizardPage::Start
-
WizardPage::SingleVersionSummary
-
WizardPage::DownloadAndInstall
-
- Finalize local updater config JSON format
- Add retry-logic (e.g. retry failed downloads etc.)
- Add some fallback code if the temp directory isn't available
- Handle all known error-cases
- Server response errors
- Release download errors
- Setup launch errors
- Documentation
- About page
- JSON Schemas
- Specify supported Command Line Arguments
- Exit Codes
- Emergency Feature
- Server Discovery
- Logging
- Common Errors
- Local Configuration
- Remote Configuration
- Allow setting the download directory
- Implement "postpone" choice behaviour
- Implement Task Scheduler
- Registration
- Removal
- Finalize REST API design
- Add info dialog before self-updating UAC dialog comes up
- Add self-updater logic
- Tests
- Fix issues launching from write-protected directory like
Program Files
- Implement Product Version detection
-
RegistryValue
-
FileVersion
-
FileSize
-
FileChecksum
-
CustomExpression
-
- Add some logging
- Tidy up and improve includes
- Optimize build times
- Use pre-compiled headers?
- Support environment variables or custom placeholders in path strings and alike
This tool benefits from these awesome projects ❤ (appearance in no special order):
- Dear ImGui
- Simple and Fast Multimedia Library
- ImGui-SFML
- Argh! A minimalist argument handler
- Markdown renderer for Dear ImGui using MD4C parser
- IconFontCppHeaders
- Ruda Font
- Fork Awesome
- REST client for C++
- cURLpp
- JSON for Modern C++
- Magic Enum C++
- Semantic Versioning library for modern C++
- WinReg
- Portable C++ Hashing Library
- A modern C++ scope guard that is easy to use but hard to misuse
- Fast C++ logging library
- A Template Engine for Modern C++
- Simple C++ ini parser
- MimeTypes
- A C++ header-only HTTP/HTTPS server and client library
- A C library for reading, creating, and modifying zip archives
- My opinionated collection of C++ utilities
- Using Icon Fonts
- Image Loading and Displaying Examples
- DailyTaskScheduler
- INFO: Windows Rundll and Rundll32 Interface
- How can I run a child process that requires elevation and wait?
- Execute from Alternate Streams
- Vista Goodies in C++: Showing Friendly Messages with Task Dialogs
- How to retrieve files digital signature information?
- Windows Authenticode Portable Executable Signature Format
- How To Get Information from Authenticode Signed Executables
- VERSIONINFO resource
- Semantic Versioning 2.0.0
- Windows Platform Comparison Environment Variable Reference
- C++ Library Manager for Windows, Linux, and MacOS
- Silently Install EXE and MSI setup applications (Unattended) - How To Guide
- Markdown Guide Basic Syntax