corundum-framework-package
A desktop app as a Velopack package, for Windows, macOS and Linux.
start is the first thing the app's main runs. Started by the Windows installer or
uninstaller for a hook, it runs the app's hook and exits; otherwise it tells the app whether
this start is its first, the first after an update, or neither, from the version the app
last ran with. Not in a package (cargo run), it says so and does nothing else.
use ;
static SPEC: PackageSpec = PackageSpec ;
The crate's other parts:
Updaterfinds and downloads the app's updates on a thread of its own, and applies one only when asked, after the app'sbefore_applyhas stopped its background processes.applyhands the update to Velopack's updater: withAfter::Exit(a daemon, a command) it exits the process; with a restart it returns, and the app ends the process itself, a GUI by closing its window.apply_pending_at_startapplies, at a GUI's start, an update downloaded earlier and never applied.cli_pathputs the app's command line onPATH: the userPathon Windows, from the install hook; a link in/usr/local/binon macOS and in~/.local/binon Linux, when the user asks. Another program's command of the same name is left alone.consoleis the Windows console shim: a GUI binary has no console, so a small console binary onPATHstarts it with the terminal's arguments and streams.
Background services
PackageSpec::services names the app's background services: Services::NONE, or with the
service feature Services::new(&[my_service]), each a function building the service's
corundum_framework_service::ServiceSpec. With them:
Updater::applyandapply_pending_at_startstop the services that are running after the app'sbefore_apply, and note them inservices-to-restartin the app's data directory first. A service whose state cannot be read is stopped and noted all the same; only a note that cannot be written refuses the update. When the apply fails, they are started again at once.startstarts the services an update stopped, on every start, packaged or not, and removes the note: whichever of the app's programs starts first after the update does it.- On Windows, the uninstall hook uninstalls each service before the files go. On macOS and Linux nothing runs at uninstall: remove the background service first (Settings › About › Remove), or its unit is left pointing at a program that is gone.
Packaging
The command on PATH (CliSpec::command) need not be the cargo binary's name. On macOS and
Linux it links to the running executable, whatever vpk --mainExe named it; on Windows it
is the shim <command>.exe beside the GUI executable in current\.
Cargo cannot build two binaries of one name in a workspace (cargo#6313), so an app's desktop
package is built as <app>-desktop, while its headless build keeps <app>. Pack it so:
- macOS and Linux: rename the desktop binary to
<app>in the pack directory, and runvpk pack --mainExe <app>. - Windows: keep the GUI executable's name, add the console shim as
<app>.exe, and runvpk pack --mainExe <app>-desktop.exe. The shim callsconsole::forward("<app>-desktop.exe"). Without the shim (cargo install, or before packaging) the GUI executable prints in the terminal throughcorundum_framework_platform::console::attach_parent, which the shell does not wait for: no exit code, no typed input. --packTitleequalsLauncherSpec::name, so the installer's shortcut and the launcher's path coincide.- Velopack's
Update.exe(UpdateMacon macOS) stays beside the executable; vpk puts it there, and the package's detection looks for it.
On iOS and Android the crate is empty: the store installs and updates the app there.
License
Licensed under either of the Apache License, Version 2.0 or the MIT license, at your option.