mirror of
https://github.com/tauri-apps/tauri.git
synced 2024-11-28 12:27:16 +03:00
parent
463fd00d06
commit
4791961981
5
.changes/wix-bundle-language.md
Normal file
5
.changes/wix-bundle-language.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
"tauri-bundler": patch
|
||||
---
|
||||
|
||||
Allow setting the Windows installer language and using project names that contains non-Unicode characters.
|
5
.changes/wix-config-language.md
Normal file
5
.changes/wix-config-language.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
"cli.rs": patch
|
||||
---
|
||||
|
||||
Adds `tauri > bundle > windows > wix > language` config option. See https://docs.microsoft.com/en-us/windows/win32/msi/localizing-the-error-and-actiontext-tables.
|
@ -160,6 +160,7 @@ It's composed of the following properties:
|
||||
{ property: "certificateThumbprint", optional: true, type: "string[]", description: `Specifies the SHA1 hash of the signing certificate.` },
|
||||
{ property: "timestampUrl", optional: true, type: "string[]", description: `Server to use during timestamping.` },
|
||||
{ property: "wix", optional: true, type: "object", child: <Properties anchorRoot="tauri.bundle.windows.wix" rows={[
|
||||
{ property: "language", optional: true, type: "string", description: `The installer language. See https://docs.microsoft.com/en-us/windows/win32/msi/localizing-the-error-and-actiontext-tables.` },
|
||||
{ property: "template", optional: true, type: "string", description: `A custom .wxs template to use.` },
|
||||
{ property: "fragmentPaths", optional: true, type: "string[]", description: `A list of paths to .wxs files with WiX fragments to use.` },
|
||||
{ property: "componentGroupRefs", optional: true, type: "string[]", description: `The ComponentGroup element ids you want to reference from the fragments.` },
|
||||
|
@ -175,6 +175,8 @@ pub struct MacOsSettings {
|
||||
/// Settings specific to the WiX implementation.
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct WixSettings {
|
||||
/// The app language. See https://docs.microsoft.com/en-us/windows/win32/msi/localizing-the-error-and-actiontext-tables.
|
||||
pub language: String,
|
||||
/// By default, the bundler uses an internal template.
|
||||
/// This option allows you to define your own wix file.
|
||||
pub template: Option<PathBuf>,
|
||||
|
154
tooling/bundler/src/bundle/windows/msi/languages.json
Normal file
154
tooling/bundler/src/bundle/windows/msi/languages.json
Normal file
@ -0,0 +1,154 @@
|
||||
{
|
||||
"ar-SA": {
|
||||
"langId": 1025,
|
||||
"asciiCode": 1256
|
||||
},
|
||||
"ca-ES": {
|
||||
"langId": 1027,
|
||||
"asciiCode": 1252
|
||||
},
|
||||
"zh-TW": {
|
||||
"langId": 1028,
|
||||
"asciiCode": 950
|
||||
},
|
||||
"zh-CN": {
|
||||
"langId": 2052,
|
||||
"asciiCode": 936
|
||||
},
|
||||
"cs-CZ": {
|
||||
"langId": 1029,
|
||||
"asciiCode": 1250
|
||||
},
|
||||
"da-DK": {
|
||||
"langId": 1030,
|
||||
"asciiCode": 1252
|
||||
},
|
||||
"de-DE": {
|
||||
"langId": 1031,
|
||||
"asciiCode": 1252
|
||||
},
|
||||
"el-GR": {
|
||||
"langId": 1032,
|
||||
"asciiCode": 1253
|
||||
},
|
||||
"en-US": {
|
||||
"langId": 1033,
|
||||
"asciiCode": 1252
|
||||
},
|
||||
"es-ES": {
|
||||
"langId": 3082,
|
||||
"asciiCode": 1252
|
||||
},
|
||||
"et-EE": {
|
||||
"langId": 1061,
|
||||
"asciiCode": 1257
|
||||
},
|
||||
"fi-FI": {
|
||||
"langId": 1035,
|
||||
"asciiCode": 1252
|
||||
},
|
||||
"fr-FR": {
|
||||
"langId": 1036,
|
||||
"asciiCode": 1252
|
||||
},
|
||||
"he-IL": {
|
||||
"langId": 1037,
|
||||
"asciiCode": 1255
|
||||
},
|
||||
"hu-HU": {
|
||||
"langId": 1038,
|
||||
"asciiCode": 1250
|
||||
},
|
||||
"it-IT": {
|
||||
"langId": 1040,
|
||||
"asciiCode": 1252
|
||||
},
|
||||
"jp-JP": {
|
||||
"langId": 1041,
|
||||
"asciiCode": 932
|
||||
},
|
||||
"ko-KO": {
|
||||
"langId": 1042,
|
||||
"asciiCode": 949
|
||||
},
|
||||
"lt-LT": {
|
||||
"langId": 1063,
|
||||
"asciiCode": 1257
|
||||
},
|
||||
"lv-LV": {
|
||||
"langId": 1062,
|
||||
"asciiCode": 1257
|
||||
},
|
||||
"nl-NL": {
|
||||
"langId": 1043,
|
||||
"asciiCode": 1252
|
||||
},
|
||||
"nb-NO": {
|
||||
"langId": 1044,
|
||||
"asciiCode": 1252
|
||||
},
|
||||
"pl-PL": {
|
||||
"langId": 1045,
|
||||
"asciiCode": 1250
|
||||
},
|
||||
"pt-BR": {
|
||||
"langId": 1046,
|
||||
"asciiCode": 1252
|
||||
},
|
||||
"pt-PT": {
|
||||
"langId": 2070,
|
||||
"asciiCode": 1252
|
||||
},
|
||||
"ro-RO": {
|
||||
"langId": 1048,
|
||||
"asciiCode": 1250
|
||||
},
|
||||
"ru-RU": {
|
||||
"langId": 1049,
|
||||
"asciiCode": 1251
|
||||
},
|
||||
"hr-HR": {
|
||||
"langId": 1050,
|
||||
"asciiCode": 1250
|
||||
},
|
||||
"sk-SK": {
|
||||
"langId": 1051,
|
||||
"asciiCode": 1250
|
||||
},
|
||||
"sv-SE": {
|
||||
"langId": 1053,
|
||||
"asciiCode": 1252
|
||||
},
|
||||
"th-TH": {
|
||||
"langId": 1054,
|
||||
"asciiCode": 874
|
||||
},
|
||||
"tr-TR": {
|
||||
"langId": 1055,
|
||||
"asciiCode": 1254
|
||||
},
|
||||
"sl-SI": {
|
||||
"langId": 1060,
|
||||
"asciiCode": 1250
|
||||
},
|
||||
"vi-VN": {
|
||||
"langId": 1066,
|
||||
"asciiCode": 1258
|
||||
},
|
||||
"eu-ES": {
|
||||
"langId": 1069,
|
||||
"asciiCode": 1252
|
||||
},
|
||||
"bg-BG": {
|
||||
"langId": 1026,
|
||||
"asciiCode": 1251
|
||||
},
|
||||
"uk-UA": {
|
||||
"langId": 1058,
|
||||
"asciiCode": 1251
|
||||
},
|
||||
"sr-Latn-CS": {
|
||||
"langId": 2074,
|
||||
"asciiCode": 1250
|
||||
}
|
||||
}
|
@ -11,14 +11,14 @@ use crate::bundle::{
|
||||
|
||||
use handlebars::{to_json, Handlebars};
|
||||
use regex::Regex;
|
||||
use serde::Serialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sha2::Digest;
|
||||
use uuid::Uuid;
|
||||
use zip::ZipArchive;
|
||||
|
||||
use std::{
|
||||
collections::BTreeMap,
|
||||
fs::{create_dir_all, remove_dir_all, write, File},
|
||||
collections::{BTreeMap, HashMap},
|
||||
fs::{create_dir_all, remove_dir_all, rename, write, File},
|
||||
io::{Cursor, Read, Write},
|
||||
path::{Path, PathBuf},
|
||||
process::{Command, Stdio},
|
||||
@ -52,6 +52,14 @@ const UUID_NAMESPACE: [u8; 16] = [
|
||||
/// Mapper between a resource directory name and its ResourceDirectory descriptor.
|
||||
type ResourceMap = BTreeMap<String, ResourceDirectory>;
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct LanguageMetadata {
|
||||
#[serde(rename = "asciiCode")]
|
||||
ascii_code: usize,
|
||||
#[serde(rename = "langId")]
|
||||
lang_id: usize,
|
||||
}
|
||||
|
||||
/// A binary to bundle with WIX.
|
||||
/// External binaries or additional project binaries are represented with this data structure.
|
||||
/// This data structure is needed because WIX requires each path to have its own `id` and `guid`.
|
||||
@ -313,10 +321,10 @@ fn run_candle(
|
||||
fn run_light(
|
||||
wix_toolset_path: &Path,
|
||||
build_path: &Path,
|
||||
wixobjs: &[&str],
|
||||
arguments: Vec<String>,
|
||||
output_path: &Path,
|
||||
settings: &Settings,
|
||||
) -> crate::Result<PathBuf> {
|
||||
) -> crate::Result<()> {
|
||||
let light_exe = wix_toolset_path.join("light.exe");
|
||||
|
||||
let mut args: Vec<String> = vec![
|
||||
@ -326,8 +334,8 @@ fn run_light(
|
||||
output_path.display().to_string(),
|
||||
];
|
||||
|
||||
for p in wixobjs {
|
||||
args.push((*p).to_string());
|
||||
for p in arguments {
|
||||
args.push(p);
|
||||
}
|
||||
|
||||
let mut cmd = Command::new(&light_exe);
|
||||
@ -336,19 +344,16 @@ fn run_light(
|
||||
.stdout(Stdio::piped())
|
||||
.current_dir(build_path);
|
||||
|
||||
common::print_info(format!("running light to produce {}", output_path.display()).as_str())?;
|
||||
common::execute_with_verbosity(&mut cmd, settings)
|
||||
.map(|_| output_path.to_path_buf())
|
||||
.map_err(|_| {
|
||||
crate::Error::ShellScriptError(format!(
|
||||
"error running light.exe{}",
|
||||
if settings.is_verbose() {
|
||||
""
|
||||
} else {
|
||||
", try running with --verbose to see command output"
|
||||
}
|
||||
))
|
||||
})
|
||||
common::execute_with_verbosity(&mut cmd, settings).map_err(|_| {
|
||||
crate::Error::ShellScriptError(format!(
|
||||
"error running light.exe{}",
|
||||
if settings.is_verbose() {
|
||||
""
|
||||
} else {
|
||||
", try running with --verbose to see command output"
|
||||
}
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
// fn get_icon_data() -> crate::Result<()> {
|
||||
@ -406,6 +411,29 @@ pub fn build_wix_app_installer(
|
||||
|
||||
let mut data = BTreeMap::new();
|
||||
|
||||
let language_map: HashMap<String, LanguageMetadata> =
|
||||
serde_json::from_str(include_str!("./languages.json")).unwrap();
|
||||
|
||||
let (language, language_metadata) = if let Some(wix) = &settings.windows().wix {
|
||||
let metadata = language_map.get(&wix.language).unwrap_or_else(|| {
|
||||
panic!(
|
||||
"Language {} not found. It must be one of {}",
|
||||
wix.language,
|
||||
language_map
|
||||
.keys()
|
||||
.cloned()
|
||||
.collect::<Vec<String>>()
|
||||
.join(", ")
|
||||
)
|
||||
});
|
||||
(wix.language.clone(), metadata)
|
||||
} else {
|
||||
common::print_info("Wix settings not found. Using `en-US` as language.")?;
|
||||
("en-US".into(), language_map.get("en-US").unwrap())
|
||||
};
|
||||
data.insert("language_id", to_json(language_metadata.lang_id));
|
||||
data.insert("ascii_codepage", to_json(language_metadata.ascii_code));
|
||||
|
||||
data.insert("product_name", to_json(settings.product_name()));
|
||||
data.insert("version", to_json(settings.version_string()));
|
||||
let manufacturer = settings.bundle_identifier().to_string();
|
||||
@ -511,16 +539,26 @@ pub fn build_wix_app_installer(
|
||||
run_candle(settings, wix_toolset_path, &output_path, wxs)?;
|
||||
}
|
||||
|
||||
let wixobjs = vec!["*.wixobj"];
|
||||
let target = run_light(
|
||||
let arguments = vec![
|
||||
format!("-cultures:{}", language.to_lowercase()),
|
||||
"*.wixobj".into(),
|
||||
];
|
||||
let msi_output_path = output_path.join("output.msi");
|
||||
let msi_path = app_installer_dir(settings)?;
|
||||
create_dir_all(msi_path.parent().unwrap())?;
|
||||
|
||||
common::print_info(format!("running light to produce {}", msi_path.display()).as_str())?;
|
||||
|
||||
run_light(
|
||||
wix_toolset_path,
|
||||
&output_path,
|
||||
&wixobjs,
|
||||
&app_installer_dir(settings)?,
|
||||
arguments,
|
||||
&msi_output_path,
|
||||
settings,
|
||||
)?;
|
||||
rename(&msi_output_path, &msi_path)?;
|
||||
|
||||
Ok(target)
|
||||
Ok(msi_path)
|
||||
}
|
||||
|
||||
/// Generates the data required for the external binaries and extra binaries bundling.
|
||||
|
@ -13,18 +13,18 @@
|
||||
Id="*"
|
||||
Name="{{{product_name}}}"
|
||||
UpgradeCode="{{{upgrade_code}}}"
|
||||
Language="1033"
|
||||
Codepage="1252"
|
||||
Language="{{language_id}}"
|
||||
Codepage="{{ascii_codepage}}"
|
||||
Manufacturer="{{{manufacturer}}}"
|
||||
Version="{{{version}}}">
|
||||
|
||||
<Package Id="*"
|
||||
Keywords="Installer"
|
||||
InstallerVersion="450"
|
||||
Languages="1033"
|
||||
Languages="{{language_id}}"
|
||||
Compressed="yes"
|
||||
InstallScope="perMachine"
|
||||
SummaryCodepage="1252"/>
|
||||
SummaryCodepage="{{ascii_codepage}}"/>
|
||||
|
||||
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed."
|
||||
MigrateFeatures="yes" />
|
||||
|
@ -53,9 +53,16 @@ pub struct MacConfig {
|
||||
pub entitlements: Option<String>,
|
||||
}
|
||||
|
||||
fn default_language() -> String {
|
||||
"en-US".into()
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
|
||||
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||
pub struct WixConfig {
|
||||
/// App language. See https://docs.microsoft.com/en-us/windows/win32/msi/localizing-the-error-and-actiontext-tables.
|
||||
#[serde(default = "default_language")]
|
||||
pub language: String,
|
||||
pub template: Option<PathBuf>,
|
||||
#[serde(default)]
|
||||
pub fragment_paths: Vec<PathBuf>,
|
||||
|
@ -1289,6 +1289,11 @@
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"language": {
|
||||
"description": "App language. See https://docs.microsoft.com/en-us/windows/win32/msi/localizing-the-error-and-actiontext-tables.",
|
||||
"default": "en-US",
|
||||
"type": "string"
|
||||
},
|
||||
"mergeRefs": {
|
||||
"default": [],
|
||||
"type": "array",
|
||||
|
@ -16,6 +16,7 @@ pub use config_definition::*;
|
||||
impl From<WixConfig> for tauri_bundler::WixSettings {
|
||||
fn from(config: WixConfig) -> tauri_bundler::WixSettings {
|
||||
tauri_bundler::WixSettings {
|
||||
language: config.language,
|
||||
template: config.template,
|
||||
fragment_paths: config.fragment_paths,
|
||||
component_group_refs: config.component_group_refs,
|
||||
|
Loading…
Reference in New Issue
Block a user