mirror of
https://github.com/tauri-apps/tauri.git
synced 2024-12-01 11:13:40 +03:00
parent
7471e347d3
commit
69ea51ec93
5
.changes/wix-fragments.md
Normal file
5
.changes/wix-fragments.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
"tauri-bundler": patch
|
||||
---
|
||||
|
||||
Adds support to `wix` fragments for custom .msi installer functionality.
|
@ -28,7 +28,7 @@ pub use self::{
|
||||
},
|
||||
};
|
||||
#[cfg(windows)]
|
||||
pub use settings::WindowsSettings;
|
||||
pub use settings::{WindowsSettings, WixSettings};
|
||||
|
||||
use common::print_finished;
|
||||
|
||||
|
@ -165,6 +165,24 @@ pub struct MacOsSettings {
|
||||
pub entitlements: Option<String>,
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
#[derive(Clone, Debug, Deserialize, Default)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct WixSettings {
|
||||
#[serde(default)]
|
||||
pub fragment_paths: Vec<PathBuf>,
|
||||
#[serde(default)]
|
||||
pub component_group_refs: Vec<String>,
|
||||
#[serde(default)]
|
||||
pub component_refs: Vec<String>,
|
||||
#[serde(default)]
|
||||
pub feature_group_refs: Vec<String>,
|
||||
#[serde(default)]
|
||||
pub feature_refs: Vec<String>,
|
||||
#[serde(default)]
|
||||
pub merge_refs: Vec<String>,
|
||||
}
|
||||
|
||||
/// The Windows bundle settings.
|
||||
#[cfg(windows)]
|
||||
#[derive(Clone, Debug, Deserialize, Default)]
|
||||
@ -172,6 +190,7 @@ pub struct WindowsSettings {
|
||||
pub digest_algorithm: Option<String>,
|
||||
pub certificate_thumbprint: Option<String>,
|
||||
pub timestamp_url: Option<String>,
|
||||
pub wix: Option<WixSettings>,
|
||||
}
|
||||
|
||||
/// The bundle settings of the BuildArtifact we're bundling.
|
||||
|
@ -157,6 +157,24 @@
|
||||
</Feature>
|
||||
</Feature>
|
||||
|
||||
<Feature Id="External" AllowAdvertise="no" Absent="disallow">
|
||||
{{#each component_group_refs as |id| ~}}
|
||||
<ComponentGroupRef Id="{{ id }}"/>
|
||||
{{/each~}}
|
||||
{{#each component_refs as |id| ~}}
|
||||
<ComponentRef Id="{{ id }}"/>
|
||||
{{/each~}}
|
||||
{{#each feature_group_refs as |id| ~}}
|
||||
<FeatureGroupRef Id="{{ id }}"/>
|
||||
{{/each~}}
|
||||
{{#each feature_refs as |id| ~}}
|
||||
<FeatureRef Id="{{ id }}"/>
|
||||
{{/each~}}
|
||||
{{#each merge_refs as |id| ~}}
|
||||
<MergeRef Id="{{ id }}"/>
|
||||
{{/each~}}
|
||||
</Feature>
|
||||
|
||||
<!-- WebView2 -->
|
||||
<Property Id="WVRTINSTALLED">
|
||||
<RegistrySearch Id="WVRTInstalled" Root="HKLM" Key="SOFTWARE\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" Name="pv" Type="raw" Win64="no"/>
|
||||
|
@ -3,8 +3,6 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use super::common;
|
||||
use libflate::gzip;
|
||||
use walkdir::WalkDir;
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
use super::macos_bundle;
|
||||
@ -159,7 +157,7 @@ fn bundle_update(settings: &Settings, bundles: &[Bundle]) -> crate::Result<Vec<P
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
pub fn create_zip(src_file: &PathBuf, dst_file: &PathBuf) -> crate::Result<PathBuf> {
|
||||
pub fn create_zip(src_file: &Path, dst_file: &Path) -> crate::Result<PathBuf> {
|
||||
let parent_dir = dst_file.parent().expect("No data in parent");
|
||||
fs::create_dir_all(parent_dir)?;
|
||||
let writer = common::create_file(dst_file)?;
|
||||
@ -186,7 +184,7 @@ pub fn create_zip(src_file: &PathBuf, dst_file: &PathBuf) -> crate::Result<PathB
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
fn create_tar(src_dir: &Path, dest_path: &Path) -> crate::Result<PathBuf> {
|
||||
let dest_file = common::create_file(&dest_path)?;
|
||||
let gzip_encoder = gzip::Encoder::new(dest_file)?;
|
||||
let gzip_encoder = libflate::gzip::Encoder::new(dest_file)?;
|
||||
|
||||
let gzip_encoder = create_tar_from_src(src_dir, gzip_encoder)?;
|
||||
let mut dest_file = gzip_encoder.finish().into_result()?;
|
||||
@ -210,7 +208,7 @@ fn create_tar_from_src<P: AsRef<Path>, W: Write>(src_dir: P, dest_file: W) -> cr
|
||||
|
||||
tar_builder.append_file(file_name, &mut src_file)?;
|
||||
} else {
|
||||
for entry in WalkDir::new(&src_dir) {
|
||||
for entry in walkdir::WalkDir::new(&src_dir) {
|
||||
let entry = entry?;
|
||||
let src_path = entry.path();
|
||||
if src_path == src_dir {
|
||||
|
@ -62,7 +62,7 @@ lazy_static! {
|
||||
|
||||
handlebars
|
||||
.register_template_string("main.wxs", include_str!("templates/main.wxs"))
|
||||
.or_else(|e| Err(e.to_string()))
|
||||
.map_err(|e| e.to_string())
|
||||
.expect("Failed to setup handlebar template");
|
||||
handlebars
|
||||
};
|
||||
@ -143,7 +143,7 @@ impl ResourceDirectory {
|
||||
}
|
||||
directories.push_str(wix_string.as_str());
|
||||
}
|
||||
let wix_string = if self.name == "" {
|
||||
let wix_string = if self.name.is_empty() {
|
||||
format!("{}{}", files, directories)
|
||||
} else {
|
||||
format!(
|
||||
@ -278,64 +278,12 @@ pub fn get_and_extract_wix(path: &Path) -> crate::Result<()> {
|
||||
extract_zip(&data, path)
|
||||
}
|
||||
|
||||
// For if bundler needs DLL files.
|
||||
|
||||
// fn run_heat_exe(
|
||||
// wix_toolset_path: &Path,
|
||||
// build_path: &Path,
|
||||
// harvest_dir: &Path,
|
||||
// platform: &str,
|
||||
// ) -> Result<(), String> {
|
||||
// let mut args = vec!["dir"];
|
||||
|
||||
// let harvest_str = harvest_dir.display().to_string();
|
||||
|
||||
// args.push(&harvest_str);
|
||||
// args.push("-platform");
|
||||
// args.push(platform);
|
||||
// args.push("-cg");
|
||||
// args.push("AppFiles");
|
||||
// args.push("-dr");
|
||||
// args.push("APPLICATIONFOLDER");
|
||||
// args.push("-gg");
|
||||
// args.push("-srd");
|
||||
// args.push("-out");
|
||||
// args.push("appdir.wxs");
|
||||
// args.push("-var");
|
||||
// args.push("var.SourceDir");
|
||||
|
||||
// let heat_exe = wix_toolset_path.join("heat.exe");
|
||||
|
||||
// let mut cmd = Command::new(&heat_exe)
|
||||
// .args(&args)
|
||||
// .stdout(Stdio::piped())
|
||||
// .current_dir(build_path)
|
||||
// .spawn()
|
||||
// .expect("error running heat.exe");
|
||||
|
||||
// {
|
||||
// let stdout = cmd.stdout.as_mut().unwrap();
|
||||
// let reader = BufReader::new(stdout);
|
||||
|
||||
// for line in reader.lines() {
|
||||
// info!(logger, "{}", line.unwrap());
|
||||
// }
|
||||
// }
|
||||
|
||||
// let status = cmd.wait().unwrap();
|
||||
// if status.success() {
|
||||
// Ok(())
|
||||
// } else {
|
||||
// Err("error running heat.exe".to_string())
|
||||
// }
|
||||
// }
|
||||
|
||||
/// Runs the Candle.exe executable for Wix. Candle parses the wxs file and generates the code for building the installer.
|
||||
fn run_candle(
|
||||
settings: &Settings,
|
||||
wix_toolset_path: &Path,
|
||||
build_path: &Path,
|
||||
wxs_file_name: &str,
|
||||
cwd: &Path,
|
||||
wxs_file_path: &Path,
|
||||
) -> crate::Result<()> {
|
||||
let arch = match settings.binary_arch() {
|
||||
"x86_64" => "x64",
|
||||
@ -357,7 +305,7 @@ fn run_candle(
|
||||
let args = vec![
|
||||
"-arch".to_string(),
|
||||
arch.to_string(),
|
||||
wxs_file_name.to_string(),
|
||||
wxs_file_path.to_string_lossy().to_string(),
|
||||
format!(
|
||||
"-dSourceDir={}",
|
||||
settings.binary_path(main_binary).display()
|
||||
@ -365,13 +313,10 @@ fn run_candle(
|
||||
];
|
||||
|
||||
let candle_exe = wix_toolset_path.join("candle.exe");
|
||||
common::print_info(format!("running candle for {}", wxs_file_name).as_str())?;
|
||||
common::print_info(format!("running candle for {:?}", wxs_file_path).as_str())?;
|
||||
|
||||
let mut cmd = Command::new(&candle_exe);
|
||||
cmd
|
||||
.args(&args)
|
||||
.stdout(Stdio::piped())
|
||||
.current_dir(build_path);
|
||||
cmd.args(&args).stdout(Stdio::piped()).current_dir(cwd);
|
||||
|
||||
common::print_info("running candle.exe")?;
|
||||
common::execute_with_verbosity(&mut cmd, &settings).map_err(|_| {
|
||||
@ -532,6 +477,17 @@ pub fn build_wix_app_installer(
|
||||
|
||||
data.insert("icon_path", to_json(icon_path));
|
||||
|
||||
let mut fragment_paths = Vec::new();
|
||||
|
||||
if let Some(wix) = &settings.windows().wix {
|
||||
data.insert("component_group_refs", to_json(&wix.component_group_refs));
|
||||
data.insert("component_refs", to_json(&wix.component_refs));
|
||||
data.insert("feature_group_refs", to_json(&wix.feature_group_refs));
|
||||
data.insert("feature_refs", to_json(&wix.feature_refs));
|
||||
data.insert("merge_refs", to_json(&wix.merge_refs));
|
||||
fragment_paths = wix.fragment_paths.clone();
|
||||
}
|
||||
|
||||
let temp = HANDLEBARS.render("main.wxs", &data)?;
|
||||
|
||||
if output_path.exists() {
|
||||
@ -543,14 +499,18 @@ pub fn build_wix_app_installer(
|
||||
let main_wxs_path = output_path.join("main.wxs");
|
||||
write(&main_wxs_path, temp)?;
|
||||
|
||||
let input_basenames = vec!["main"];
|
||||
let mut candle_inputs = vec!["main.wxs".into()];
|
||||
|
||||
for basename in &input_basenames {
|
||||
let wxs = format!("{}.wxs", basename);
|
||||
let current_dir = std::env::current_dir()?;
|
||||
for fragment_path in fragment_paths {
|
||||
candle_inputs.push(current_dir.join(fragment_path));
|
||||
}
|
||||
|
||||
for wxs in &candle_inputs {
|
||||
run_candle(settings, &wix_toolset_path, &output_path, &wxs)?;
|
||||
}
|
||||
|
||||
let wixobjs = vec!["main.wixobj"];
|
||||
let wixobjs = vec!["*.wixobj"];
|
||||
let target = run_light(
|
||||
&wix_toolset_path,
|
||||
&output_path,
|
||||
@ -600,12 +560,12 @@ fn locate_signtool() -> crate::Result<PathBuf> {
|
||||
let mut kit_bin_paths: Vec<PathBuf> = installed_kits
|
||||
.iter()
|
||||
.rev()
|
||||
.map(|kit| kits_root_10_bin_path.join(kit).to_path_buf())
|
||||
.map(|kit| kits_root_10_bin_path.join(kit))
|
||||
.collect();
|
||||
|
||||
/* Add kits root bin path.
|
||||
For Windows SDK 10 versions earlier than v10.0.15063.468, signtool will be located there. */
|
||||
kit_bin_paths.push(kits_root_10_bin_path.to_path_buf());
|
||||
kit_bin_paths.push(kits_root_10_bin_path);
|
||||
|
||||
// Choose which version of SignTool to use based on OS bitness
|
||||
let arch_dir = match bitness::os_bitness().expect("failed to get os bitness") {
|
||||
@ -622,7 +582,7 @@ fn locate_signtool() -> crate::Result<PathBuf> {
|
||||
/* Check if SignTool exists at this location. */
|
||||
if signtool_path.exists() {
|
||||
// SignTool found. Return it.
|
||||
return Ok(signtool_path.to_path_buf());
|
||||
return Ok(signtool_path);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@ use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value as JsonValue;
|
||||
use serde_with::skip_serializing_none;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::{collections::HashMap, path::PathBuf};
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
|
||||
#[serde(untagged)]
|
||||
@ -41,12 +41,30 @@ pub struct MacConfig {
|
||||
pub entitlements: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
|
||||
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||
pub struct WixConfig {
|
||||
#[serde(default)]
|
||||
pub fragment_paths: Vec<PathBuf>,
|
||||
#[serde(default)]
|
||||
pub component_group_refs: Vec<String>,
|
||||
#[serde(default)]
|
||||
pub component_refs: Vec<String>,
|
||||
#[serde(default)]
|
||||
pub feature_group_refs: Vec<String>,
|
||||
#[serde(default)]
|
||||
pub feature_refs: Vec<String>,
|
||||
#[serde(default)]
|
||||
pub merge_refs: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
|
||||
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||
pub struct WindowsConfig {
|
||||
pub digest_algorithm: Option<String>,
|
||||
pub certificate_thumbprint: Option<String>,
|
||||
pub timestamp_url: Option<String>,
|
||||
pub wix: Option<WixConfig>,
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
|
@ -90,7 +90,8 @@
|
||||
"windows": {
|
||||
"certificateThumbprint": null,
|
||||
"digestAlgorithm": null,
|
||||
"timestampUrl": null
|
||||
"timestampUrl": null,
|
||||
"wix": null
|
||||
}
|
||||
},
|
||||
"updater": {
|
||||
@ -343,7 +344,8 @@
|
||||
"default": {
|
||||
"certificateThumbprint": null,
|
||||
"digestAlgorithm": null,
|
||||
"timestampUrl": null
|
||||
"timestampUrl": null,
|
||||
"wix": null
|
||||
},
|
||||
"allOf": [
|
||||
{
|
||||
@ -909,7 +911,8 @@
|
||||
"windows": {
|
||||
"certificateThumbprint": null,
|
||||
"digestAlgorithm": null,
|
||||
"timestampUrl": null
|
||||
"timestampUrl": null,
|
||||
"wix": null
|
||||
}
|
||||
},
|
||||
"allOf": [
|
||||
@ -1159,6 +1162,64 @@
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"wix": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/WixConfig"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"WixConfig": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"componentGroupRefs": {
|
||||
"default": [],
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"componentRefs": {
|
||||
"default": [],
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"featureGroupRefs": {
|
||||
"default": [],
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"featureRefs": {
|
||||
"default": [],
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"fragmentPaths": {
|
||||
"default": [],
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"mergeRefs": {
|
||||
"default": [],
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
|
@ -352,6 +352,7 @@ fn tauri_config_to_bundle_settings(
|
||||
timestamp_url: config.windows.timestamp_url,
|
||||
digest_algorithm: config.windows.digest_algorithm,
|
||||
certificate_thumbprint: config.windows.certificate_thumbprint,
|
||||
wix: config.windows.wix.map(|w| w.into()),
|
||||
},
|
||||
updater: Some(UpdaterSettings {
|
||||
active: updater_config.active,
|
||||
|
@ -12,6 +12,20 @@ use serde_json::Value as JsonValue;
|
||||
mod config_definition;
|
||||
pub use config_definition::*;
|
||||
|
||||
#[cfg(windows)]
|
||||
impl From<WixConfig> for tauri_bundler::WixSettings {
|
||||
fn from(config: WixConfig) -> tauri_bundler::WixSettings {
|
||||
tauri_bundler::WixSettings {
|
||||
fragment_paths: config.fragment_paths,
|
||||
component_group_refs: config.component_group_refs,
|
||||
component_refs: config.component_refs,
|
||||
feature_group_refs: config.feature_group_refs,
|
||||
feature_refs: config.feature_refs,
|
||||
merge_refs: config.merge_refs,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
use std::{
|
||||
env::set_var,
|
||||
fs::File,
|
||||
|
Loading…
Reference in New Issue
Block a user