mirror of
https://github.com/velopack/velopack.git
synced 2025-10-25 15:19:22 +00:00
Build basic C header with cbindgen
This commit is contained in:
71
Cargo.lock
generated
71
Cargo.lock
generated
@@ -315,6 +315,25 @@ version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495"
|
||||
|
||||
[[package]]
|
||||
name = "cbindgen"
|
||||
version = "0.27.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fce8dd7fcfcbf3a0a87d8f515194b49d6135acab73e18bd380d1d93bb1a15eb"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"heck 0.4.1",
|
||||
"indexmap",
|
||||
"log",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"syn 2.0.87",
|
||||
"tempfile",
|
||||
"toml 0.8.19",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.1.37"
|
||||
@@ -380,7 +399,7 @@ version = "4.5.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"heck 0.5.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
@@ -885,6 +904,12 @@ version = "0.15.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.5.0"
|
||||
@@ -1746,12 +1771,6 @@ dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scratch"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3cf7c11c38cb994f3d40e8a8cde3bbd1f72a435e4c49e85d6553d8312306152"
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.23"
|
||||
@@ -1796,6 +1815,15 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
version = "0.6.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha1"
|
||||
version = "0.10.6"
|
||||
@@ -1904,7 +1932,7 @@ version = "0.26.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"heck 0.5.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustversion",
|
||||
@@ -2066,11 +2094,26 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.8.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"toml_edit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.6.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
@@ -2079,6 +2122,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"winnow",
|
||||
]
|
||||
@@ -2134,12 +2179,6 @@ version = "1.0.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
|
||||
|
||||
[[package]]
|
||||
name = "untrusted"
|
||||
version = "0.9.0"
|
||||
@@ -2279,7 +2318,9 @@ name = "velopack_libc"
|
||||
version = "0.0.0-local"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cbindgen",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"log",
|
||||
"velopack",
|
||||
]
|
||||
@@ -2773,7 +2814,7 @@ version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b68db261ef59e9e52806f688020631e987592bd83619edccda9c47d42cde4f6c"
|
||||
dependencies = [
|
||||
"toml",
|
||||
"toml 0.5.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -77,6 +77,7 @@ fs_extra = "1.3"
|
||||
memmap2 = "0.9"
|
||||
webview2-com = "0.33"
|
||||
windows = "0.58"
|
||||
cbindgen = "0.27"
|
||||
|
||||
# default to small, optimized workspace release binaries
|
||||
[profile.release]
|
||||
|
||||
@@ -21,4 +21,8 @@ crate-type = ["cdylib"]
|
||||
velopack.workspace = true
|
||||
anyhow.workspace = true
|
||||
lazy_static.workspace = true
|
||||
log.workspace = true
|
||||
log.workspace = true
|
||||
libc.workspace = true
|
||||
|
||||
[build-dependencies]
|
||||
cbindgen.workspace = true
|
||||
18
src/lib-cpp/build.rs
Normal file
18
src/lib-cpp/build.rs
Normal file
@@ -0,0 +1,18 @@
|
||||
extern crate cbindgen;
|
||||
|
||||
use std::env;
|
||||
|
||||
fn main() {
|
||||
let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
|
||||
cbindgen::Builder::new()
|
||||
.with_crate(crate_dir)
|
||||
.with_documentation(true)
|
||||
.with_language(cbindgen::Language::C)
|
||||
.with_autogen_warning("// === THIS FILE IS AUTO-GENERATED - DO NOT EDIT ===")
|
||||
.with_include_guard("VELOPACK_H")
|
||||
.with_cpp_compat(true)
|
||||
.with_include_version(true)
|
||||
.generate()
|
||||
.expect("Unable to generate bindings")
|
||||
.write_to_file("include/Velopack.h");
|
||||
}
|
||||
@@ -1,620 +1,216 @@
|
||||
//! This header provides the C and C++ API for the Velopack library.
|
||||
//! All the C constructs are prefixed by `vpkc_` and all the C++ constructs are in the `Velopack` namespace.
|
||||
//! The C++ API is a thin wrapper around the C API, providing a more idiomatic C++ interface.
|
||||
//! You should not mix and match the C and C++ APIs in the same program.
|
||||
#ifndef VELOPACK_H
|
||||
#define VELOPACK_H
|
||||
|
||||
#include <stddef.h> // For size_t
|
||||
#include <stdbool.h> // For bool
|
||||
#include <stdint.h> // For uint64_t, uint32_t
|
||||
/* Generated with cbindgen:0.27.0 */
|
||||
|
||||
// === THIS FILE IS AUTO-GENERATED - DO NOT EDIT ===
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
enum vpkc_update_check_t
|
||||
#ifdef __cplusplus
|
||||
#include <string>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
#endif
|
||||
: int16_t
|
||||
#endif // __cplusplus
|
||||
{
|
||||
UPDATE_ERROR = -1,
|
||||
UPDATE_AVAILABLE = 0,
|
||||
NO_UPDATE_AVAILABLE = 1,
|
||||
REMOTE_IS_EMPTY = 2,
|
||||
};
|
||||
#ifndef __cplusplus
|
||||
typedef int16_t vpkc_update_check_t;
|
||||
#endif // __cplusplus
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#include <string.h>
|
||||
#endif
|
||||
/**
|
||||
* Options to customise the behaviour of UpdateManager.
|
||||
*/
|
||||
typedef struct vpkc_update_options_t {
|
||||
/**
|
||||
* Allows UpdateManager to update to a version that's lower than the current version (i.e. downgrading).
|
||||
* This could happen if a release has bugs and was retracted from the release feed, or if you're using
|
||||
* ExplicitChannel to switch channels to another channel where the latest version on that
|
||||
* channel is lower than the current version.
|
||||
*/
|
||||
bool AllowVersionDowngrade;
|
||||
/**
|
||||
* **This option should usually be left None**. <br/>
|
||||
* Overrides the default channel used to fetch updates.
|
||||
* The default channel will be whatever channel was specified on the command line when building this release.
|
||||
* For example, if the current release was packaged with '--channel beta', then the default channel will be 'beta'.
|
||||
* This allows users to automatically receive updates from the same channel they installed from. This options
|
||||
* allows you to explicitly switch channels, for example if the user wished to switch back to the 'stable' channel
|
||||
* without having to reinstall the application.
|
||||
*/
|
||||
char *ExplicitChannel;
|
||||
} vpkc_update_options_t;
|
||||
|
||||
/**
|
||||
* VelopackLocator provides some utility functions for locating the current app important paths (eg. path to packages, update binary, and so forth).
|
||||
*/
|
||||
typedef struct vpkc_locator_config_t {
|
||||
/**
|
||||
* The root directory of the current app.
|
||||
*/
|
||||
char *RootAppDir;
|
||||
/**
|
||||
* The path to the Update.exe binary.
|
||||
*/
|
||||
char *UpdateExePath;
|
||||
/**
|
||||
* The path to the packages' directory.
|
||||
*/
|
||||
char *PackagesDir;
|
||||
/**
|
||||
* The current app manifest.
|
||||
*/
|
||||
char *ManifestPath;
|
||||
/**
|
||||
* The directory containing the application's user binaries.
|
||||
*/
|
||||
char *CurrentBinaryDir;
|
||||
/**
|
||||
* Whether the current application is portable or installed.
|
||||
*/
|
||||
bool IsPortable;
|
||||
} vpkc_locator_config_t;
|
||||
|
||||
typedef void vpkc_update_manager_t;
|
||||
|
||||
/**
|
||||
* An individual Velopack asset, could refer to an asset on-disk or in a remote package feed.
|
||||
*/
|
||||
typedef struct vpkc_asset_t {
|
||||
/**
|
||||
* The name or Id of the package containing this release.
|
||||
*/
|
||||
char *PackageId;
|
||||
/**
|
||||
* The version of this release.
|
||||
*/
|
||||
char *Version;
|
||||
/**
|
||||
* The type of asset (eg. "Full" or "Delta").
|
||||
*/
|
||||
char *Type;
|
||||
/**
|
||||
* The filename of the update package containing this release.
|
||||
*/
|
||||
char *FileName;
|
||||
/**
|
||||
* The SHA1 checksum of the update package containing this release.
|
||||
*/
|
||||
char *SHA1;
|
||||
/**
|
||||
* The SHA256 checksum of the update package containing this release.
|
||||
*/
|
||||
char *SHA256;
|
||||
/**
|
||||
* The size in bytes of the update package containing this release.
|
||||
*/
|
||||
uint64_t Size;
|
||||
/**
|
||||
* The release notes in markdown format, as passed to Velopack when packaging the release. This may be an empty string.
|
||||
*/
|
||||
char *NotesMarkdown;
|
||||
/**
|
||||
* The release notes in HTML format, transformed from Markdown when packaging the release. This may be an empty string.
|
||||
*/
|
||||
char *NotesHtml;
|
||||
} vpkc_asset_t;
|
||||
|
||||
/**
|
||||
* Holds information about the current version and pending updates, such as how many there are, and access to release notes.
|
||||
*/
|
||||
typedef struct vpkc_update_info_t {
|
||||
/**
|
||||
* The available version that we are updating to.
|
||||
*/
|
||||
struct vpkc_asset_t TargetFullRelease;
|
||||
/**
|
||||
* True if the update is a version downgrade or lateral move (such as when switching channels to the same version number).
|
||||
* In this case, only full updates are allowed, and any local packages on disk newer than the downloaded version will be
|
||||
* deleted.
|
||||
*/
|
||||
bool IsDowngrade;
|
||||
} vpkc_update_info_t;
|
||||
|
||||
typedef void (*vpkc_progress_callback_t)(void *p_user_data, size_t progress);
|
||||
|
||||
typedef void (*vpkc_hook_callback_t)(void *p_user_data, const char *psz_app_version);
|
||||
|
||||
typedef void (*vpkc_log_callback_t)(void *p_user_data,
|
||||
const char *psz_level,
|
||||
const char *psz_message);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void vpkc_update_manager_t;
|
||||
typedef void (*vpkc_progress_callback_t)(void* pUserData, size_t progress);
|
||||
typedef void (*vpkc_log_callback_t)(void* pUserData, const char* pszLevel, const char* pszMessage);
|
||||
typedef void (*vpkc_hook_callback_t)(void* pUserData, const char* pszAppVersion);
|
||||
|
||||
typedef enum vpkc_update_check_t {
|
||||
UPDATE_ERROR = -1,
|
||||
UPDATE_AVAILABLE = 0,
|
||||
NO_UPDATE_AVAILABLE = 1,
|
||||
REMOTE_IS_EMPTY = 2,
|
||||
} vpkc_update_check_t;
|
||||
|
||||
// !! AUTO-GENERATED-START C_TYPES
|
||||
|
||||
/// VelopackLocator provides some utility functions for locating the current app important paths (eg. path to packages, update binary, and so forth).
|
||||
typedef struct vpkc_locator_config_t {
|
||||
/// The root directory of the current app.
|
||||
char* RootAppDir;
|
||||
/// The path to the Update.exe binary.
|
||||
char* UpdateExePath;
|
||||
/// The path to the packages' directory.
|
||||
char* PackagesDir;
|
||||
/// The current app manifest.
|
||||
char* ManifestPath;
|
||||
/// The directory containing the application's user binaries.
|
||||
char* CurrentBinaryDir;
|
||||
/// Whether the current application is portable or installed.
|
||||
bool IsPortable;
|
||||
} vpkc_locator_config_t;
|
||||
|
||||
/// An individual Velopack asset, could refer to an asset on-disk or in a remote package feed.
|
||||
typedef struct vpkc_asset_t {
|
||||
/// The name or Id of the package containing this release.
|
||||
char* PackageId;
|
||||
/// The version of this release.
|
||||
char* Version;
|
||||
/// The type of asset (eg. "Full" or "Delta").
|
||||
char* Type;
|
||||
/// The filename of the update package containing this release.
|
||||
char* FileName;
|
||||
/// The SHA1 checksum of the update package containing this release.
|
||||
char* SHA1;
|
||||
/// The SHA256 checksum of the update package containing this release.
|
||||
char* SHA256;
|
||||
/// The size in bytes of the update package containing this release.
|
||||
uint64_t Size;
|
||||
/// The release notes in markdown format, as passed to Velopack when packaging the release. This may be an empty string.
|
||||
char* NotesMarkdown;
|
||||
/// The release notes in HTML format, transformed from Markdown when packaging the release. This may be an empty string.
|
||||
char* NotesHtml;
|
||||
} vpkc_asset_t;
|
||||
|
||||
/// Holds information about the current version and pending updates, such as how many there are, and access to release notes.
|
||||
typedef struct vpkc_update_info_t {
|
||||
/// The available version that we are updating to.
|
||||
vpkc_asset_t TargetFullRelease;
|
||||
/// True if the update is a version downgrade or lateral move (such as when switching channels to the same version number).
|
||||
/// In this case, only full updates are allowed, and any local packages on disk newer than the downloaded version will be
|
||||
/// deleted.
|
||||
bool IsDowngrade;
|
||||
} vpkc_update_info_t;
|
||||
|
||||
/// Options to customise the behaviour of UpdateManager.
|
||||
typedef struct vpkc_update_options_t {
|
||||
/// Allows UpdateManager to update to a version that's lower than the current version (i.e. downgrading).
|
||||
/// This could happen if a release has bugs and was retracted from the release feed, or if you're using
|
||||
/// ExplicitChannel to switch channels to another channel where the latest version on that
|
||||
/// channel is lower than the current version.
|
||||
bool AllowVersionDowngrade;
|
||||
/// **This option should usually be left None**. <br/>
|
||||
/// Overrides the default channel used to fetch updates.
|
||||
/// The default channel will be whatever channel was specified on the command line when building this release.
|
||||
/// For example, if the current release was packaged with '--channel beta', then the default channel will be 'beta'.
|
||||
/// This allows users to automatically receive updates from the same channel they installed from. This options
|
||||
/// allows you to explicitly switch channels, for example if the user wished to switch back to the 'stable' channel
|
||||
/// without having to reinstall the application.
|
||||
char* ExplicitChannel;
|
||||
} vpkc_update_options_t;
|
||||
// !! AUTO-GENERATED-END C_TYPES
|
||||
|
||||
/// Creates a new vpkc_update_manager_t. Free with vpkc_free_update_manager.
|
||||
/// \group UpdateManager
|
||||
bool vpkc_new_update_manager(const char* pszUrlOrString, vpkc_update_options_t* pOptions, vpkc_locator_config_t* pLocator, vpkc_update_manager_t** pManager);
|
||||
/// \group UpdateManager
|
||||
size_t vpkc_get_current_version(vpkc_update_manager_t* pManager, char* pszVersion, size_t cVersion);
|
||||
/// \group UpdateManager
|
||||
size_t vpkc_get_app_id(vpkc_update_manager_t* pManager, char* pszId, size_t cId);
|
||||
/// \group UpdateManager
|
||||
bool vpkc_is_portable(vpkc_update_manager_t* pManager);
|
||||
/// \group UpdateManager
|
||||
bool vpkc_update_pending_restart(vpkc_update_manager_t* pManager, vpkc_asset_t* pAsset);
|
||||
/// \group UpdateManager
|
||||
vpkc_update_check_t vpkc_check_for_updates(vpkc_update_manager_t* pManager, vpkc_update_info_t* pUpdate);
|
||||
/// \group UpdateManager
|
||||
bool vpkc_download_updates(vpkc_update_manager_t* pManager, vpkc_update_info_t* pUpdate, vpkc_progress_callback_t cbProgress, void* pUserData = 0);
|
||||
/// \group UpdateManager
|
||||
bool vpkc_wait_exit_then_apply_update(vpkc_update_manager_t* pManager, vpkc_asset_t* pAsset, bool bSilent, bool bRestart, char** pRestartArgs, size_t cRestartArgs);
|
||||
/// \group UpdateManager
|
||||
void vpkc_free_update_manager(vpkc_update_manager_t* pManager);
|
||||
/// \group UpdateManager
|
||||
void vpkc_free_update_info(vpkc_update_info_t* pUpdateInfo);
|
||||
/// \group UpdateManager
|
||||
void vpkc_free_asset(vpkc_asset_t* pAsset);
|
||||
|
||||
/// Should be run at the beginning of your application to handle Velopack events.
|
||||
/// \group VelopackApp
|
||||
void vpkc_app_run(void* pUserData = 0);
|
||||
/// \group VelopackApp
|
||||
void vpkc_app_set_auto_apply_on_startup(bool bAutoApply);
|
||||
/// \group VelopackApp
|
||||
void vpkc_app_set_args(char** pArgs, size_t cArgs);
|
||||
/// \group VelopackApp
|
||||
void vpkc_app_set_locator(vpkc_locator_config_t* pLocator);
|
||||
/// \group VelopackApp
|
||||
void vpkc_app_set_hook_after_install(vpkc_hook_callback_t cbAfterInstall);
|
||||
/// \group VelopackApp
|
||||
void vpkc_app_set_hook_before_uninstall(vpkc_hook_callback_t cbBeforeUninstall);
|
||||
/// \group VelopackApp
|
||||
void vpkc_app_set_hook_before_update(vpkc_hook_callback_t cbBeforeUpdate);
|
||||
/// \group VelopackApp
|
||||
void vpkc_app_set_hook_after_update(vpkc_hook_callback_t cbAfterUpdate);
|
||||
/// \group VelopackApp
|
||||
void vpkc_app_set_hook_first_run(vpkc_hook_callback_t cbFirstRun);
|
||||
/// \group VelopackApp
|
||||
void vpkc_app_set_hook_restarted(vpkc_hook_callback_t cbRestarted);
|
||||
|
||||
/// Given a function has returned a failure, this function will return the last error message as a string.
|
||||
size_t vpkc_get_last_error(char* pszError, size_t cError);
|
||||
|
||||
/// Sets the callback to be used/called with log messages from Velopack.
|
||||
void vpkc_set_logger(vpkc_log_callback_t cbLog, void* pUserData = 0);
|
||||
|
||||
#ifdef __cplusplus // end of extern "C"
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
namespace Velopack {
|
||||
|
||||
static inline void throw_last_error() {
|
||||
size_t neededSize = vpkc_get_last_error(nullptr, 0);
|
||||
std::string strError(neededSize, '\0');
|
||||
vpkc_get_last_error(&strError[0], neededSize);
|
||||
throw std::runtime_error(strError);
|
||||
}
|
||||
|
||||
static inline std::string to_cppstring(const char* psz) {
|
||||
return psz == nullptr ? "" : psz;
|
||||
}
|
||||
|
||||
static inline char* to_cstring(const std::string& str) {
|
||||
return const_cast<char*>(str.c_str());
|
||||
}
|
||||
|
||||
static inline char* to_cstring_opt(const std::optional<std::string>& str) {
|
||||
return str.has_value() ? to_cstring(str.value()) : nullptr;
|
||||
}
|
||||
|
||||
static inline std::optional<std::string> to_cppstring_opt(const char* psz) {
|
||||
return psz == nullptr ? std::nullopt : std::optional<std::string>(psz);
|
||||
}
|
||||
|
||||
static inline bool to_cppbool(bool b) { return b; }
|
||||
static inline bool to_cbool(bool b) { return b; }
|
||||
static inline uint64_t to_cu64(uint64_t i) { return i; }
|
||||
static inline uint64_t to_cppu64(uint64_t i) { return i; }
|
||||
|
||||
// !! AUTO-GENERATED-START CPP_TYPES
|
||||
|
||||
/// VelopackLocator provides some utility functions for locating the current app important paths (eg. path to packages, update binary, and so forth).
|
||||
struct VelopackLocatorConfig {
|
||||
/// The root directory of the current app.
|
||||
std::string RootAppDir;
|
||||
/// The path to the Update.exe binary.
|
||||
std::string UpdateExePath;
|
||||
/// The path to the packages' directory.
|
||||
std::string PackagesDir;
|
||||
/// The current app manifest.
|
||||
std::string ManifestPath;
|
||||
/// The directory containing the application's user binaries.
|
||||
std::string CurrentBinaryDir;
|
||||
/// Whether the current application is portable or installed.
|
||||
bool IsPortable;
|
||||
};
|
||||
|
||||
/// An individual Velopack asset, could refer to an asset on-disk or in a remote package feed.
|
||||
struct VelopackAsset {
|
||||
/// The name or Id of the package containing this release.
|
||||
std::string PackageId;
|
||||
/// The version of this release.
|
||||
std::string Version;
|
||||
/// The type of asset (eg. "Full" or "Delta").
|
||||
std::string Type;
|
||||
/// The filename of the update package containing this release.
|
||||
std::string FileName;
|
||||
/// The SHA1 checksum of the update package containing this release.
|
||||
std::string SHA1;
|
||||
/// The SHA256 checksum of the update package containing this release.
|
||||
std::string SHA256;
|
||||
/// The size in bytes of the update package containing this release.
|
||||
uint64_t Size;
|
||||
/// The release notes in markdown format, as passed to Velopack when packaging the release. This may be an empty string.
|
||||
std::string NotesMarkdown;
|
||||
/// The release notes in HTML format, transformed from Markdown when packaging the release. This may be an empty string.
|
||||
std::string NotesHtml;
|
||||
};
|
||||
|
||||
/// Holds information about the current version and pending updates, such as how many there are, and access to release notes.
|
||||
struct UpdateInfo {
|
||||
/// The available version that we are updating to.
|
||||
VelopackAsset TargetFullRelease;
|
||||
/// True if the update is a version downgrade or lateral move (such as when switching channels to the same version number).
|
||||
/// In this case, only full updates are allowed, and any local packages on disk newer than the downloaded version will be
|
||||
/// deleted.
|
||||
bool IsDowngrade;
|
||||
};
|
||||
|
||||
/// Options to customise the behaviour of UpdateManager.
|
||||
struct UpdateOptions {
|
||||
/// Allows UpdateManager to update to a version that's lower than the current version (i.e. downgrading).
|
||||
/// This could happen if a release has bugs and was retracted from the release feed, or if you're using
|
||||
/// ExplicitChannel to switch channels to another channel where the latest version on that
|
||||
/// channel is lower than the current version.
|
||||
bool AllowVersionDowngrade;
|
||||
/// **This option should usually be left None**. <br/>
|
||||
/// Overrides the default channel used to fetch updates.
|
||||
/// The default channel will be whatever channel was specified on the command line when building this release.
|
||||
/// For example, if the current release was packaged with '--channel beta', then the default channel will be 'beta'.
|
||||
/// This allows users to automatically receive updates from the same channel they installed from. This options
|
||||
/// allows you to explicitly switch channels, for example if the user wished to switch back to the 'stable' channel
|
||||
/// without having to reinstall the application.
|
||||
std::optional<std::string> ExplicitChannel;
|
||||
};
|
||||
|
||||
static inline vpkc_locator_config_t to_c(const VelopackLocatorConfig& dto) {
|
||||
return {
|
||||
to_cstring(dto.RootAppDir),
|
||||
to_cstring(dto.UpdateExePath),
|
||||
to_cstring(dto.PackagesDir),
|
||||
to_cstring(dto.ManifestPath),
|
||||
to_cstring(dto.CurrentBinaryDir),
|
||||
to_cbool(dto.IsPortable),
|
||||
};
|
||||
}
|
||||
|
||||
static inline VelopackLocatorConfig to_cpp(const vpkc_locator_config_t& dto) {
|
||||
return {
|
||||
to_cppstring(dto.RootAppDir),
|
||||
to_cppstring(dto.UpdateExePath),
|
||||
to_cppstring(dto.PackagesDir),
|
||||
to_cppstring(dto.ManifestPath),
|
||||
to_cppstring(dto.CurrentBinaryDir),
|
||||
to_cppbool(dto.IsPortable),
|
||||
};
|
||||
}
|
||||
|
||||
static inline vpkc_asset_t to_c(const VelopackAsset& dto) {
|
||||
return {
|
||||
to_cstring(dto.PackageId),
|
||||
to_cstring(dto.Version),
|
||||
to_cstring(dto.Type),
|
||||
to_cstring(dto.FileName),
|
||||
to_cstring(dto.SHA1),
|
||||
to_cstring(dto.SHA256),
|
||||
to_cu64(dto.Size),
|
||||
to_cstring(dto.NotesMarkdown),
|
||||
to_cstring(dto.NotesHtml),
|
||||
};
|
||||
}
|
||||
|
||||
static inline VelopackAsset to_cpp(const vpkc_asset_t& dto) {
|
||||
return {
|
||||
to_cppstring(dto.PackageId),
|
||||
to_cppstring(dto.Version),
|
||||
to_cppstring(dto.Type),
|
||||
to_cppstring(dto.FileName),
|
||||
to_cppstring(dto.SHA1),
|
||||
to_cppstring(dto.SHA256),
|
||||
to_cppu64(dto.Size),
|
||||
to_cppstring(dto.NotesMarkdown),
|
||||
to_cppstring(dto.NotesHtml),
|
||||
};
|
||||
}
|
||||
|
||||
static inline vpkc_update_info_t to_c(const UpdateInfo& dto) {
|
||||
return {
|
||||
to_c(dto.TargetFullRelease),
|
||||
to_cbool(dto.IsDowngrade),
|
||||
};
|
||||
}
|
||||
|
||||
static inline UpdateInfo to_cpp(const vpkc_update_info_t& dto) {
|
||||
return {
|
||||
to_cpp(dto.TargetFullRelease),
|
||||
to_cppbool(dto.IsDowngrade),
|
||||
};
|
||||
}
|
||||
|
||||
static inline vpkc_update_options_t to_c(const UpdateOptions& dto) {
|
||||
return {
|
||||
to_cbool(dto.AllowVersionDowngrade),
|
||||
to_cstring_opt(dto.ExplicitChannel),
|
||||
};
|
||||
}
|
||||
|
||||
static inline UpdateOptions to_cpp(const vpkc_update_options_t& dto) {
|
||||
return {
|
||||
to_cppbool(dto.AllowVersionDowngrade),
|
||||
to_cppstring_opt(dto.ExplicitChannel),
|
||||
};
|
||||
}
|
||||
// !! AUTO-GENERATED-END CPP_TYPES
|
||||
|
||||
static inline char** to_cstring_array(const std::vector<std::string>& vec) {
|
||||
char** result = new char*[vec.size()];
|
||||
for (size_t i = 0; i < vec.size(); ++i) {
|
||||
result[i] = new char[vec[i].size() + 1]; // +1 for null-terminator
|
||||
#ifdef _WIN32
|
||||
strcpy_s(result[i], vec[i].size() + 1, vec[i].c_str()); // Copy string content
|
||||
#else
|
||||
strcpy(result[i], vec[i].c_str()); // Copy string content
|
||||
#endif
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline void free_cstring_array(char** arr, size_t size) {
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
delete[] arr[i];
|
||||
}
|
||||
delete[] arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* VelopackApp helps you to handle app activation events correctly.
|
||||
* This should be used as early as possible in your application startup code.
|
||||
* (eg. the beginning of main() or wherever your entry point is)
|
||||
*/
|
||||
class VelopackApp {
|
||||
private:
|
||||
VelopackApp() {};
|
||||
public:
|
||||
/**
|
||||
* Build a new VelopackApp instance.
|
||||
*/
|
||||
static VelopackApp Build() {
|
||||
return VelopackApp();
|
||||
};
|
||||
|
||||
/**
|
||||
* Set whether to automatically apply downloaded updates on startup. This is ON by default.
|
||||
*/
|
||||
VelopackApp& SetAutoApplyOnStartup(bool bAutoApply) {
|
||||
vpkc_app_set_auto_apply_on_startup(bAutoApply);
|
||||
return *this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Override the command line arguments used by VelopackApp. (by default this is env::args().skip(1))
|
||||
*/
|
||||
VelopackApp& SetArgs(const std::vector<std::string>& args) {
|
||||
char** pArgs = to_cstring_array(args);
|
||||
vpkc_app_set_args(pArgs, args.size());
|
||||
free_cstring_array(pArgs, args.size());
|
||||
return *this;
|
||||
};
|
||||
|
||||
/**
|
||||
* VelopackLocator provides some utility functions for locating the current app important paths (eg. path to packages, update binary, and so forth).
|
||||
*/
|
||||
VelopackApp& SetLocator(const VelopackLocatorConfig& locator) {
|
||||
vpkc_locator_config_t vpkc_locator = to_c(locator);
|
||||
vpkc_app_set_locator(&vpkc_locator);
|
||||
return *this;
|
||||
};
|
||||
|
||||
/**
|
||||
* WARNING: FastCallback hooks are run during critical stages of Velopack operations.
|
||||
* Your code will be run and then the process will exit.
|
||||
* If your code has not completed within 30 seconds, it will be terminated.
|
||||
* Only supported on windows; On other operating systems, this will never be called.
|
||||
*/
|
||||
VelopackApp& OnAfterInstall(vpkc_hook_callback_t cbInstall) {
|
||||
vpkc_app_set_hook_after_install(cbInstall);
|
||||
return *this;
|
||||
};
|
||||
|
||||
/**
|
||||
* WARNING: FastCallback hooks are run during critical stages of Velopack operations.
|
||||
* Your code will be run and then the process will exit.
|
||||
* If your code has not completed within 30 seconds, it will be terminated.
|
||||
* Only supported on windows; On other operating systems, this will never be called.
|
||||
*/
|
||||
VelopackApp& OnBeforeUninstall(vpkc_hook_callback_t cbInstall) {
|
||||
vpkc_app_set_hook_before_uninstall(cbInstall);
|
||||
return *this;
|
||||
};
|
||||
|
||||
/**
|
||||
* WARNING: FastCallback hooks are run during critical stages of Velopack operations.
|
||||
* Your code will be run and then the process will exit.
|
||||
* If your code has not completed within 30 seconds, it will be terminated.
|
||||
* Only supported on windows; On other operating systems, this will never be called.
|
||||
*/
|
||||
VelopackApp& OnBeforeUpdate(vpkc_hook_callback_t cbInstall) {
|
||||
vpkc_app_set_hook_before_update(cbInstall);
|
||||
return *this;
|
||||
};
|
||||
|
||||
/**
|
||||
* WARNING: FastCallback hooks are run during critical stages of Velopack operations.
|
||||
* Your code will be run and then the process will exit.
|
||||
* If your code has not completed within 30 seconds, it will be terminated.
|
||||
* Only supported on windows; On other operating systems, this will never be called.
|
||||
*/
|
||||
VelopackApp& OnAfterUpdate(vpkc_hook_callback_t cbInstall) {
|
||||
vpkc_app_set_hook_after_update(cbInstall);
|
||||
return *this;
|
||||
};
|
||||
|
||||
/**
|
||||
* This hook is triggered when the application is started for the first time after installation.
|
||||
*/
|
||||
VelopackApp& OnFirstRun(vpkc_hook_callback_t cbInstall) {
|
||||
vpkc_app_set_hook_first_run(cbInstall);
|
||||
return *this;
|
||||
};
|
||||
|
||||
/**
|
||||
* This hook is triggered when the application is restarted by Velopack after installing updates.
|
||||
*/
|
||||
VelopackApp& OnRestarted(vpkc_hook_callback_t cbInstall) {
|
||||
vpkc_app_set_hook_restarted(cbInstall);
|
||||
return *this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Runs the Velopack startup logic. This should be the first thing to run in your app.
|
||||
* In some circumstances it may terminate/restart the process to perform tasks.
|
||||
*/
|
||||
void Run(void* pUserData = 0) {
|
||||
vpkc_app_run(pUserData);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Provides functionality for checking for updates, downloading updates, and applying updates to the current application.
|
||||
*/
|
||||
class UpdateManager {
|
||||
private:
|
||||
vpkc_update_manager_t* m_pManager = 0;
|
||||
public:
|
||||
/**
|
||||
* Create a new UpdateManager instance.
|
||||
* @param urlOrPath Location of the update server or path to the local update directory.
|
||||
* @param options Optional extra configuration for update manager.
|
||||
* @param locator Override the default locator configuration (usually used for testing / mocks).
|
||||
*/
|
||||
UpdateManager(const std::string& urlOrPath, const UpdateOptions* options = nullptr, const VelopackLocatorConfig* locator = nullptr) {
|
||||
vpkc_update_options_t* pOptions = nullptr;
|
||||
if (options != nullptr) {
|
||||
vpkc_update_options_t vpkc_options = to_c(*options);
|
||||
pOptions = &vpkc_options;
|
||||
}
|
||||
|
||||
vpkc_locator_config_t* pLocator = nullptr;
|
||||
if (locator != nullptr) {
|
||||
vpkc_locator_config_t vpkc_locator = to_c(*locator);
|
||||
pLocator = &vpkc_locator;
|
||||
}
|
||||
|
||||
if (!vpkc_new_update_manager(urlOrPath.c_str(), pOptions, pLocator, &m_pManager)) {
|
||||
throw_last_error();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Destructor for UpdateManager.
|
||||
*/
|
||||
~UpdateManager() {
|
||||
vpkc_free_update_manager(m_pManager);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns whether the app is in portable mode. On Windows this can be true or false.
|
||||
* On MacOS and Linux this will always be true.
|
||||
*/
|
||||
bool IsPortable() noexcept {
|
||||
return vpkc_is_portable(m_pManager);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the currently installed version of the app.
|
||||
*/
|
||||
std::string GetCurrentVersion() noexcept {
|
||||
size_t neededSize = vpkc_get_current_version(m_pManager, nullptr, 0);
|
||||
std::string strVersion(neededSize, '\0');
|
||||
vpkc_get_current_version(m_pManager, &strVersion[0], neededSize);
|
||||
return strVersion;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the currently installed app id.
|
||||
*/
|
||||
std::string GetAppId() noexcept {
|
||||
size_t neededSize = vpkc_get_app_id(m_pManager, nullptr, 0);
|
||||
std::string strId(neededSize, '\0');
|
||||
vpkc_get_app_id(m_pManager, &strId[0], neededSize);
|
||||
return strId;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns an UpdateInfo object if there is an update downloaded which still needs to be applied.
|
||||
* You can pass the UpdateInfo object to waitExitThenApplyUpdate to apply the update.
|
||||
*/
|
||||
std::optional<VelopackAsset> UpdatePendingRestart() noexcept {
|
||||
vpkc_asset_t asset;
|
||||
if (vpkc_update_pending_restart(m_pManager, &asset)) {
|
||||
VelopackAsset cpp_asset = to_cpp(asset);
|
||||
vpkc_free_asset(&asset);
|
||||
return cpp_asset;
|
||||
}
|
||||
return std::nullopt;
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks for updates, returning None if there are none available. If there are updates available, this method will return an
|
||||
* UpdateInfo object containing the latest available release, and any delta updates that can be applied if they are available.
|
||||
*/
|
||||
std::optional<UpdateInfo> CheckForUpdates() {
|
||||
vpkc_update_info_t update;
|
||||
vpkc_update_check_t result = vpkc_check_for_updates(m_pManager, &update);
|
||||
switch (result) {
|
||||
case vpkc_update_check_t::UPDATE_ERROR:
|
||||
throw_last_error();
|
||||
return std::nullopt;
|
||||
case vpkc_update_check_t::NO_UPDATE_AVAILABLE:
|
||||
case vpkc_update_check_t::REMOTE_IS_EMPTY:
|
||||
return std::nullopt;
|
||||
case vpkc_update_check_t::UPDATE_AVAILABLE:
|
||||
UpdateInfo cpp_info = to_cpp(update);
|
||||
vpkc_free_update_info(&update);
|
||||
return cpp_info;
|
||||
}
|
||||
return std::nullopt;
|
||||
};
|
||||
|
||||
/**
|
||||
* Downloads the specified updates to the local app packages directory. Progress is reported back to the caller via an optional Sender.
|
||||
* This function will acquire a global update lock so may fail if there is already another update operation in progress.
|
||||
* - If the update contains delta packages and the delta feature is enabled
|
||||
* this method will attempt to unpack and prepare them.
|
||||
* - If there is no delta update available, or there is an error preparing delta
|
||||
* packages, this method will fall back to downloading the full version of the update.
|
||||
*/
|
||||
void DownloadUpdates(const UpdateInfo& update, vpkc_progress_callback_t progress = nullptr, void* pUserData = 0) {
|
||||
vpkc_update_info_t vpkc_update = to_c(update);
|
||||
if (!vpkc_download_updates(m_pManager, &vpkc_update, progress, pUserData)) {
|
||||
throw_last_error();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This will launch the Velopack updater and tell it to wait for this program to exit gracefully.
|
||||
* You should then clean up any state and exit your app. The updater will apply updates and then
|
||||
* optionally restart your app. The updater will only wait for 60 seconds before giving up.
|
||||
*/
|
||||
void WaitExitThenApplyUpdate(const VelopackAsset& asset, bool silent = false, bool restart = true, std::vector<std::string> restartArgs = {}) {
|
||||
char** pRestartArgs = to_cstring_array(restartArgs);
|
||||
vpkc_asset_t vpkc_asset = to_c(asset);
|
||||
bool result = vpkc_wait_exit_then_apply_update(m_pManager, &vpkc_asset, silent, restart, pRestartArgs, restartArgs.size());
|
||||
free_cstring_array(pRestartArgs, restartArgs.size());
|
||||
|
||||
if (!result) {
|
||||
throw_last_error();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This will launch the Velopack updater and tell it to wait for this program to exit gracefully.
|
||||
* You should then clean up any state and exit your app. The updater will apply updates and then
|
||||
* optionally restart your app. The updater will only wait for 60 seconds before giving up.
|
||||
*/
|
||||
void WaitExitThenApplyUpdate(const UpdateInfo& asset, bool silent = false, bool restart = true, std::vector<std::string> restartArgs = {}) {
|
||||
this->WaitExitThenApplyUpdate(asset.TargetFullRelease, silent, restart, restartArgs);
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace Velopack
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // VELOPACK_H
|
||||
bool vpkc_new_update_manager(const char *psz_url_or_string,
|
||||
struct vpkc_update_options_t *p_options,
|
||||
struct vpkc_locator_config_t *p_locator,
|
||||
vpkc_update_manager_t **p_manager);
|
||||
|
||||
size_t vpkc_get_current_version(vpkc_update_manager_t *p_manager,
|
||||
char *psz_version,
|
||||
size_t c_version);
|
||||
|
||||
size_t vpkc_get_app_id(vpkc_update_manager_t *p_manager, char *psz_id, size_t c_id);
|
||||
|
||||
bool vpkc_is_portable(vpkc_update_manager_t *p_manager);
|
||||
|
||||
bool vpkc_update_pending_restart(vpkc_update_manager_t *p_manager, struct vpkc_asset_t *p_asset);
|
||||
|
||||
vpkc_update_check_t vpkc_check_for_updates(vpkc_update_manager_t *p_manager,
|
||||
struct vpkc_update_info_t *p_update);
|
||||
|
||||
bool vpkc_download_updates(vpkc_update_manager_t *p_manager,
|
||||
struct vpkc_update_info_t *p_update,
|
||||
vpkc_progress_callback_t cb_progress,
|
||||
void *p_user_data);
|
||||
|
||||
bool vpkc_wait_exit_then_apply_update(vpkc_update_manager_t *p_manager,
|
||||
struct vpkc_asset_t *p_asset,
|
||||
bool b_silent,
|
||||
bool b_restart,
|
||||
char **p_restart_args,
|
||||
size_t c_restart_args);
|
||||
|
||||
void vpkc_free_update_manager(vpkc_update_manager_t *p_manager);
|
||||
|
||||
void vpkc_free_update_info(struct vpkc_update_info_t *p_update_info);
|
||||
|
||||
void vpkc_free_asset(struct vpkc_asset_t *p_asset);
|
||||
|
||||
void vpkc_app_run(void *p_user_data);
|
||||
|
||||
void vpkc_app_set_auto_apply_on_startup(bool b_auto_apply);
|
||||
|
||||
void vpkc_app_set_args(char **p_args, size_t c_args);
|
||||
|
||||
void vpkc_app_set_locator(struct vpkc_locator_config_t *p_locator);
|
||||
|
||||
void vpkc_app_set_hook_after_install(vpkc_hook_callback_t cb_after_install);
|
||||
|
||||
void vpkc_app_set_hook_before_uninstall(vpkc_hook_callback_t cb_before_uninstall);
|
||||
|
||||
void vpkc_app_set_hook_before_update(vpkc_hook_callback_t cb_before_update);
|
||||
|
||||
void vpkc_app_set_hook_after_update(vpkc_hook_callback_t cb_after_update);
|
||||
|
||||
void vpkc_app_set_hook_first_run(vpkc_hook_callback_t cb_first_run);
|
||||
|
||||
void vpkc_app_set_hook_restarted(vpkc_hook_callback_t cb_restarted);
|
||||
|
||||
size_t vpkc_get_last_error(char *psz_error, size_t c_error);
|
||||
|
||||
void vpkc_set_logger(vpkc_log_callback_t cb_log, void *p_user_data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif /* VELOPACK_H */
|
||||
|
||||
471
src/lib-cpp/include/Velopack.hpp
Normal file
471
src/lib-cpp/include/Velopack.hpp
Normal file
@@ -0,0 +1,471 @@
|
||||
//! This header provides the C++ API for the Velopack library.
|
||||
//! This C++ API is a thin wrapper around the C API, providing a more idiomatic C++ interface.
|
||||
//! You should not mix and match the C and C++ APIs in the same program.
|
||||
#ifndef VELOPACK_HPP
|
||||
#define VELOPACK_HPP
|
||||
|
||||
#include <string>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "Velopack.h"
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
namespace Velopack {
|
||||
|
||||
static inline void throw_last_error() {
|
||||
size_t neededSize = vpkc_get_last_error(nullptr, 0);
|
||||
std::string strError(neededSize, '\0');
|
||||
vpkc_get_last_error(&strError[0], neededSize);
|
||||
throw std::runtime_error(strError);
|
||||
}
|
||||
|
||||
static inline std::string to_cppstring(const char* psz) {
|
||||
return psz == nullptr ? "" : psz;
|
||||
}
|
||||
|
||||
static inline char* to_cstring(const std::string& str) {
|
||||
return const_cast<char*>(str.c_str());
|
||||
}
|
||||
|
||||
static inline char* to_cstring_opt(const std::optional<std::string>& str) {
|
||||
return str.has_value() ? to_cstring(str.value()) : nullptr;
|
||||
}
|
||||
|
||||
static inline std::optional<std::string> to_cppstring_opt(const char* psz) {
|
||||
return psz == nullptr ? std::nullopt : std::optional<std::string>(psz);
|
||||
}
|
||||
|
||||
static inline bool to_cppbool(bool b) { return b; }
|
||||
static inline bool to_cbool(bool b) { return b; }
|
||||
static inline uint64_t to_cu64(uint64_t i) { return i; }
|
||||
static inline uint64_t to_cppu64(uint64_t i) { return i; }
|
||||
|
||||
// !! AUTO-GENERATED-START CPP_TYPES
|
||||
|
||||
/// VelopackLocator provides some utility functions for locating the current app important paths (eg. path to packages, update binary, and so forth).
|
||||
struct VelopackLocatorConfig {
|
||||
/// The root directory of the current app.
|
||||
std::string RootAppDir;
|
||||
/// The path to the Update.exe binary.
|
||||
std::string UpdateExePath;
|
||||
/// The path to the packages' directory.
|
||||
std::string PackagesDir;
|
||||
/// The current app manifest.
|
||||
std::string ManifestPath;
|
||||
/// The directory containing the application's user binaries.
|
||||
std::string CurrentBinaryDir;
|
||||
/// Whether the current application is portable or installed.
|
||||
bool IsPortable;
|
||||
};
|
||||
|
||||
/// An individual Velopack asset, could refer to an asset on-disk or in a remote package feed.
|
||||
struct VelopackAsset {
|
||||
/// The name or Id of the package containing this release.
|
||||
std::string PackageId;
|
||||
/// The version of this release.
|
||||
std::string Version;
|
||||
/// The type of asset (eg. "Full" or "Delta").
|
||||
std::string Type;
|
||||
/// The filename of the update package containing this release.
|
||||
std::string FileName;
|
||||
/// The SHA1 checksum of the update package containing this release.
|
||||
std::string SHA1;
|
||||
/// The SHA256 checksum of the update package containing this release.
|
||||
std::string SHA256;
|
||||
/// The size in bytes of the update package containing this release.
|
||||
uint64_t Size;
|
||||
/// The release notes in markdown format, as passed to Velopack when packaging the release. This may be an empty string.
|
||||
std::string NotesMarkdown;
|
||||
/// The release notes in HTML format, transformed from Markdown when packaging the release. This may be an empty string.
|
||||
std::string NotesHtml;
|
||||
};
|
||||
|
||||
/// Holds information about the current version and pending updates, such as how many there are, and access to release notes.
|
||||
struct UpdateInfo {
|
||||
/// The available version that we are updating to.
|
||||
VelopackAsset TargetFullRelease;
|
||||
/// True if the update is a version downgrade or lateral move (such as when switching channels to the same version number).
|
||||
/// In this case, only full updates are allowed, and any local packages on disk newer than the downloaded version will be
|
||||
/// deleted.
|
||||
bool IsDowngrade;
|
||||
};
|
||||
|
||||
/// Options to customise the behaviour of UpdateManager.
|
||||
struct UpdateOptions {
|
||||
/// Allows UpdateManager to update to a version that's lower than the current version (i.e. downgrading).
|
||||
/// This could happen if a release has bugs and was retracted from the release feed, or if you're using
|
||||
/// ExplicitChannel to switch channels to another channel where the latest version on that
|
||||
/// channel is lower than the current version.
|
||||
bool AllowVersionDowngrade;
|
||||
/// **This option should usually be left None**. <br/>
|
||||
/// Overrides the default channel used to fetch updates.
|
||||
/// The default channel will be whatever channel was specified on the command line when building this release.
|
||||
/// For example, if the current release was packaged with '--channel beta', then the default channel will be 'beta'.
|
||||
/// This allows users to automatically receive updates from the same channel they installed from. This options
|
||||
/// allows you to explicitly switch channels, for example if the user wished to switch back to the 'stable' channel
|
||||
/// without having to reinstall the application.
|
||||
std::optional<std::string> ExplicitChannel;
|
||||
};
|
||||
|
||||
static inline vpkc_locator_config_t to_c(const VelopackLocatorConfig& dto) {
|
||||
return {
|
||||
to_cstring(dto.RootAppDir),
|
||||
to_cstring(dto.UpdateExePath),
|
||||
to_cstring(dto.PackagesDir),
|
||||
to_cstring(dto.ManifestPath),
|
||||
to_cstring(dto.CurrentBinaryDir),
|
||||
to_cbool(dto.IsPortable),
|
||||
};
|
||||
}
|
||||
|
||||
static inline VelopackLocatorConfig to_cpp(const vpkc_locator_config_t& dto) {
|
||||
return {
|
||||
to_cppstring(dto.RootAppDir),
|
||||
to_cppstring(dto.UpdateExePath),
|
||||
to_cppstring(dto.PackagesDir),
|
||||
to_cppstring(dto.ManifestPath),
|
||||
to_cppstring(dto.CurrentBinaryDir),
|
||||
to_cppbool(dto.IsPortable),
|
||||
};
|
||||
}
|
||||
|
||||
static inline vpkc_asset_t to_c(const VelopackAsset& dto) {
|
||||
return {
|
||||
to_cstring(dto.PackageId),
|
||||
to_cstring(dto.Version),
|
||||
to_cstring(dto.Type),
|
||||
to_cstring(dto.FileName),
|
||||
to_cstring(dto.SHA1),
|
||||
to_cstring(dto.SHA256),
|
||||
to_cu64(dto.Size),
|
||||
to_cstring(dto.NotesMarkdown),
|
||||
to_cstring(dto.NotesHtml),
|
||||
};
|
||||
}
|
||||
|
||||
static inline VelopackAsset to_cpp(const vpkc_asset_t& dto) {
|
||||
return {
|
||||
to_cppstring(dto.PackageId),
|
||||
to_cppstring(dto.Version),
|
||||
to_cppstring(dto.Type),
|
||||
to_cppstring(dto.FileName),
|
||||
to_cppstring(dto.SHA1),
|
||||
to_cppstring(dto.SHA256),
|
||||
to_cppu64(dto.Size),
|
||||
to_cppstring(dto.NotesMarkdown),
|
||||
to_cppstring(dto.NotesHtml),
|
||||
};
|
||||
}
|
||||
|
||||
static inline vpkc_update_info_t to_c(const UpdateInfo& dto) {
|
||||
return {
|
||||
to_c(dto.TargetFullRelease),
|
||||
to_cbool(dto.IsDowngrade),
|
||||
};
|
||||
}
|
||||
|
||||
static inline UpdateInfo to_cpp(const vpkc_update_info_t& dto) {
|
||||
return {
|
||||
to_cpp(dto.TargetFullRelease),
|
||||
to_cppbool(dto.IsDowngrade),
|
||||
};
|
||||
}
|
||||
|
||||
static inline vpkc_update_options_t to_c(const UpdateOptions& dto) {
|
||||
return {
|
||||
to_cbool(dto.AllowVersionDowngrade),
|
||||
to_cstring_opt(dto.ExplicitChannel),
|
||||
};
|
||||
}
|
||||
|
||||
static inline UpdateOptions to_cpp(const vpkc_update_options_t& dto) {
|
||||
return {
|
||||
to_cppbool(dto.AllowVersionDowngrade),
|
||||
to_cppstring_opt(dto.ExplicitChannel),
|
||||
};
|
||||
}
|
||||
// !! AUTO-GENERATED-END CPP_TYPES
|
||||
|
||||
static inline char** to_cstring_array(const std::vector<std::string>& vec) {
|
||||
char** result = new char*[vec.size()];
|
||||
for (size_t i = 0; i < vec.size(); ++i) {
|
||||
result[i] = new char[vec[i].size() + 1]; // +1 for null-terminator
|
||||
#ifdef _WIN32
|
||||
strcpy_s(result[i], vec[i].size() + 1, vec[i].c_str()); // Copy string content
|
||||
#else
|
||||
strcpy(result[i], vec[i].c_str()); // Copy string content
|
||||
#endif
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline void free_cstring_array(char** arr, size_t size) {
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
delete[] arr[i];
|
||||
}
|
||||
delete[] arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* VelopackApp helps you to handle app activation events correctly.
|
||||
* This should be used as early as possible in your application startup code.
|
||||
* (eg. the beginning of main() or wherever your entry point is)
|
||||
*/
|
||||
class VelopackApp {
|
||||
private:
|
||||
VelopackApp() {};
|
||||
public:
|
||||
/**
|
||||
* Build a new VelopackApp instance.
|
||||
*/
|
||||
static VelopackApp Build() {
|
||||
return VelopackApp();
|
||||
};
|
||||
|
||||
/**
|
||||
* Set whether to automatically apply downloaded updates on startup. This is ON by default.
|
||||
*/
|
||||
VelopackApp& SetAutoApplyOnStartup(bool bAutoApply) {
|
||||
vpkc_app_set_auto_apply_on_startup(bAutoApply);
|
||||
return *this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Override the command line arguments used by VelopackApp. (by default this is env::args().skip(1))
|
||||
*/
|
||||
VelopackApp& SetArgs(const std::vector<std::string>& args) {
|
||||
char** pArgs = to_cstring_array(args);
|
||||
vpkc_app_set_args(pArgs, args.size());
|
||||
free_cstring_array(pArgs, args.size());
|
||||
return *this;
|
||||
};
|
||||
|
||||
/**
|
||||
* VelopackLocator provides some utility functions for locating the current app important paths (eg. path to packages, update binary, and so forth).
|
||||
*/
|
||||
VelopackApp& SetLocator(const VelopackLocatorConfig& locator) {
|
||||
vpkc_locator_config_t vpkc_locator = to_c(locator);
|
||||
vpkc_app_set_locator(&vpkc_locator);
|
||||
return *this;
|
||||
};
|
||||
|
||||
/**
|
||||
* WARNING: FastCallback hooks are run during critical stages of Velopack operations.
|
||||
* Your code will be run and then the process will exit.
|
||||
* If your code has not completed within 30 seconds, it will be terminated.
|
||||
* Only supported on windows; On other operating systems, this will never be called.
|
||||
*/
|
||||
VelopackApp& OnAfterInstall(vpkc_hook_callback_t cbInstall) {
|
||||
vpkc_app_set_hook_after_install(cbInstall);
|
||||
return *this;
|
||||
};
|
||||
|
||||
/**
|
||||
* WARNING: FastCallback hooks are run during critical stages of Velopack operations.
|
||||
* Your code will be run and then the process will exit.
|
||||
* If your code has not completed within 30 seconds, it will be terminated.
|
||||
* Only supported on windows; On other operating systems, this will never be called.
|
||||
*/
|
||||
VelopackApp& OnBeforeUninstall(vpkc_hook_callback_t cbInstall) {
|
||||
vpkc_app_set_hook_before_uninstall(cbInstall);
|
||||
return *this;
|
||||
};
|
||||
|
||||
/**
|
||||
* WARNING: FastCallback hooks are run during critical stages of Velopack operations.
|
||||
* Your code will be run and then the process will exit.
|
||||
* If your code has not completed within 30 seconds, it will be terminated.
|
||||
* Only supported on windows; On other operating systems, this will never be called.
|
||||
*/
|
||||
VelopackApp& OnBeforeUpdate(vpkc_hook_callback_t cbInstall) {
|
||||
vpkc_app_set_hook_before_update(cbInstall);
|
||||
return *this;
|
||||
};
|
||||
|
||||
/**
|
||||
* WARNING: FastCallback hooks are run during critical stages of Velopack operations.
|
||||
* Your code will be run and then the process will exit.
|
||||
* If your code has not completed within 30 seconds, it will be terminated.
|
||||
* Only supported on windows; On other operating systems, this will never be called.
|
||||
*/
|
||||
VelopackApp& OnAfterUpdate(vpkc_hook_callback_t cbInstall) {
|
||||
vpkc_app_set_hook_after_update(cbInstall);
|
||||
return *this;
|
||||
};
|
||||
|
||||
/**
|
||||
* This hook is triggered when the application is started for the first time after installation.
|
||||
*/
|
||||
VelopackApp& OnFirstRun(vpkc_hook_callback_t cbInstall) {
|
||||
vpkc_app_set_hook_first_run(cbInstall);
|
||||
return *this;
|
||||
};
|
||||
|
||||
/**
|
||||
* This hook is triggered when the application is restarted by Velopack after installing updates.
|
||||
*/
|
||||
VelopackApp& OnRestarted(vpkc_hook_callback_t cbInstall) {
|
||||
vpkc_app_set_hook_restarted(cbInstall);
|
||||
return *this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Runs the Velopack startup logic. This should be the first thing to run in your app.
|
||||
* In some circumstances it may terminate/restart the process to perform tasks.
|
||||
*/
|
||||
void Run(void* pUserData = 0) {
|
||||
vpkc_app_run(pUserData);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Provides functionality for checking for updates, downloading updates, and applying updates to the current application.
|
||||
*/
|
||||
class UpdateManager {
|
||||
private:
|
||||
vpkc_update_manager_t* m_pManager = 0;
|
||||
public:
|
||||
/**
|
||||
* Create a new UpdateManager instance.
|
||||
* @param urlOrPath Location of the update server or path to the local update directory.
|
||||
* @param options Optional extra configuration for update manager.
|
||||
* @param locator Override the default locator configuration (usually used for testing / mocks).
|
||||
*/
|
||||
UpdateManager(const std::string& urlOrPath, const UpdateOptions* options = nullptr, const VelopackLocatorConfig* locator = nullptr) {
|
||||
vpkc_update_options_t* pOptions = nullptr;
|
||||
if (options != nullptr) {
|
||||
vpkc_update_options_t vpkc_options = to_c(*options);
|
||||
pOptions = &vpkc_options;
|
||||
}
|
||||
|
||||
vpkc_locator_config_t* pLocator = nullptr;
|
||||
if (locator != nullptr) {
|
||||
vpkc_locator_config_t vpkc_locator = to_c(*locator);
|
||||
pLocator = &vpkc_locator;
|
||||
}
|
||||
|
||||
if (!vpkc_new_update_manager(urlOrPath.c_str(), pOptions, pLocator, &m_pManager)) {
|
||||
throw_last_error();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Destructor for UpdateManager.
|
||||
*/
|
||||
~UpdateManager() {
|
||||
vpkc_free_update_manager(m_pManager);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns whether the app is in portable mode. On Windows this can be true or false.
|
||||
* On MacOS and Linux this will always be true.
|
||||
*/
|
||||
bool IsPortable() noexcept {
|
||||
return vpkc_is_portable(m_pManager);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the currently installed version of the app.
|
||||
*/
|
||||
std::string GetCurrentVersion() noexcept {
|
||||
size_t neededSize = vpkc_get_current_version(m_pManager, nullptr, 0);
|
||||
std::string strVersion(neededSize, '\0');
|
||||
vpkc_get_current_version(m_pManager, &strVersion[0], neededSize);
|
||||
return strVersion;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the currently installed app id.
|
||||
*/
|
||||
std::string GetAppId() noexcept {
|
||||
size_t neededSize = vpkc_get_app_id(m_pManager, nullptr, 0);
|
||||
std::string strId(neededSize, '\0');
|
||||
vpkc_get_app_id(m_pManager, &strId[0], neededSize);
|
||||
return strId;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns an UpdateInfo object if there is an update downloaded which still needs to be applied.
|
||||
* You can pass the UpdateInfo object to waitExitThenApplyUpdate to apply the update.
|
||||
*/
|
||||
std::optional<VelopackAsset> UpdatePendingRestart() noexcept {
|
||||
vpkc_asset_t asset;
|
||||
if (vpkc_update_pending_restart(m_pManager, &asset)) {
|
||||
VelopackAsset cpp_asset = to_cpp(asset);
|
||||
vpkc_free_asset(&asset);
|
||||
return cpp_asset;
|
||||
}
|
||||
return std::nullopt;
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks for updates, returning None if there are none available. If there are updates available, this method will return an
|
||||
* UpdateInfo object containing the latest available release, and any delta updates that can be applied if they are available.
|
||||
*/
|
||||
std::optional<UpdateInfo> CheckForUpdates() {
|
||||
vpkc_update_info_t update;
|
||||
vpkc_update_check_t result = vpkc_check_for_updates(m_pManager, &update);
|
||||
switch (result) {
|
||||
case vpkc_update_check_t::UPDATE_ERROR:
|
||||
throw_last_error();
|
||||
return std::nullopt;
|
||||
case vpkc_update_check_t::NO_UPDATE_AVAILABLE:
|
||||
case vpkc_update_check_t::REMOTE_IS_EMPTY:
|
||||
return std::nullopt;
|
||||
case vpkc_update_check_t::UPDATE_AVAILABLE:
|
||||
UpdateInfo cpp_info = to_cpp(update);
|
||||
vpkc_free_update_info(&update);
|
||||
return cpp_info;
|
||||
}
|
||||
return std::nullopt;
|
||||
};
|
||||
|
||||
/**
|
||||
* Downloads the specified updates to the local app packages directory. Progress is reported back to the caller via an optional Sender.
|
||||
* This function will acquire a global update lock so may fail if there is already another update operation in progress.
|
||||
* - If the update contains delta packages and the delta feature is enabled
|
||||
* this method will attempt to unpack and prepare them.
|
||||
* - If there is no delta update available, or there is an error preparing delta
|
||||
* packages, this method will fall back to downloading the full version of the update.
|
||||
*/
|
||||
void DownloadUpdates(const UpdateInfo& update, vpkc_progress_callback_t progress = nullptr, void* pUserData = 0) {
|
||||
vpkc_update_info_t vpkc_update = to_c(update);
|
||||
if (!vpkc_download_updates(m_pManager, &vpkc_update, progress, pUserData)) {
|
||||
throw_last_error();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This will launch the Velopack updater and tell it to wait for this program to exit gracefully.
|
||||
* You should then clean up any state and exit your app. The updater will apply updates and then
|
||||
* optionally restart your app. The updater will only wait for 60 seconds before giving up.
|
||||
*/
|
||||
void WaitExitThenApplyUpdate(const VelopackAsset& asset, bool silent = false, bool restart = true, std::vector<std::string> restartArgs = {}) {
|
||||
char** pRestartArgs = to_cstring_array(restartArgs);
|
||||
vpkc_asset_t vpkc_asset = to_c(asset);
|
||||
bool result = vpkc_wait_exit_then_apply_update(m_pManager, &vpkc_asset, silent, restart, pRestartArgs, restartArgs.size());
|
||||
free_cstring_array(pRestartArgs, restartArgs.size());
|
||||
|
||||
if (!result) {
|
||||
throw_last_error();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This will launch the Velopack updater and tell it to wait for this program to exit gracefully.
|
||||
* You should then clean up any state and exit your app. The updater will apply updates and then
|
||||
* optionally restart your app. The updater will only wait for 60 seconds before giving up.
|
||||
*/
|
||||
void WaitExitThenApplyUpdate(const UpdateInfo& asset, bool silent = false, bool restart = true, std::vector<std::string> restartArgs = {}) {
|
||||
this->WaitExitThenApplyUpdate(asset.TargetFullRelease, silent, restart, restartArgs);
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace Velopack
|
||||
|
||||
#endif // VELOPACK_HPP
|
||||
@@ -9,23 +9,16 @@ mod types;
|
||||
use types::*;
|
||||
|
||||
use anyhow::{anyhow, bail};
|
||||
use std::ffi::{c_char, c_void, CString};
|
||||
use std::ffi::CString;
|
||||
use libc::{size_t, c_char, c_void};
|
||||
use velopack::{sources, Error as VelopackError, UpdateCheck, UpdateManager, VelopackApp};
|
||||
|
||||
#[repr(C)]
|
||||
pub enum vpkc_update_check_t {
|
||||
UPDATE_ERROR = -1,
|
||||
UPDATE_AVAILABLE = 0,
|
||||
NO_UPDATE_AVAILABLE = 1,
|
||||
REMOTE_IS_EMPTY = 2,
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn vpkc_new_update_manager(
|
||||
psz_url_or_string: *const c_char,
|
||||
p_options: *mut vpkc_update_options_t,
|
||||
p_locator: *mut vpkc_locator_config_t,
|
||||
p_manager: *mut *mut c_void,
|
||||
p_manager: *mut *mut vpkc_update_manager_t,
|
||||
) -> bool {
|
||||
wrap_error(|| {
|
||||
let update_url = c_to_string_opt(psz_url_or_string).ok_or(anyhow!("URL or path is null"))?;
|
||||
@@ -34,13 +27,13 @@ pub extern "C" fn vpkc_new_update_manager(
|
||||
let locator = c_to_velopacklocatorconfig_opt(p_locator);
|
||||
let manager = UpdateManager::new(source, options, locator)?;
|
||||
let opaque = Box::new(UpdateManagerOpaque::new(manager));
|
||||
unsafe { *p_manager = Box::into_raw(opaque) as *mut c_void };
|
||||
unsafe { *p_manager = Box::into_raw(opaque) as *mut vpkc_update_manager_t };
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn vpkc_get_current_version(p_manager: *mut c_void, psz_version: *mut c_char, c_version: usize) -> usize {
|
||||
pub extern "C" fn vpkc_get_current_version(p_manager: *mut vpkc_update_manager_t, psz_version: *mut c_char, c_version: size_t) -> size_t {
|
||||
if p_manager.is_null() {
|
||||
return 0;
|
||||
}
|
||||
@@ -51,7 +44,7 @@ pub extern "C" fn vpkc_get_current_version(p_manager: *mut c_void, psz_version:
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn vpkc_get_app_id(p_manager: *mut c_void, psz_id: *mut c_char, c_id: usize) -> usize {
|
||||
pub extern "C" fn vpkc_get_app_id(p_manager: *mut vpkc_update_manager_t, psz_id: *mut c_char, c_id: size_t) -> size_t {
|
||||
if p_manager.is_null() {
|
||||
return 0;
|
||||
}
|
||||
@@ -62,7 +55,7 @@ pub extern "C" fn vpkc_get_app_id(p_manager: *mut c_void, psz_id: *mut c_char, c
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn vpkc_is_portable(p_manager: *mut c_void) -> bool {
|
||||
pub extern "C" fn vpkc_is_portable(p_manager: *mut vpkc_update_manager_t) -> bool {
|
||||
if p_manager.is_null() {
|
||||
return false;
|
||||
}
|
||||
@@ -72,7 +65,7 @@ pub extern "C" fn vpkc_is_portable(p_manager: *mut c_void) -> bool {
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn vpkc_update_pending_restart(p_manager: *mut c_void, p_asset: *mut vpkc_asset_t) -> bool {
|
||||
pub extern "C" fn vpkc_update_pending_restart(p_manager: *mut vpkc_update_manager_t, p_asset: *mut vpkc_asset_t) -> bool {
|
||||
if p_manager.is_null() {
|
||||
return false;
|
||||
}
|
||||
@@ -89,7 +82,7 @@ pub extern "C" fn vpkc_update_pending_restart(p_manager: *mut c_void, p_asset: *
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn vpkc_check_for_updates(p_manager: *mut c_void, p_update: *mut vpkc_update_info_t) -> vpkc_update_check_t {
|
||||
pub extern "C" fn vpkc_check_for_updates(p_manager: *mut vpkc_update_manager_t, p_update: *mut vpkc_update_info_t) -> vpkc_update_check_t {
|
||||
if p_manager.is_null() {
|
||||
set_last_error("pManager must not be null");
|
||||
return vpkc_update_check_t::UPDATE_ERROR;
|
||||
@@ -115,7 +108,7 @@ pub extern "C" fn vpkc_check_for_updates(p_manager: *mut c_void, p_update: *mut
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn vpkc_download_updates(
|
||||
p_manager: *mut c_void,
|
||||
p_manager: *mut vpkc_update_manager_t,
|
||||
p_update: *mut vpkc_update_info_t,
|
||||
cb_progress: vpkc_progress_callback_t,
|
||||
p_user_data: *mut c_void,
|
||||
@@ -143,7 +136,7 @@ pub extern "C" fn vpkc_download_updates(
|
||||
// Try to receive progress updates without blocking
|
||||
match progress_receiver.try_recv() {
|
||||
Ok(progress) => {
|
||||
cb_progress(p_user_data, progress as usize);
|
||||
cb_progress(p_user_data, progress as size_t);
|
||||
}
|
||||
_ => {
|
||||
// No progress updates available, sleep for a short time to avoid busy-waiting
|
||||
@@ -171,12 +164,12 @@ pub extern "C" fn vpkc_download_updates(
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn vpkc_wait_exit_then_apply_update(
|
||||
p_manager: *mut c_void,
|
||||
p_manager: *mut vpkc_update_manager_t,
|
||||
p_asset: *mut vpkc_asset_t,
|
||||
b_silent: bool,
|
||||
b_restart: bool,
|
||||
p_restart_args: *mut *mut c_char,
|
||||
c_restart_args: usize,
|
||||
c_restart_args: size_t,
|
||||
) -> bool {
|
||||
wrap_error(|| {
|
||||
if p_manager.is_null() {
|
||||
@@ -192,7 +185,7 @@ pub extern "C" fn vpkc_wait_exit_then_apply_update(
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn vpkc_free_update_manager(p_manager: *mut c_void) {
|
||||
pub extern "C" fn vpkc_free_update_manager(p_manager: *mut vpkc_update_manager_t) {
|
||||
if !p_manager.is_null() {
|
||||
// Convert the raw pointer back into a Box to deallocate it properly
|
||||
let _ = unsafe { Box::from_raw(p_manager as *mut UpdateManagerOpaque) };
|
||||
@@ -283,7 +276,7 @@ pub extern "C" fn vpkc_app_set_auto_apply_on_startup(b_auto_apply: bool) {
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn vpkc_app_set_args(p_args: *mut *mut c_char, c_args: usize) {
|
||||
pub extern "C" fn vpkc_app_set_args(p_args: *mut *mut c_char, c_args: size_t) {
|
||||
update_app_options(|opt| {
|
||||
opt.args = c_to_string_array_opt(p_args, c_args);
|
||||
});
|
||||
@@ -339,7 +332,7 @@ pub extern "C" fn vpkc_app_set_hook_restarted(cb_restarted: vpkc_hook_callback_t
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn vpkc_get_last_error(psz_error: *mut c_char, c_error: usize) -> usize {
|
||||
pub extern "C" fn vpkc_get_last_error(psz_error: *mut c_char, c_error: size_t) -> size_t {
|
||||
let error = get_last_error();
|
||||
return_cstr(psz_error, c_error, &error)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use std::ffi::{c_char, c_void, CStr, CString};
|
||||
use std::ffi::{CStr, CString};
|
||||
use libc::{c_char, c_void, size_t};
|
||||
use std::path::PathBuf;
|
||||
use velopack::{locator::VelopackLocatorConfig, UpdateInfo, UpdateOptions, VelopackAsset};
|
||||
|
||||
@@ -56,7 +57,7 @@ pub unsafe fn free_pathbuf(psz: *mut *mut c_char) {
|
||||
free_string(psz);
|
||||
}
|
||||
|
||||
pub fn c_to_string_array_opt(p_args: *mut *mut c_char, c_args: usize) -> Option<Vec<String>> {
|
||||
pub fn c_to_string_array_opt(p_args: *mut *mut c_char, c_args: size_t) -> Option<Vec<String>> {
|
||||
if p_args.is_null() || c_args == 0 {
|
||||
return None;
|
||||
}
|
||||
@@ -71,7 +72,7 @@ pub fn c_to_string_array_opt(p_args: *mut *mut c_char, c_args: usize) -> Option<
|
||||
Some(args)
|
||||
}
|
||||
|
||||
pub fn return_cstr(psz: *mut c_char, c: usize, s: &str) -> usize {
|
||||
pub fn return_cstr(psz: *mut c_char, c: size_t, s: &str) -> size_t {
|
||||
if !psz.is_null() && c > 0 {
|
||||
let cstr = CString::new(s).unwrap();
|
||||
let bytes = cstr.as_bytes_with_nul();
|
||||
@@ -85,7 +86,17 @@ pub fn return_cstr(psz: *mut c_char, c: usize, s: &str) -> usize {
|
||||
return s.len();
|
||||
}
|
||||
|
||||
pub type vpkc_progress_callback_t = extern "C" fn(p_user_data: *mut c_void, progress: usize);
|
||||
#[repr(i16)]
|
||||
pub enum vpkc_update_check_t {
|
||||
UPDATE_ERROR = -1,
|
||||
UPDATE_AVAILABLE = 0,
|
||||
NO_UPDATE_AVAILABLE = 1,
|
||||
REMOTE_IS_EMPTY = 2,
|
||||
}
|
||||
|
||||
pub type vpkc_update_manager_t = c_void;
|
||||
|
||||
pub type vpkc_progress_callback_t = extern "C" fn(p_user_data: *mut c_void, progress: size_t);
|
||||
|
||||
pub type vpkc_log_callback_t = extern "C" fn(p_user_data: *mut c_void, psz_level: *const c_char, psz_message: *const c_char);
|
||||
|
||||
@@ -94,12 +105,19 @@ pub type vpkc_hook_callback_t = extern "C" fn(p_user_data: *mut c_void, psz_app_
|
||||
// !! AUTO-GENERATED-START RUST_TYPES
|
||||
#[rustfmt::skip]
|
||||
#[repr(C)]
|
||||
/// VelopackLocator provides some utility functions for locating the current app important paths (eg. path to packages, update binary, and so forth).
|
||||
pub struct vpkc_locator_config_t {
|
||||
/// The root directory of the current app.
|
||||
pub RootAppDir: *mut c_char,
|
||||
/// The path to the Update.exe binary.
|
||||
pub UpdateExePath: *mut c_char,
|
||||
/// The path to the packages' directory.
|
||||
pub PackagesDir: *mut c_char,
|
||||
/// The current app manifest.
|
||||
pub ManifestPath: *mut c_char,
|
||||
/// The directory containing the application's user binaries.
|
||||
pub CurrentBinaryDir: *mut c_char,
|
||||
/// Whether the current application is portable or installed.
|
||||
pub IsPortable: bool,
|
||||
}
|
||||
|
||||
@@ -144,15 +162,25 @@ pub unsafe fn free_velopacklocatorconfig(obj: *mut vpkc_locator_config_t) {
|
||||
|
||||
#[rustfmt::skip]
|
||||
#[repr(C)]
|
||||
/// An individual Velopack asset, could refer to an asset on-disk or in a remote package feed.
|
||||
pub struct vpkc_asset_t {
|
||||
/// The name or Id of the package containing this release.
|
||||
pub PackageId: *mut c_char,
|
||||
/// The version of this release.
|
||||
pub Version: *mut c_char,
|
||||
/// The type of asset (eg. "Full" or "Delta").
|
||||
pub Type: *mut c_char,
|
||||
/// The filename of the update package containing this release.
|
||||
pub FileName: *mut c_char,
|
||||
/// The SHA1 checksum of the update package containing this release.
|
||||
pub SHA1: *mut c_char,
|
||||
/// The SHA256 checksum of the update package containing this release.
|
||||
pub SHA256: *mut c_char,
|
||||
/// The size in bytes of the update package containing this release.
|
||||
pub Size: u64,
|
||||
/// The release notes in markdown format, as passed to Velopack when packaging the release. This may be an empty string.
|
||||
pub NotesMarkdown: *mut c_char,
|
||||
/// The release notes in HTML format, transformed from Markdown when packaging the release. This may be an empty string.
|
||||
pub NotesHtml: *mut c_char,
|
||||
}
|
||||
|
||||
@@ -206,8 +234,13 @@ pub unsafe fn free_velopackasset(obj: *mut vpkc_asset_t) {
|
||||
|
||||
#[rustfmt::skip]
|
||||
#[repr(C)]
|
||||
/// Holds information about the current version and pending updates, such as how many there are, and access to release notes.
|
||||
pub struct vpkc_update_info_t {
|
||||
/// The available version that we are updating to.
|
||||
pub TargetFullRelease: vpkc_asset_t,
|
||||
/// True if the update is a version downgrade or lateral move (such as when switching channels to the same version number).
|
||||
/// In this case, only full updates are allowed, and any local packages on disk newer than the downloaded version will be
|
||||
/// deleted.
|
||||
pub IsDowngrade: bool,
|
||||
}
|
||||
|
||||
@@ -240,8 +273,20 @@ pub unsafe fn free_updateinfo(obj: *mut vpkc_update_info_t) {
|
||||
|
||||
#[rustfmt::skip]
|
||||
#[repr(C)]
|
||||
/// Options to customise the behaviour of UpdateManager.
|
||||
pub struct vpkc_update_options_t {
|
||||
/// Allows UpdateManager to update to a version that's lower than the current version (i.e. downgrading).
|
||||
/// This could happen if a release has bugs and was retracted from the release feed, or if you're using
|
||||
/// ExplicitChannel to switch channels to another channel where the latest version on that
|
||||
/// channel is lower than the current version.
|
||||
pub AllowVersionDowngrade: bool,
|
||||
/// **This option should usually be left None**. <br/>
|
||||
/// Overrides the default channel used to fetch updates.
|
||||
/// The default channel will be whatever channel was specified on the command line when building this release.
|
||||
/// For example, if the current release was packaged with '--channel beta', then the default channel will be 'beta'.
|
||||
/// This allows users to automatically receive updates from the same channel they installed from. This options
|
||||
/// allows you to explicitly switch channels, for example if the user wished to switch back to the 'stable' channel
|
||||
/// without having to reinstall the application.
|
||||
pub ExplicitChannel: *mut c_char,
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ if (desiredStructs.Length != availableStructs.Count) {
|
||||
// string rustCppLib = Path.Combine(libcppDir, "src", "lib.rs");
|
||||
string rustTypes = Path.Combine(libcppDir, "src", "types.rs");
|
||||
//string rustCppMap = Path.Combine(libcppDir, "src", "map.rs");
|
||||
string rustCppInclude = Path.Combine(libcppDir, "include", "Velopack.h");
|
||||
string rustCppInclude = Path.Combine(libcppDir, "include", "Velopack.hpp");
|
||||
//string rustBridgeC = Path.Combine(libcppDir, "src", "bridge.cc");
|
||||
|
||||
//Console.WriteLine("Generating bridge dtos");
|
||||
@@ -65,12 +65,12 @@ string rustCppInclude = Path.Combine(libcppDir, "include", "Velopack.h");
|
||||
// Templates.WriteBridgeToCoreMapping(desiredStructs, sbBridgeMapping, rs);
|
||||
//}
|
||||
|
||||
Console.WriteLine("Generating C types");
|
||||
var cTypes = new IndentStringBuilder();
|
||||
cTypes.AppendLine();
|
||||
foreach (var rs in availableStructs) {
|
||||
Templates.WriteBasicC(basic_libc_names, cTypes, rs);
|
||||
}
|
||||
// Console.WriteLine("Generating C types");
|
||||
// var cTypes = new IndentStringBuilder();
|
||||
// cTypes.AppendLine();
|
||||
// foreach (var rs in availableStructs) {
|
||||
// Templates.WriteBasicC(basic_libc_names, cTypes, rs);
|
||||
// }
|
||||
|
||||
Console.WriteLine("Generating C++ types");
|
||||
var cppTypes = new IndentStringBuilder();
|
||||
@@ -98,7 +98,7 @@ Console.WriteLine("Writing all to file");
|
||||
//Util.ReplaceTextInFile(rustCppLib, "BRIDGE_DTOS", sbBridgeDto.ToString());
|
||||
//Util.ReplaceTextInFile(rustCppMap, "CORE_MAPPING", sbBridgeMapping.ToString());
|
||||
Util.ReplaceTextInFile(rustTypes, "RUST_TYPES", rustCTypes.ToString());
|
||||
Util.ReplaceTextInFile(rustCppInclude, "C_TYPES", cTypes.ToString());
|
||||
// Util.ReplaceTextInFile(rustCppInclude, "C_TYPES", cTypes.ToString());
|
||||
Util.ReplaceTextInFile(rustCppInclude, "CPP_TYPES", cppTypes.ToString());
|
||||
//Util.ReplaceTextInFile(rustBridgeC, "BRIDGE_MAPPING", cToBridgeMapping.ToString());
|
||||
|
||||
|
||||
@@ -55,9 +55,11 @@
|
||||
var cName = nameMap[rs.Name];
|
||||
sb.AppendLine("#[rustfmt::skip]");
|
||||
sb.AppendLine($"#[repr(C)]");
|
||||
sb.AppendDocComment(rs.DocComment);
|
||||
sb.AppendLine($"pub struct {cName} {{");
|
||||
using (sb.Indent()) {
|
||||
foreach (var field in rs.Fields) {
|
||||
sb.AppendDocComment(field.DocComment);
|
||||
sb.AppendLine($"pub {field.Name}: {GetBasicCTypeInRust(nameMap, field.Type)},");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user