mirror of
				https://github.com/velopack/velopack.git
				synced 2025-10-25 15:19:22 +00:00 
			
		
		
		
	Add bridge code for app builder
This commit is contained in:
		| @@ -15,7 +15,7 @@ rust-version.workspace = true | ||||
|  | ||||
| [lib] | ||||
| path = "src/lib.rs" | ||||
| crate-type = ["cdylib", "staticlib"] | ||||
| crate-type = ["cdylib"] | ||||
|  | ||||
| [dependencies] | ||||
| cxx.workspace = true | ||||
|   | ||||
| @@ -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++) { | ||||
|   | ||||
| @@ -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); | ||||
| @@ -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 {}; | ||||
|   | ||||
| @@ -48,30 +48,30 @@ 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 { | ||||
|         pub data: Vec<String>, | ||||
|         pub has_data: bool, | ||||
|     } | ||||
|      | ||||
|  | ||||
|     // C++ types and signatures exposed to Rust. | ||||
|     unsafe extern "C++" { | ||||
|         include!("velopack_libc/include/Velopack.h"); | ||||
| @@ -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 { | ||||
| @@ -314,7 +316,7 @@ impl Log for LoggerImpl { | ||||
|             Level::Debug => "debug", | ||||
|             Level::Trace => "trace", | ||||
|         }.to_string(); | ||||
|          | ||||
|  | ||||
|         if let Some(cb) = get_logger() { | ||||
|             if let Some(cb) = unsafe { cb.as_mut() } { | ||||
|                 cb.log(level, text); | ||||
| @@ -345,7 +347,7 @@ fn get_logger() -> Option<*mut ffi::LoggerCallbackManager> { | ||||
| fn bridge_set_logger_callback(cb: cxx::UniquePtr<ffi::LoggerCallbackManager>) { | ||||
|     let _ = log::set_logger(&LOGGER); | ||||
|     log::set_max_level(log::LevelFilter::Trace); | ||||
|      | ||||
|  | ||||
|     let cb = cb.into_raw(); | ||||
|     store_logger(cb); | ||||
| } | ||||
		Reference in New Issue
	
	Block a user