Add bridge code for app builder

This commit is contained in:
Caelan Sayler
2024-10-16 21:24:28 +01:00
committed by Caelan
parent d04412dcce
commit e3a7b4614a
5 changed files with 125 additions and 33 deletions

View File

@@ -15,7 +15,7 @@ rust-version.workspace = true
[lib]
path = "src/lib.rs"
crate-type = ["cdylib", "staticlib"]
crate-type = ["cdylib"]
[dependencies]
cxx.workspace = true

View File

@@ -15,6 +15,27 @@
#if defined(VELOPACK_LIBC_EXPORTS) && defined(_WIN32)
#define VPKC_EXPORT __declspec(dllexport)
#pragma comment(linker, "/EXPORT:vpkc_new_update_manager")
#pragma comment(linker, "/EXPORT:vpkc_get_current_version")
#pragma comment(linker, "/EXPORT:vpkc_get_app_id")
#pragma comment(linker, "/EXPORT:vpkc_is_portable")
#pragma comment(linker, "/EXPORT:vpkc_update_pending_restart")
#pragma comment(linker, "/EXPORT:vpkc_download_updates")
#pragma comment(linker, "/EXPORT:vpkc_wait_exit_then_apply_update")
#pragma comment(linker, "/EXPORT:vpkc_app_set_auto_apply_on_startup")
#pragma comment(linker, "/EXPORT:vpkc_app_set_args")
#pragma comment(linker, "/EXPORT:vpkc_app_set_locator")
#pragma comment(linker, "/EXPORT:vpkc_app_set_hook_after_install")
#pragma comment(linker, "/EXPORT:vpkc_app_set_hook_before_uninstall")
#pragma comment(linker, "/EXPORT:vpkc_app_set_hook_before_update")
#pragma comment(linker, "/EXPORT:vpkc_app_set_hook_after_update")
#pragma comment(linker, "/EXPORT:vpkc_app_set_hook_first_run")
#pragma comment(linker, "/EXPORT:vpkc_app_set_hook_restarted")
#pragma comment(linker, "/EXPORT:vpkc_app_run")
#pragma comment(linker, "/EXPORT:vpkc_get_last_error")
#pragma comment(linker, "/EXPORT:vpkc_set_log")
#pragma comment(linker, "/EXPORT:vpkc_free_update_manager")
#pragma comment(linker, "/EXPORT:vpkc_free_update_info")
#pragma comment(linker, "/EXPORT:vpkc_free_asset")
#elif defined(VELOPACK_LIBC_EXPORTS) && !defined(_WIN32)
#define VPKC_EXPORT __attribute__((visibility("default"))) __attribute__((used))
#else
@@ -69,6 +90,7 @@ typedef struct {
bool IsDowngrade;
} vpkc_update_info_t;
// Update Manager
VPKC_EXPORT bool VPKC_CALL vpkc_new_update_manager(const char* pszUrlOrString, const vpkc_options_t* pOptions, const vpkc_locator_t* locator, vpkc_update_manager_t* pManager);
VPKC_EXPORT size_t VPKC_CALL vpkc_get_current_version(vpkc_update_manager_t* pManager, char* pszVersion, size_t cVersion);
VPKC_EXPORT size_t VPKC_CALL vpkc_get_app_id(vpkc_update_manager_t* pManager, char* pszId, size_t cId);
@@ -78,6 +100,7 @@ VPKC_EXPORT vpkc_update_check_t VPKC_CALL vpkc_check_for_updates(vpkc_update_man
VPKC_EXPORT bool VPKC_CALL vpkc_download_updates(vpkc_update_manager_t* pManager, const vpkc_update_info_t* pUpdate, vpkc_progress_callback_t cbProgress);
VPKC_EXPORT bool VPKC_CALL vpkc_wait_exit_then_apply_update(vpkc_update_manager_t* pManager, vpkc_asset_t* pAsset, bool bSilent, bool bRestart, char** pRestartArgs, size_t cRestartArgs);
// VelopackApp
VPKC_EXPORT void VPKC_CALL vpkc_app_set_auto_apply_on_startup(bool bAutoApply);
VPKC_EXPORT void VPKC_CALL vpkc_app_set_args(char** pArgs, size_t cArgs);
VPKC_EXPORT void VPKC_CALL vpkc_app_set_locator(vpkc_locator_t* pLocator);
@@ -89,6 +112,7 @@ VPKC_EXPORT void VPKC_CALL vpkc_app_set_hook_first_run(vpkc_hook_callback_t cbFi
VPKC_EXPORT void VPKC_CALL vpkc_app_set_hook_restarted(vpkc_hook_callback_t cbRestarted);
VPKC_EXPORT void VPKC_CALL vpkc_app_run();
// Misc functions
VPKC_EXPORT size_t VPKC_CALL vpkc_get_last_error(char* pszError, size_t cError);
VPKC_EXPORT void VPKC_CALL vpkc_set_log(vpkc_log_callback_t cbLog);
VPKC_EXPORT void VPKC_CALL vpkc_free_update_manager(vpkc_update_manager_t* pManager);
@@ -336,7 +360,8 @@ namespace Velopack {
strcpy_s(pRestartArgs[i], restartArgs[i].size() + 1, restartArgs[i].c_str());
}
bool result = vpkc_wait_exit_then_apply_update(&m_pManager, &to_vpkc(asset), silent, restart, pRestartArgs, restartArgs.size());
vpkc_asset_t vpkc_asset = to_vpkc(asset);
bool result = vpkc_wait_exit_then_apply_update(&m_pManager, &vpkc_asset, silent, restart, pRestartArgs, restartArgs.size());
// Free all the memory
for (size_t i = 0; i < restartArgs.size(); i++) {

View File

@@ -1,7 +1,65 @@
#include "velopack_libc/include/Velopack.h"
#include "velopack_libc/src/bridge.hpp"
#include "velopack_libc/src/lib.rs.h"
VPKC_EXPORT bool VPKC_CALL vpkc_new_update_manager(const char* pszUrlOrString, const vpkc_options_t* pOptions, const vpkc_locator_t* locator, vpkc_update_manager_t* pManager)
{
return 0;
// Update Manager
VPKC_EXPORT bool VPKC_CALL vpkc_new_update_manager(const char* pszUrlOrString, const vpkc_options_t* pOptions, const vpkc_locator_t* locator, vpkc_update_manager_t* pManager);
VPKC_EXPORT size_t VPKC_CALL vpkc_get_current_version(vpkc_update_manager_t* pManager, char* pszVersion, size_t cVersion);
VPKC_EXPORT size_t VPKC_CALL vpkc_get_app_id(vpkc_update_manager_t* pManager, char* pszId, size_t cId);
VPKC_EXPORT bool VPKC_CALL vpkc_is_portable(vpkc_update_manager_t* pManager);
VPKC_EXPORT bool VPKC_CALL vpkc_update_pending_restart(vpkc_update_manager_t* pManager, vpkc_asset_t* pAsset);
VPKC_EXPORT vpkc_update_check_t VPKC_CALL vpkc_check_for_updates(vpkc_update_manager_t* pManager, vpkc_update_info_t* pUpdate);
VPKC_EXPORT bool VPKC_CALL vpkc_download_updates(vpkc_update_manager_t* pManager, const vpkc_update_info_t* pUpdate, vpkc_progress_callback_t cbProgress);
VPKC_EXPORT bool VPKC_CALL vpkc_wait_exit_then_apply_update(vpkc_update_manager_t* pManager, vpkc_asset_t* pAsset, bool bSilent, bool bRestart, char** pRestartArgs, size_t cRestartArgs);
// VelopackApp
bool autoApply = true;
StringArrayOption args{};
LocatorConfigOption locator{};
HookCallbackManager hooks{};
VPKC_EXPORT void VPKC_CALL vpkc_app_set_auto_apply_on_startup(bool bAutoApply) {
autoApply = bAutoApply;
}
VPKC_EXPORT void VPKC_CALL vpkc_app_set_args(char** pArgs, size_t cArgs) {
args.has_data = true;
args.data.clear();
for (size_t i = 0; i < cArgs; i++) {
args.data.push_back(pArgs[i]);
}
}
VPKC_EXPORT void VPKC_CALL vpkc_app_set_locator(vpkc_locator_t* pLocator) {
locator.has_data = true;
locator.data.RootAppDir = pLocator->RootAppDir;
locator.data.UpdateExePath = pLocator->UpdateExePath;
locator.data.PackagesDir = pLocator->PackagesDir;
locator.data.ManifestPath = pLocator->ManifestPath;
locator.data.CurrentBinaryDir = pLocator->CurrentBinaryDir;
locator.data.IsPortable = pLocator->IsPortable;
}
VPKC_EXPORT void VPKC_CALL vpkc_app_set_hook_after_install(vpkc_hook_callback_t cbAfterInstall) {
hooks.after_install = cbAfterInstall;
}
VPKC_EXPORT void VPKC_CALL vpkc_app_set_hook_before_uninstall(vpkc_hook_callback_t cbBeforeUninstall) {
hooks.before_uninstall = cbBeforeUninstall;
}
VPKC_EXPORT void VPKC_CALL vpkc_app_set_hook_before_update(vpkc_hook_callback_t cbBeforeUpdate) {
hooks.before_update = cbBeforeUpdate;
}
VPKC_EXPORT void VPKC_CALL vpkc_app_set_hook_after_update(vpkc_hook_callback_t cbAfterUpdate) {
hooks.after_update = cbAfterUpdate;
}
VPKC_EXPORT void VPKC_CALL vpkc_app_set_hook_first_run(vpkc_hook_callback_t cbFirstRun) {
hooks.first_run = cbFirstRun;
}
VPKC_EXPORT void VPKC_CALL vpkc_app_set_hook_restarted(vpkc_hook_callback_t cbRestarted) {
hooks.restarted = cbRestarted;
}
VPKC_EXPORT void VPKC_CALL vpkc_app_run() {
bridge_appbuilder_run(hooks, args, locator, autoApply);
}
// Misc functions
VPKC_EXPORT size_t VPKC_CALL vpkc_get_last_error(char* pszError, size_t cError);
VPKC_EXPORT void VPKC_CALL vpkc_set_log(vpkc_log_callback_t cbLog);
VPKC_EXPORT void VPKC_CALL vpkc_free_update_manager(vpkc_update_manager_t* pManager);
VPKC_EXPORT void VPKC_CALL vpkc_free_update_info(vpkc_update_info_t* pManager);
VPKC_EXPORT void VPKC_CALL vpkc_free_asset(vpkc_asset_t* pManager);

View File

@@ -3,6 +3,13 @@
#include "velopack_libc/include/Velopack.h"
struct HookCallbackManager {
vpkc_hook_callback_t after_install = nullptr;
vpkc_hook_callback_t before_uninstall = nullptr;
vpkc_hook_callback_t before_update = nullptr;
vpkc_hook_callback_t after_update = nullptr;
vpkc_hook_callback_t first_run = nullptr;
vpkc_hook_callback_t restarted = nullptr;
void install_hook(::rust::String app_version) const {};
void update_hook(::rust::String app_version) const {};
void obsolete_hook(::rust::String app_version) const {};

View File

@@ -48,23 +48,23 @@ mod ffi {
pub has_data: bool,
}
pub struct LocatorConfigDto<'a> {
pub RootAppDir: &'a CxxString,
pub UpdateExePath: &'a CxxString,
pub PackagesDir: &'a CxxString,
pub ManifestPath: &'a CxxString,
pub CurrentBinaryDir: &'a CxxString,
pub struct LocatorConfigDto {
pub RootAppDir: String,
pub UpdateExePath: String,
pub PackagesDir: String,
pub ManifestPath: String,
pub CurrentBinaryDir: String,
pub IsPortable: bool,
}
pub struct LocatorConfigOption<'a> {
pub data: LocatorConfigDto<'a>,
pub struct LocatorConfigOption {
pub data: LocatorConfigDto,
pub has_data: bool,
}
pub struct UpdateOptionsDto<'a> {
pub struct UpdateOptionsDto {
pub AllowVersionDowngrade: bool,
pub ExplicitChannel: &'a CxxString,
pub ExplicitChannel: String,
}
pub struct StringArrayOption {
@@ -100,7 +100,7 @@ mod ffi {
fn bridge_check_for_updates(manager: &UpdateManagerOpaque) -> Result<UpdateInfoOption>;
fn bridge_download_update(manager: &UpdateManagerOpaque, to_download: UpdateInfoDto, progress: UniquePtr<DownloadCallbackManager>) -> Result<()>;
fn bridge_wait_exit_then_apply_update(manager: &UpdateManagerOpaque, to_download: AssetDto, silent: bool, restart: bool, restart_args: Vec<String>) -> Result<()>;
fn bridge_appbuilder_run(cb: UniquePtr<HookCallbackManager>, custom_args: StringArrayOption, locator: LocatorConfigOption, auto_apply: bool);
unsafe fn bridge_appbuilder_run(cb: &HookCallbackManager, custom_args: &StringArrayOption, locator: &LocatorConfigOption, auto_apply: bool);
fn bridge_set_logger_callback(cb: UniquePtr<LoggerCallbackManager>);
}
}
@@ -112,17 +112,17 @@ struct UpdateManagerOpaque {
fn to_locator_config(locator: &ffi::LocatorConfigDto) -> VelopackLocatorConfig {
VelopackLocatorConfig {
RootAppDir: PathBuf::from(locator.RootAppDir.to_string_lossy().to_string()),
UpdateExePath: PathBuf::from(locator.UpdateExePath.to_string_lossy().to_string()),
PackagesDir: PathBuf::from(locator.PackagesDir.to_string_lossy().to_string()),
ManifestPath: PathBuf::from(locator.ManifestPath.to_string_lossy().to_string()),
CurrentBinaryDir: PathBuf::from(locator.CurrentBinaryDir.to_string_lossy().to_string()),
RootAppDir: PathBuf::from(locator.RootAppDir.clone()),
UpdateExePath: PathBuf::from(locator.UpdateExePath.clone()),
PackagesDir: PathBuf::from(locator.PackagesDir.clone()),
ManifestPath: PathBuf::from(locator.ManifestPath.clone()),
CurrentBinaryDir: PathBuf::from(locator.CurrentBinaryDir.clone()),
IsPortable: locator.IsPortable,
}
}
fn to_update_options(options: &ffi::UpdateOptionsDto) -> VelopackUpdateOptions {
let channel = options.ExplicitChannel.to_string_lossy().to_string();
let channel = options.ExplicitChannel.clone();
VelopackUpdateOptions {
AllowVersionDowngrade: options.AllowVersionDowngrade,
ExplicitChannel: if channel.is_empty() { None } else { Some(channel) },
@@ -267,15 +267,16 @@ fn bridge_wait_exit_then_apply_update(manager: &UpdateManagerOpaque, to_download
Ok(())
}
fn bridge_appbuilder_run(cb: cxx::UniquePtr<ffi::HookCallbackManager>, custom_args: ffi::StringArrayOption, locator: ffi::LocatorConfigOption, auto_apply: bool) {
fn bridge_appbuilder_run(cb: &ffi::HookCallbackManager, custom_args: &ffi::StringArrayOption, locator: &ffi::LocatorConfigOption, auto_apply: bool) {
let mut app = VelopackApp::build()
.set_auto_apply_on_startup(auto_apply)
.on_first_run(|v| cb.firstrun_hook(v.to_string()))
.on_restarted(|v| cb.restarted_hook(v.to_string()))
.set_auto_apply_on_startup(auto_apply);
.on_restarted(|v| cb.restarted_hook(v.to_string()));
#[cfg(windows)]
{
app = app.on_after_install_fast_callback(|v| cb.install_hook(v.to_string()))
app = app
.on_after_install_fast_callback(|v| cb.install_hook(v.to_string()))
.on_after_update_fast_callback(|v| cb.update_hook(v.to_string()))
.on_before_update_fast_callback(|v| cb.obsolete_hook(v.to_string()))
.on_before_uninstall_fast_callback(|v| cb.uninstall_hook(v.to_string()));
@@ -286,13 +287,14 @@ fn bridge_appbuilder_run(cb: cxx::UniquePtr<ffi::HookCallbackManager>, custom_ar
}
if custom_args.has_data {
app = app.set_args(custom_args.data);
app = app.set_args(custom_args.data.clone());
}
app.run();
}
struct LoggerImpl {}
static LOGGER: LoggerImpl = LoggerImpl {};
impl Log for LoggerImpl {