settings.rs 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175
  1. // Copyright 2016-2019 Cargo-Bundle developers <https://github.com/burtonageo/cargo-bundle>
  2. // Copyright 2019-2024 Tauri Programme within The Commons Conservancy
  3. // SPDX-License-Identifier: Apache-2.0
  4. // SPDX-License-Identifier: MIT
  5. use super::category::AppCategory;
  6. use crate::bundle::{common, platform::target_triple};
  7. use anyhow::Context;
  8. pub use tauri_utils::config::WebviewInstallMode;
  9. use tauri_utils::{
  10. config::{BundleType, DeepLinkProtocol, FileAssociation, NSISInstallerMode, NsisCompression},
  11. resources::{external_binaries, ResourcePaths},
  12. };
  13. use std::{
  14. collections::HashMap,
  15. path::{Path, PathBuf},
  16. };
  17. /// The type of the package we're bundling.
  18. #[derive(Clone, Copy, Debug, Eq, PartialEq)]
  19. #[non_exhaustive]
  20. pub enum PackageType {
  21. /// The macOS application bundle (.app).
  22. MacOsBundle,
  23. /// The iOS app bundle.
  24. IosBundle,
  25. /// The Windows bundle (.msi).
  26. WindowsMsi,
  27. /// The NSIS bundle (.exe).
  28. Nsis,
  29. /// The Linux Debian package bundle (.deb).
  30. Deb,
  31. /// The Linux RPM bundle (.rpm).
  32. Rpm,
  33. /// The Linux AppImage bundle (.AppImage).
  34. AppImage,
  35. /// The macOS DMG bundle (.dmg).
  36. Dmg,
  37. /// The Updater bundle.
  38. Updater,
  39. }
  40. impl From<BundleType> for PackageType {
  41. fn from(bundle: BundleType) -> Self {
  42. match bundle {
  43. BundleType::Deb => Self::Deb,
  44. BundleType::Rpm => Self::Rpm,
  45. BundleType::AppImage => Self::AppImage,
  46. BundleType::Msi => Self::WindowsMsi,
  47. BundleType::Nsis => Self::Nsis,
  48. BundleType::App => Self::MacOsBundle,
  49. BundleType::Dmg => Self::Dmg,
  50. }
  51. }
  52. }
  53. impl PackageType {
  54. /// Maps a short name to a PackageType.
  55. /// Possible values are "deb", "ios", "msi", "app", "rpm", "appimage", "dmg", "updater".
  56. pub fn from_short_name(name: &str) -> Option<PackageType> {
  57. // Other types we may eventually want to support: apk.
  58. match name {
  59. "deb" => Some(PackageType::Deb),
  60. "ios" => Some(PackageType::IosBundle),
  61. "msi" => Some(PackageType::WindowsMsi),
  62. "nsis" => Some(PackageType::Nsis),
  63. "app" => Some(PackageType::MacOsBundle),
  64. "rpm" => Some(PackageType::Rpm),
  65. "appimage" => Some(PackageType::AppImage),
  66. "dmg" => Some(PackageType::Dmg),
  67. "updater" => Some(PackageType::Updater),
  68. _ => None,
  69. }
  70. }
  71. /// Gets the short name of this PackageType.
  72. #[allow(clippy::trivially_copy_pass_by_ref)]
  73. pub fn short_name(&self) -> &'static str {
  74. match *self {
  75. PackageType::Deb => "deb",
  76. PackageType::IosBundle => "ios",
  77. PackageType::WindowsMsi => "msi",
  78. PackageType::Nsis => "nsis",
  79. PackageType::MacOsBundle => "app",
  80. PackageType::Rpm => "rpm",
  81. PackageType::AppImage => "appimage",
  82. PackageType::Dmg => "dmg",
  83. PackageType::Updater => "updater",
  84. }
  85. }
  86. /// Gets the list of the possible package types.
  87. pub fn all() -> &'static [PackageType] {
  88. ALL_PACKAGE_TYPES
  89. }
  90. /// Gets a number representing priority which used to sort package types
  91. /// in an order that guarantees that if a certain package type
  92. /// depends on another (like Dmg depending on MacOsBundle), the dependency
  93. /// will be built first
  94. ///
  95. /// The lower the number, the higher the priority
  96. pub fn priority(&self) -> u32 {
  97. match self {
  98. PackageType::MacOsBundle => 0,
  99. PackageType::IosBundle => 0,
  100. PackageType::WindowsMsi => 0,
  101. PackageType::Nsis => 0,
  102. PackageType::Deb => 0,
  103. PackageType::Rpm => 0,
  104. PackageType::AppImage => 0,
  105. PackageType::Dmg => 1,
  106. PackageType::Updater => 2,
  107. }
  108. }
  109. }
  110. const ALL_PACKAGE_TYPES: &[PackageType] = &[
  111. #[cfg(target_os = "linux")]
  112. PackageType::Deb,
  113. #[cfg(target_os = "macos")]
  114. PackageType::IosBundle,
  115. #[cfg(target_os = "windows")]
  116. PackageType::WindowsMsi,
  117. #[cfg(target_os = "windows")]
  118. PackageType::Nsis,
  119. #[cfg(target_os = "macos")]
  120. PackageType::MacOsBundle,
  121. #[cfg(target_os = "linux")]
  122. PackageType::Rpm,
  123. #[cfg(target_os = "macos")]
  124. PackageType::Dmg,
  125. #[cfg(target_os = "linux")]
  126. PackageType::AppImage,
  127. PackageType::Updater,
  128. ];
  129. /// The package settings.
  130. #[derive(Debug, Clone)]
  131. pub struct PackageSettings {
  132. /// the package's product name.
  133. pub product_name: String,
  134. /// the package's version.
  135. pub version: String,
  136. /// the package's description.
  137. pub description: String,
  138. /// the package's homepage.
  139. pub homepage: Option<String>,
  140. /// the package's authors.
  141. pub authors: Option<Vec<String>>,
  142. /// the default binary to run.
  143. pub default_run: Option<String>,
  144. }
  145. /// The updater settings.
  146. #[derive(Debug, Default, Clone)]
  147. pub struct UpdaterSettings {
  148. /// Should generate v1 compatible zipped updater
  149. pub v1_compatible: bool,
  150. /// Signature public key.
  151. pub pubkey: String,
  152. /// Args to pass to `msiexec.exe` to run the updater on Windows.
  153. pub msiexec_args: &'static [&'static str],
  154. }
  155. /// The Linux debian bundle settings.
  156. #[derive(Clone, Debug, Default)]
  157. pub struct DebianSettings {
  158. // OS-specific settings:
  159. /// the list of debian dependencies.
  160. pub depends: Option<Vec<String>>,
  161. /// the list of dependencies the package provides.
  162. pub provides: Option<Vec<String>>,
  163. /// the list of package conflicts.
  164. pub conflicts: Option<Vec<String>>,
  165. /// the list of package replaces.
  166. pub replaces: Option<Vec<String>>,
  167. /// List of custom files to add to the deb package.
  168. /// Maps the path on the debian package to the path of the file to include (relative to the current working directory).
  169. pub files: HashMap<PathBuf, PathBuf>,
  170. /// Path to a custom desktop file Handlebars template.
  171. ///
  172. /// Available variables: `categories`, `comment` (optional), `exec`, `icon` and `name`.
  173. ///
  174. /// Default file contents:
  175. /// ```text
  176. #[doc = include_str!("./linux/freedesktop/main.desktop")]
  177. /// ```
  178. pub desktop_template: Option<PathBuf>,
  179. /// Define the section in Debian Control file. See : <https://www.debian.org/doc/debian-policy/ch-archive.html#s-subsections>
  180. pub section: Option<String>,
  181. /// Change the priority of the Debian Package. By default, it is set to `optional`.
  182. /// Recognized Priorities as of now are : `required`, `important`, `standard`, `optional`, `extra`
  183. pub priority: Option<String>,
  184. /// Path of the uncompressed Changelog file, to be stored at /usr/share/doc/package-name/changelog.gz. See
  185. /// <https://www.debian.org/doc/debian-policy/ch-docs.html#changelog-files-and-release-notes>
  186. pub changelog: Option<PathBuf>,
  187. /// Path to script that will be executed before the package is unpacked. See
  188. /// <https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html>
  189. pub pre_install_script: Option<PathBuf>,
  190. /// Path to script that will be executed after the package is unpacked. See
  191. /// <https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html>
  192. pub post_install_script: Option<PathBuf>,
  193. /// Path to script that will be executed before the package is removed. See
  194. /// <https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html>
  195. pub pre_remove_script: Option<PathBuf>,
  196. /// Path to script that will be executed after the package is removed. See
  197. /// <https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html>
  198. pub post_remove_script: Option<PathBuf>,
  199. }
  200. /// The Linux AppImage bundle settings.
  201. #[derive(Clone, Debug, Default)]
  202. pub struct AppImageSettings {
  203. /// The files to include in the Appimage Binary.
  204. pub files: HashMap<PathBuf, PathBuf>,
  205. }
  206. /// The RPM bundle settings.
  207. #[derive(Clone, Debug, Default)]
  208. pub struct RpmSettings {
  209. /// The list of RPM dependencies your application relies on.
  210. pub depends: Option<Vec<String>>,
  211. /// The list of RPM dependencies your application provides.
  212. pub provides: Option<Vec<String>>,
  213. /// The list of RPM dependencies your application conflicts with. They must not be present
  214. /// in order for the package to be installed.
  215. pub conflicts: Option<Vec<String>>,
  216. /// The list of RPM dependencies your application supersedes - if this package is installed,
  217. /// packages listed as “obsoletes” will be automatically removed (if they are present).
  218. pub obsoletes: Option<Vec<String>>,
  219. /// The RPM release tag.
  220. pub release: String,
  221. /// The RPM epoch.
  222. pub epoch: u32,
  223. /// List of custom files to add to the RPM package.
  224. /// Maps the path on the RPM package to the path of the file to include (relative to the current working directory).
  225. pub files: HashMap<PathBuf, PathBuf>,
  226. /// Path to a custom desktop file Handlebars template.
  227. ///
  228. /// Available variables: `categories`, `comment` (optional), `exec`, `icon` and `name`.
  229. ///
  230. /// Default file contents:
  231. /// ```text
  232. #[doc = include_str!("./linux/freedesktop/main.desktop")]
  233. /// ```
  234. pub desktop_template: Option<PathBuf>,
  235. /// Path to script that will be executed before the package is unpacked. See
  236. /// <http://ftp.rpm.org/max-rpm/s1-rpm-inside-scripts.html>
  237. pub pre_install_script: Option<PathBuf>,
  238. /// Path to script that will be executed after the package is unpacked. See
  239. /// <http://ftp.rpm.org/max-rpm/s1-rpm-inside-scripts.html>
  240. pub post_install_script: Option<PathBuf>,
  241. /// Path to script that will be executed before the package is removed. See
  242. /// <http://ftp.rpm.org/max-rpm/s1-rpm-inside-scripts.html>
  243. pub pre_remove_script: Option<PathBuf>,
  244. /// Path to script that will be executed after the package is removed. See
  245. /// <http://ftp.rpm.org/max-rpm/s1-rpm-inside-scripts.html>
  246. pub post_remove_script: Option<PathBuf>,
  247. }
  248. /// Position coordinates struct.
  249. #[derive(Clone, Debug, Default)]
  250. pub struct Position {
  251. /// X coordinate.
  252. pub x: u32,
  253. /// Y coordinate.
  254. pub y: u32,
  255. }
  256. /// Size of the window.
  257. #[derive(Clone, Debug, Default)]
  258. pub struct Size {
  259. /// Width of the window.
  260. pub width: u32,
  261. /// Height of the window.
  262. pub height: u32,
  263. }
  264. /// The DMG bundle settings.
  265. #[derive(Clone, Debug, Default)]
  266. pub struct DmgSettings {
  267. /// Image to use as the background in dmg file. Accepted formats: `png`/`jpg`/`gif`.
  268. pub background: Option<PathBuf>,
  269. /// Position of volume window on screen.
  270. pub window_position: Option<Position>,
  271. /// Size of volume window.
  272. pub window_size: Size,
  273. /// Position of app file on window.
  274. pub app_position: Position,
  275. /// Position of application folder on window.
  276. pub application_folder_position: Position,
  277. }
  278. /// The macOS bundle settings.
  279. #[derive(Clone, Debug, Default)]
  280. pub struct MacOsSettings {
  281. /// MacOS frameworks that need to be bundled with the app.
  282. ///
  283. /// Each string can either be the name of a framework (without the `.framework` extension, e.g. `"SDL2"`),
  284. /// in which case we will search for that framework in the standard install locations (`~/Library/Frameworks/`, `/Library/Frameworks/`, and `/Network/Library/Frameworks/`),
  285. /// or a path to a specific framework bundle (e.g. `./data/frameworks/SDL2.framework`). Note that this setting just makes tauri-bundler copy the specified frameworks into the OS X app bundle
  286. /// (under `Foobar.app/Contents/Frameworks/`); you are still responsible for:
  287. ///
  288. /// - arranging for the compiled binary to link against those frameworks (e.g. by emitting lines like `cargo:rustc-link-lib=framework=SDL2` from your `build.rs` script)
  289. ///
  290. /// - embedding the correct rpath in your binary (e.g. by running `install_name_tool -add_rpath "@executable_path/../Frameworks" path/to/binary` after compiling)
  291. pub frameworks: Option<Vec<String>>,
  292. /// List of custom files to add to the application bundle.
  293. /// Maps the path in the Contents directory in the app to the path of the file to include (relative to the current working directory).
  294. pub files: HashMap<PathBuf, PathBuf>,
  295. /// A version string indicating the minimum MacOS version that the bundled app supports (e.g. `"10.11"`).
  296. /// If you are using this config field, you may also want have your `build.rs` script emit `cargo:rustc-env=MACOSX_DEPLOYMENT_TARGET=10.11`.
  297. pub minimum_system_version: Option<String>,
  298. /// The exception domain to use on the macOS .app bundle.
  299. ///
  300. /// This allows communication to the outside world e.g. a web server you're shipping.
  301. pub exception_domain: Option<String>,
  302. /// Code signing identity.
  303. pub signing_identity: Option<String>,
  304. /// Preserve the hardened runtime version flag, see <https://developer.apple.com/documentation/security/hardened_runtime>
  305. ///
  306. /// Settings this to `false` is useful when using an ad-hoc signature, making it less strict.
  307. pub hardened_runtime: bool,
  308. /// Provider short name for notarization.
  309. pub provider_short_name: Option<String>,
  310. /// Path to the entitlements.plist file.
  311. pub entitlements: Option<String>,
  312. /// Path to the Info.plist file for the bundle.
  313. pub info_plist_path: Option<PathBuf>,
  314. }
  315. /// Configuration for a target language for the WiX build.
  316. #[derive(Debug, Clone, Default)]
  317. pub struct WixLanguageConfig {
  318. /// The path to a locale (`.wxl`) file. See <https://wixtoolset.org/documentation/manual/v3/howtos/ui_and_localization/build_a_localized_version.html>.
  319. pub locale_path: Option<PathBuf>,
  320. }
  321. /// The languages to build using WiX.
  322. #[derive(Debug, Clone)]
  323. pub struct WixLanguage(pub Vec<(String, WixLanguageConfig)>);
  324. impl Default for WixLanguage {
  325. fn default() -> Self {
  326. Self(vec![("en-US".into(), Default::default())])
  327. }
  328. }
  329. /// Settings specific to the WiX implementation.
  330. #[derive(Clone, Debug, Default)]
  331. pub struct WixSettings {
  332. /// A GUID upgrade code for MSI installer. This code **_must stay the same across all of your updates_**,
  333. /// otherwise, Windows will treat your update as a different app and your users will have duplicate versions of your app.
  334. ///
  335. /// By default, tauri generates this code by generating a Uuid v5 using the string `<productName>.exe.app.x64` in the DNS namespace.
  336. /// You can use Tauri's CLI to generate and print this code for you by running `tauri inspect wix-upgrade-code`.
  337. ///
  338. /// It is recommended that you set this value in your tauri config file to avoid accidental changes in your upgrade code
  339. /// whenever you want to change your product name.
  340. pub upgrade_code: Option<uuid::Uuid>,
  341. /// The app languages to build. See <https://docs.microsoft.com/en-us/windows/win32/msi/localizing-the-error-and-actiontext-tables>.
  342. pub language: WixLanguage,
  343. /// By default, the bundler uses an internal template.
  344. /// This option allows you to define your own wix file.
  345. pub template: Option<PathBuf>,
  346. /// A list of paths to .wxs files with WiX fragments to use.
  347. pub fragment_paths: Vec<PathBuf>,
  348. /// The ComponentGroup element ids you want to reference from the fragments.
  349. pub component_group_refs: Vec<String>,
  350. /// The Component element ids you want to reference from the fragments.
  351. pub component_refs: Vec<String>,
  352. /// The FeatureGroup element ids you want to reference from the fragments.
  353. pub feature_group_refs: Vec<String>,
  354. /// The Feature element ids you want to reference from the fragments.
  355. pub feature_refs: Vec<String>,
  356. /// The Merge element ids you want to reference from the fragments.
  357. pub merge_refs: Vec<String>,
  358. /// Create an elevated update task within Windows Task Scheduler.
  359. pub enable_elevated_update_task: bool,
  360. /// Path to a bitmap file to use as the installation user interface banner.
  361. /// This bitmap will appear at the top of all but the first page of the installer.
  362. ///
  363. /// The required dimensions are 493px × 58px.
  364. pub banner_path: Option<PathBuf>,
  365. /// Path to a bitmap file to use on the installation user interface dialogs.
  366. /// It is used on the welcome and completion dialogs.
  367. /// The required dimensions are 493px × 312px.
  368. pub dialog_image_path: Option<PathBuf>,
  369. /// Enables FIPS compliant algorithms.
  370. pub fips_compliant: bool,
  371. }
  372. /// Settings specific to the NSIS implementation.
  373. #[derive(Clone, Debug, Default)]
  374. pub struct NsisSettings {
  375. /// A custom .nsi template to use.
  376. pub template: Option<PathBuf>,
  377. /// The path to a bitmap file to display on the header of installers pages.
  378. ///
  379. /// The recommended dimensions are 150px x 57px.
  380. pub header_image: Option<PathBuf>,
  381. /// The path to a bitmap file for the Welcome page and the Finish page.
  382. ///
  383. /// The recommended dimensions are 164px x 314px.
  384. pub sidebar_image: Option<PathBuf>,
  385. /// The path to an icon file used as the installer icon.
  386. pub installer_icon: Option<PathBuf>,
  387. /// Whether the installation will be for all users or just the current user.
  388. pub install_mode: NSISInstallerMode,
  389. /// A list of installer languages.
  390. /// By default the OS language is used. If the OS language is not in the list of languages, the first language will be used.
  391. /// To allow the user to select the language, set `display_language_selector` to `true`.
  392. ///
  393. /// See <https://github.com/kichik/nsis/tree/9465c08046f00ccb6eda985abbdbf52c275c6c4d/Contrib/Language%20files> for the complete list of languages.
  394. pub languages: Option<Vec<String>>,
  395. /// An key-value pair where the key is the language and the
  396. /// value is the path to a custom `.nsi` file that holds the translated text for tauri's custom messages.
  397. ///
  398. /// See <https://github.com/tauri-apps/tauri/blob/dev/crates/tauri-bundler/src/bundle/windows/nsis/languages/English.nsh> for an example `.nsi` file.
  399. ///
  400. /// **Note**: the key must be a valid NSIS language and it must be added to [`NsisConfig`]languages array,
  401. pub custom_language_files: Option<HashMap<String, PathBuf>>,
  402. /// Whether to display a language selector dialog before the installer and uninstaller windows are rendered or not.
  403. /// By default the OS language is selected, with a fallback to the first language in the `languages` array.
  404. pub display_language_selector: bool,
  405. /// Set compression algorithm used to compress files in the installer.
  406. pub compression: NsisCompression,
  407. /// Set the folder name for the start menu shortcut.
  408. ///
  409. /// Use this option if you have multiple apps and wish to group their shortcuts under one folder
  410. /// or if you generally prefer to set your shortcut inside a folder.
  411. ///
  412. /// Examples:
  413. /// - `AwesomePublisher`, shortcut will be placed in `%AppData%\Microsoft\Windows\Start Menu\Programs\AwesomePublisher\<your-app>.lnk`
  414. /// - If unset, shortcut will be placed in `%AppData%\Microsoft\Windows\Start Menu\Programs\<your-app>.lnk`
  415. pub start_menu_folder: Option<String>,
  416. /// A path to a `.nsh` file that contains special NSIS macros to be hooked into the
  417. /// main installer.nsi script.
  418. ///
  419. /// Supported hooks are:
  420. /// - `NSIS_HOOK_PREINSTALL`: This hook runs before copying files, setting registry key values and creating shortcuts.
  421. /// - `NSIS_HOOK_POSTINSTALL`: This hook runs after the installer has finished copying all files, setting the registry keys and created shortcuts.
  422. /// - `NSIS_HOOK_PREUNINSTALL`: This hook runs before removing any files, registry keys and shortcuts.
  423. /// - `NSIS_HOOK_POSTUNINSTALL`: This hook runs after files, registry keys and shortcuts have been removed.
  424. ///
  425. ///
  426. /// ### Example
  427. ///
  428. /// ```nsh
  429. /// !macro NSIS_HOOK_PREINSTALL
  430. /// MessageBox MB_OK "PreInstall"
  431. /// !macroend
  432. ///
  433. /// !macro NSIS_HOOK_POSTINSTALL
  434. /// MessageBox MB_OK "PostInstall"
  435. /// !macroend
  436. ///
  437. /// !macro NSIS_HOOK_PREUNINSTALL
  438. /// MessageBox MB_OK "PreUnInstall"
  439. /// !macroend
  440. ///
  441. /// !macro NSIS_HOOK_POSTUNINSTALL
  442. /// MessageBox MB_OK "PostUninstall"
  443. /// !macroend
  444. /// ```
  445. pub installer_hooks: Option<PathBuf>,
  446. /// Try to ensure that the WebView2 version is equal to or newer than this version,
  447. /// if the user's WebView2 is older than this version,
  448. /// the installer will try to trigger a WebView2 update.
  449. pub minimum_webview2_version: Option<String>,
  450. }
  451. /// The Custom Signing Command Settings for Windows exe
  452. #[derive(Clone, Debug)]
  453. pub struct CustomSignCommandSettings {
  454. /// The command to run to sign the binary.
  455. pub cmd: String,
  456. /// The arguments to pass to the command.
  457. ///
  458. /// "%1" will be replaced with the path to the binary to be signed.
  459. pub args: Vec<String>,
  460. }
  461. /// The Windows bundle settings.
  462. #[derive(Clone, Debug)]
  463. pub struct WindowsSettings {
  464. /// The file digest algorithm to use for creating file signatures. Required for code signing. SHA-256 is recommended.
  465. pub digest_algorithm: Option<String>,
  466. /// The SHA1 hash of the signing certificate.
  467. pub certificate_thumbprint: Option<String>,
  468. /// Server to use during timestamping.
  469. pub timestamp_url: Option<String>,
  470. /// Whether to use Time-Stamp Protocol (TSP, a.k.a. RFC 3161) for the timestamp server. Your code signing provider may
  471. /// use a TSP timestamp server, like e.g. SSL.com does. If so, enable TSP by setting to true.
  472. pub tsp: bool,
  473. /// WiX configuration.
  474. pub wix: Option<WixSettings>,
  475. /// Nsis configuration.
  476. pub nsis: Option<NsisSettings>,
  477. /// The path to the application icon. Defaults to `./icons/icon.ico`.
  478. pub icon_path: PathBuf,
  479. /// The installation mode for the Webview2 runtime.
  480. pub webview_install_mode: WebviewInstallMode,
  481. /// Validates a second app installation, blocking the user from installing an older version if set to `false`.
  482. ///
  483. /// For instance, if `1.2.1` is installed, the user won't be able to install app version `1.2.0` or `1.1.5`.
  484. ///
  485. /// /// The default value of this flag is `true`.
  486. pub allow_downgrades: bool,
  487. /// Specify a custom command to sign the binaries.
  488. /// This command needs to have a `%1` in it which is just a placeholder for the binary path,
  489. /// which we will detect and replace before calling the command.
  490. ///
  491. /// Example:
  492. /// ```text
  493. /// sign-cli --arg1 --arg2 %1
  494. /// ```
  495. ///
  496. /// By Default we use `signtool.exe` which can be found only on Windows so
  497. /// if you are on another platform and want to cross-compile and sign you will
  498. /// need to use another tool like `osslsigncode`.
  499. pub sign_command: Option<CustomSignCommandSettings>,
  500. }
  501. impl Default for WindowsSettings {
  502. fn default() -> Self {
  503. Self {
  504. digest_algorithm: None,
  505. certificate_thumbprint: None,
  506. timestamp_url: None,
  507. tsp: false,
  508. wix: None,
  509. nsis: None,
  510. icon_path: PathBuf::from("icons/icon.ico"),
  511. webview_install_mode: Default::default(),
  512. allow_downgrades: true,
  513. sign_command: None,
  514. }
  515. }
  516. }
  517. /// The bundle settings of the BuildArtifact we're bundling.
  518. #[derive(Clone, Debug, Default)]
  519. pub struct BundleSettings {
  520. /// the app's identifier.
  521. pub identifier: Option<String>,
  522. /// The app's publisher. Defaults to the second element in the identifier string.
  523. ///
  524. /// Currently maps to the Manufacturer property of the Windows Installer
  525. /// and the Maintainer field of debian packages if the Cargo.toml does not have the authors field.
  526. pub publisher: Option<String>,
  527. /// A url to the home page of your application. If None, will
  528. /// fallback to [PackageSettings::homepage].
  529. ///
  530. /// Supported bundle targets: `deb`, `rpm`, `nsis` and `msi`
  531. pub homepage: Option<String>,
  532. /// the app's icon list.
  533. pub icon: Option<Vec<String>>,
  534. /// the app's resources to bundle.
  535. ///
  536. /// each item can be a path to a file or a path to a folder.
  537. ///
  538. /// supports glob patterns.
  539. pub resources: Option<Vec<String>>,
  540. /// The app's resources to bundle. Takes precedence over `Self::resources` when specified.
  541. ///
  542. /// Maps each resource path to its target directory in the bundle resources directory.
  543. ///
  544. /// Supports glob patterns.
  545. pub resources_map: Option<HashMap<String, String>>,
  546. /// the app's copyright.
  547. pub copyright: Option<String>,
  548. /// The package's license identifier to be included in the appropriate bundles.
  549. /// If not set, defaults to the license from the Cargo.toml file.
  550. pub license: Option<String>,
  551. /// The path to the license file to be included in the appropriate bundles.
  552. pub license_file: Option<PathBuf>,
  553. /// the app's category.
  554. pub category: Option<AppCategory>,
  555. /// the file associations
  556. pub file_associations: Option<Vec<FileAssociation>>,
  557. /// the app's short description.
  558. pub short_description: Option<String>,
  559. /// the app's long description.
  560. pub long_description: Option<String>,
  561. // Bundles for other binaries:
  562. /// Configuration map for the apps to bundle.
  563. pub bin: Option<HashMap<String, BundleSettings>>,
  564. /// External binaries to add to the bundle.
  565. ///
  566. /// Note that each binary name should have the target platform's target triple appended,
  567. /// as well as `.exe` for Windows.
  568. /// For example, if you're bundling a sidecar called `sqlite3`, the bundler expects
  569. /// a binary named `sqlite3-x86_64-unknown-linux-gnu` on linux,
  570. /// and `sqlite3-x86_64-pc-windows-gnu.exe` on windows.
  571. ///
  572. /// Run `tauri build --help` for more info on targets.
  573. ///
  574. /// If you are building a universal binary for MacOS, the bundler expects
  575. /// your external binary to also be universal, and named after the target triple,
  576. /// e.g. `sqlite3-universal-apple-darwin`. See
  577. /// <https://developer.apple.com/documentation/apple-silicon/building-a-universal-macos-binary>
  578. pub external_bin: Option<Vec<String>>,
  579. /// Deep-link protocols.
  580. pub deep_link_protocols: Option<Vec<DeepLinkProtocol>>,
  581. /// Debian-specific settings.
  582. pub deb: DebianSettings,
  583. /// AppImage-specific settings.
  584. pub appimage: AppImageSettings,
  585. /// Rpm-specific settings.
  586. pub rpm: RpmSettings,
  587. /// DMG-specific settings.
  588. pub dmg: DmgSettings,
  589. /// MacOS-specific settings.
  590. pub macos: MacOsSettings,
  591. /// Updater configuration.
  592. pub updater: Option<UpdaterSettings>,
  593. /// Windows-specific settings.
  594. pub windows: WindowsSettings,
  595. }
  596. /// A binary to bundle.
  597. #[derive(Clone, Debug)]
  598. pub struct BundleBinary {
  599. name: String,
  600. main: bool,
  601. src_path: Option<String>,
  602. }
  603. impl BundleBinary {
  604. /// Creates a new bundle binary.
  605. pub fn new(name: String, main: bool) -> Self {
  606. Self {
  607. name,
  608. main,
  609. src_path: None,
  610. }
  611. }
  612. /// Creates a new bundle binary with path.
  613. pub fn with_path(name: String, main: bool, src_path: Option<String>) -> Self {
  614. Self {
  615. name,
  616. src_path,
  617. main,
  618. }
  619. }
  620. /// Mark the binary as the main executable.
  621. pub fn set_main(&mut self, main: bool) {
  622. self.main = main;
  623. }
  624. /// Sets the binary name.
  625. pub fn set_name(&mut self, name: String) {
  626. self.name = name;
  627. }
  628. /// Sets the src path of the binary.
  629. #[must_use]
  630. pub fn set_src_path(mut self, src_path: Option<String>) -> Self {
  631. self.src_path = src_path;
  632. self
  633. }
  634. /// Returns the binary `main` flag.
  635. pub fn main(&self) -> bool {
  636. self.main
  637. }
  638. /// Returns the binary name.
  639. pub fn name(&self) -> &str {
  640. &self.name
  641. }
  642. /// Returns the binary source path.
  643. pub fn src_path(&self) -> Option<&String> {
  644. self.src_path.as_ref()
  645. }
  646. }
  647. #[derive(Clone, Copy, Debug, Eq, PartialEq)]
  648. pub enum Arch {
  649. /// For the x86_64 / x64 / AMD64 instruction sets (64 bits).
  650. X86_64,
  651. /// For the x86 / i686 / i686 / 8086 instruction sets (32 bits).
  652. X86,
  653. /// For the AArch64 / ARM64 instruction sets (64 bits).
  654. AArch64,
  655. /// For the AArch32 / ARM32 instruction sets with hard-float (32 bits).
  656. Armhf,
  657. /// For the AArch32 / ARM32 instruction sets with soft-float (32 bits).
  658. Armel,
  659. /// For universal macOS applications.
  660. Universal,
  661. }
  662. /// The Settings exposed by the module.
  663. #[derive(Clone, Debug)]
  664. pub struct Settings {
  665. /// The log level.
  666. log_level: log::Level,
  667. /// the package settings.
  668. package: PackageSettings,
  669. /// the package types we're bundling.
  670. ///
  671. /// if not present, we'll use the PackageType list for the target OS.
  672. package_types: Option<Vec<PackageType>>,
  673. /// the directory where the bundles will be placed.
  674. project_out_directory: PathBuf,
  675. /// the directory to place tools used by the bundler,
  676. /// if `None`, tools are placed in the current user's platform-specific cache directory.
  677. local_tools_directory: Option<PathBuf>,
  678. /// the bundle settings.
  679. bundle_settings: BundleSettings,
  680. /// the binaries to bundle.
  681. binaries: Vec<BundleBinary>,
  682. /// The target triple.
  683. target: String,
  684. }
  685. /// A builder for [`Settings`].
  686. #[derive(Default)]
  687. pub struct SettingsBuilder {
  688. log_level: Option<log::Level>,
  689. project_out_directory: Option<PathBuf>,
  690. package_types: Option<Vec<PackageType>>,
  691. package_settings: Option<PackageSettings>,
  692. bundle_settings: BundleSettings,
  693. binaries: Vec<BundleBinary>,
  694. target: Option<String>,
  695. local_tools_directory: Option<PathBuf>,
  696. }
  697. impl SettingsBuilder {
  698. /// Creates the default settings builder.
  699. pub fn new() -> Self {
  700. Default::default()
  701. }
  702. /// Sets the project output directory. It's used as current working directory.
  703. #[must_use]
  704. pub fn project_out_directory<P: AsRef<Path>>(mut self, path: P) -> Self {
  705. self
  706. .project_out_directory
  707. .replace(path.as_ref().to_path_buf());
  708. self
  709. }
  710. /// Sets the directory to place tools used by the bundler
  711. /// when [`BundleSettings::use_local_tools_dir`] is true.
  712. #[must_use]
  713. pub fn local_tools_directory<P: AsRef<Path>>(mut self, path: P) -> Self {
  714. self
  715. .local_tools_directory
  716. .replace(path.as_ref().to_path_buf());
  717. self
  718. }
  719. /// Sets the package types to create.
  720. #[must_use]
  721. pub fn package_types(mut self, package_types: Vec<PackageType>) -> Self {
  722. self.package_types = Some(package_types);
  723. self
  724. }
  725. /// Sets the package settings.
  726. #[must_use]
  727. pub fn package_settings(mut self, settings: PackageSettings) -> Self {
  728. self.package_settings.replace(settings);
  729. self
  730. }
  731. /// Sets the bundle settings.
  732. #[must_use]
  733. pub fn bundle_settings(mut self, settings: BundleSettings) -> Self {
  734. self.bundle_settings = settings;
  735. self
  736. }
  737. /// Sets the binaries to bundle.
  738. #[must_use]
  739. pub fn binaries(mut self, binaries: Vec<BundleBinary>) -> Self {
  740. self.binaries = binaries;
  741. self
  742. }
  743. /// Sets the target triple.
  744. #[must_use]
  745. pub fn target(mut self, target: String) -> Self {
  746. self.target.replace(target);
  747. self
  748. }
  749. /// Sets the log level for spawned commands. Defaults to [`log::Level::Error`].
  750. #[must_use]
  751. pub fn log_level(mut self, level: log::Level) -> Self {
  752. self.log_level.replace(level);
  753. self
  754. }
  755. /// Builds a Settings from the CLI args.
  756. ///
  757. /// Package settings will be read from Cargo.toml.
  758. ///
  759. /// Bundle settings will be read from $TAURI_DIR/tauri.conf.json if it exists and fallback to Cargo.toml's [package.metadata.bundle].
  760. pub fn build(self) -> crate::Result<Settings> {
  761. let target = if let Some(t) = self.target {
  762. t
  763. } else {
  764. target_triple()?
  765. };
  766. Ok(Settings {
  767. log_level: self.log_level.unwrap_or(log::Level::Error),
  768. package: self
  769. .package_settings
  770. .ok_or_else(|| crate::Error::GenericError("package settings is required".into()))?,
  771. package_types: self.package_types,
  772. project_out_directory: self
  773. .project_out_directory
  774. .ok_or_else(|| crate::Error::GenericError("out directory is required".into()))?,
  775. local_tools_directory: self.local_tools_directory,
  776. binaries: self.binaries,
  777. bundle_settings: BundleSettings {
  778. external_bin: self
  779. .bundle_settings
  780. .external_bin
  781. .as_ref()
  782. .map(|bins| external_binaries(bins, &target)),
  783. ..self.bundle_settings
  784. },
  785. target,
  786. })
  787. }
  788. }
  789. impl Settings {
  790. /// Sets the log level for spawned commands.
  791. pub fn set_log_level(&mut self, level: log::Level) {
  792. self.log_level = level;
  793. }
  794. /// Returns the log level for spawned commands.
  795. pub fn log_level(&self) -> log::Level {
  796. self.log_level
  797. }
  798. /// Returns the directory where the bundle should be placed.
  799. pub fn project_out_directory(&self) -> &Path {
  800. &self.project_out_directory
  801. }
  802. /// Returns the target triple.
  803. pub fn target(&self) -> &str {
  804. &self.target
  805. }
  806. /// Returns the architecture for the binary being bundled (e.g. "arm", "x86" or "x86_64").
  807. pub fn binary_arch(&self) -> Arch {
  808. if self.target.starts_with("x86_64") {
  809. Arch::X86_64
  810. } else if self.target.starts_with('i') {
  811. Arch::X86
  812. } else if self.target.starts_with("arm") && self.target.ends_with("hf") {
  813. Arch::Armhf
  814. } else if self.target.starts_with("arm") {
  815. Arch::Armel
  816. } else if self.target.starts_with("aarch64") {
  817. Arch::AArch64
  818. } else if self.target.starts_with("universal") {
  819. Arch::Universal
  820. } else {
  821. panic!("Unexpected target triple {}", self.target)
  822. }
  823. }
  824. /// Returns the file name of the binary being bundled.
  825. pub fn main_binary(&self) -> crate::Result<&BundleBinary> {
  826. self
  827. .binaries
  828. .iter()
  829. .find(|bin| bin.main)
  830. .context("failed to find main binary, make sure you have a `package > default-run` in the Cargo.toml file")
  831. .map_err(Into::into)
  832. }
  833. /// Returns the file name of the binary being bundled.
  834. pub fn main_binary_mut(&mut self) -> crate::Result<&mut BundleBinary> {
  835. self
  836. .binaries
  837. .iter_mut()
  838. .find(|bin| bin.main)
  839. .context("failed to find main binary, make sure you have a `package > default-run` in the Cargo.toml file")
  840. .map_err(Into::into)
  841. }
  842. /// Returns the file name of the binary being bundled.
  843. pub fn main_binary_name(&self) -> crate::Result<&str> {
  844. self
  845. .binaries
  846. .iter()
  847. .find(|bin| bin.main)
  848. .context("failed to find main binary, make sure you have a `package > default-run` in the Cargo.toml file")
  849. .map(|b| b.name())
  850. .map_err(Into::into)
  851. }
  852. /// Returns the path to the specified binary.
  853. pub fn binary_path(&self, binary: &BundleBinary) -> PathBuf {
  854. let target_os = self
  855. .target()
  856. .split('-')
  857. .nth(2)
  858. .unwrap_or(std::env::consts::OS);
  859. let path = self.project_out_directory.join(binary.name());
  860. if target_os == "windows" {
  861. path.with_extension("exe")
  862. } else {
  863. path
  864. }
  865. }
  866. /// Returns the list of binaries to bundle.
  867. pub fn binaries(&self) -> &Vec<BundleBinary> {
  868. &self.binaries
  869. }
  870. /// If a list of package types was specified by the command-line, returns
  871. /// that list filtered by the current target OS available targets.
  872. ///
  873. /// If a target triple was specified by the
  874. /// command-line, returns the native package type(s) for that target.
  875. ///
  876. /// Otherwise returns the native package type(s) for the host platform.
  877. ///
  878. /// Fails if the host/target's native package type is not supported.
  879. pub fn package_types(&self) -> crate::Result<Vec<PackageType>> {
  880. let target_os = self
  881. .target
  882. .split('-')
  883. .nth(2)
  884. .unwrap_or(std::env::consts::OS)
  885. .replace("darwin", "macos");
  886. let platform_types = match target_os.as_str() {
  887. "macos" => vec![PackageType::MacOsBundle, PackageType::Dmg],
  888. "ios" => vec![PackageType::IosBundle],
  889. "linux" => vec![PackageType::Deb, PackageType::Rpm, PackageType::AppImage],
  890. "windows" => vec![PackageType::WindowsMsi, PackageType::Nsis],
  891. os => {
  892. return Err(crate::Error::GenericError(format!(
  893. "Native {os} bundles not yet supported."
  894. )))
  895. }
  896. };
  897. if let Some(package_types) = &self.package_types {
  898. let mut types = vec![];
  899. for package_type in package_types {
  900. let package_type = *package_type;
  901. if platform_types
  902. .clone()
  903. .into_iter()
  904. .any(|t| t == package_type)
  905. {
  906. types.push(package_type);
  907. }
  908. }
  909. Ok(types)
  910. } else {
  911. Ok(platform_types)
  912. }
  913. }
  914. /// Returns the product name.
  915. pub fn product_name(&self) -> &str {
  916. &self.package.product_name
  917. }
  918. /// Returns the bundle's identifier
  919. pub fn bundle_identifier(&self) -> &str {
  920. self.bundle_settings.identifier.as_deref().unwrap_or("")
  921. }
  922. /// Returns the bundle's publisher
  923. pub fn publisher(&self) -> Option<&str> {
  924. self.bundle_settings.publisher.as_deref()
  925. }
  926. /// Returns an iterator over the icon files to be used for this bundle.
  927. pub fn icon_files(&self) -> ResourcePaths<'_> {
  928. match self.bundle_settings.icon {
  929. Some(ref paths) => ResourcePaths::new(paths.as_slice(), false),
  930. None => ResourcePaths::new(&[], false),
  931. }
  932. }
  933. /// Returns an iterator over the resource files to be included in this
  934. /// bundle.
  935. pub fn resource_files(&self) -> ResourcePaths<'_> {
  936. match (
  937. &self.bundle_settings.resources,
  938. &self.bundle_settings.resources_map,
  939. ) {
  940. (Some(paths), None) => ResourcePaths::new(paths.as_slice(), true),
  941. (None, Some(map)) => ResourcePaths::from_map(map, true),
  942. (Some(_), Some(_)) => panic!("cannot use both `resources` and `resources_map`"),
  943. (None, None) => ResourcePaths::new(&[], true),
  944. }
  945. }
  946. /// Returns an iterator over the external binaries to be included in this
  947. /// bundle.
  948. pub fn external_binaries(&self) -> ResourcePaths<'_> {
  949. match self.bundle_settings.external_bin {
  950. Some(ref paths) => ResourcePaths::new(paths.as_slice(), true),
  951. None => ResourcePaths::new(&[], true),
  952. }
  953. }
  954. /// Copies external binaries to a path.
  955. ///
  956. /// Returns the list of destination paths.
  957. pub fn copy_binaries(&self, path: &Path) -> crate::Result<Vec<PathBuf>> {
  958. let mut paths = Vec::new();
  959. for src in self.external_binaries() {
  960. let src = src?;
  961. let dest = path.join(
  962. src
  963. .file_name()
  964. .expect("failed to extract external binary filename")
  965. .to_string_lossy()
  966. .replace(&format!("-{}", self.target), ""),
  967. );
  968. common::copy_file(&src, &dest)?;
  969. paths.push(dest);
  970. }
  971. Ok(paths)
  972. }
  973. /// Copies resources to a path.
  974. pub fn copy_resources(&self, path: &Path) -> crate::Result<()> {
  975. for resource in self.resource_files().iter() {
  976. let resource = resource?;
  977. let dest = path.join(resource.target());
  978. common::copy_file(resource.path(), dest)?;
  979. }
  980. Ok(())
  981. }
  982. /// Returns the version string of the bundle.
  983. pub fn version_string(&self) -> &str {
  984. &self.package.version
  985. }
  986. /// Returns the copyright text.
  987. pub fn copyright_string(&self) -> Option<&str> {
  988. self.bundle_settings.copyright.as_deref()
  989. }
  990. /// Returns the list of authors name.
  991. pub fn author_names(&self) -> &[String] {
  992. match self.package.authors {
  993. Some(ref names) => names.as_slice(),
  994. None => &[],
  995. }
  996. }
  997. /// Returns the authors as a comma-separated string.
  998. pub fn authors_comma_separated(&self) -> Option<String> {
  999. let names = self.author_names();
  1000. if names.is_empty() {
  1001. None
  1002. } else {
  1003. Some(names.join(", "))
  1004. }
  1005. }
  1006. /// Returns the bundle license.
  1007. pub fn license(&self) -> Option<String> {
  1008. self.bundle_settings.license.clone()
  1009. }
  1010. /// Returns the bundle license file.
  1011. pub fn license_file(&self) -> Option<PathBuf> {
  1012. self.bundle_settings.license_file.clone()
  1013. }
  1014. /// Returns the package's homepage URL, defaulting to "" if not defined.
  1015. pub fn homepage_url(&self) -> Option<&str> {
  1016. self
  1017. .bundle_settings
  1018. .homepage
  1019. .as_deref()
  1020. .or(self.package.homepage.as_deref())
  1021. }
  1022. /// Returns the app's category.
  1023. pub fn app_category(&self) -> Option<AppCategory> {
  1024. self.bundle_settings.category
  1025. }
  1026. /// Return file associations.
  1027. pub fn file_associations(&self) -> Option<&Vec<FileAssociation>> {
  1028. self.bundle_settings.file_associations.as_ref()
  1029. }
  1030. /// Return the list of deep link protocols to be registered for
  1031. /// this bundle.
  1032. pub fn deep_link_protocols(&self) -> Option<&Vec<DeepLinkProtocol>> {
  1033. self.bundle_settings.deep_link_protocols.as_ref()
  1034. }
  1035. /// Returns the app's short description.
  1036. pub fn short_description(&self) -> &str {
  1037. self
  1038. .bundle_settings
  1039. .short_description
  1040. .as_ref()
  1041. .unwrap_or(&self.package.description)
  1042. }
  1043. /// Returns the app's long description.
  1044. pub fn long_description(&self) -> Option<&str> {
  1045. self.bundle_settings.long_description.as_deref()
  1046. }
  1047. /// Returns the directory for local tools path.
  1048. pub fn local_tools_directory(&self) -> Option<&Path> {
  1049. self.local_tools_directory.as_deref()
  1050. }
  1051. /// Returns the debian settings.
  1052. pub fn deb(&self) -> &DebianSettings {
  1053. &self.bundle_settings.deb
  1054. }
  1055. /// Returns the appimage settings.
  1056. pub fn appimage(&self) -> &AppImageSettings {
  1057. &self.bundle_settings.appimage
  1058. }
  1059. /// Returns the RPM settings.
  1060. pub fn rpm(&self) -> &RpmSettings {
  1061. &self.bundle_settings.rpm
  1062. }
  1063. /// Returns the DMG settings.
  1064. pub fn dmg(&self) -> &DmgSettings {
  1065. &self.bundle_settings.dmg
  1066. }
  1067. /// Returns the MacOS settings.
  1068. pub fn macos(&self) -> &MacOsSettings {
  1069. &self.bundle_settings.macos
  1070. }
  1071. /// Returns the Windows settings.
  1072. pub fn windows(&self) -> &WindowsSettings {
  1073. &self.bundle_settings.windows
  1074. }
  1075. /// Returns the Updater settings.
  1076. pub fn updater(&self) -> Option<&UpdaterSettings> {
  1077. self.bundle_settings.updater.as_ref()
  1078. }
  1079. }