Skip to content

Commit 17da87d

Browse files
fix(bundler/nsis): write installer templates UTF16LE encoded, closes #7036 (#7040)
* fix(bundler/nsis): write installer templates UTF16LE encoded, closes #7036 * cleanup * lint * return err instead of panic * Update .changes/nsis-encoding.md [skip ci] --------- Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
1 parent 8b9f6cf commit 17da87d

File tree

5 files changed

+87
-129
lines changed

5 files changed

+87
-129
lines changed

.changes/nsis-encoding.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'tauri-bundler': 'patch:bug'
3+
---
4+
5+
Fix NSIS bundler failing to build when `productName` contained chinsese characters.

tooling/bundler/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ handlebars = "4.3"
3131
tempfile = "3.5.0"
3232
log = { version = "0.4.17", features = [ "kv_unstable" ] }
3333
dirs-next = "2.0"
34-
encoding_rs = "0.8"
3534
os_pipe = "1"
3635
attohttpc = { version = "0.25", default-features = false }
3736
hex = "0.4"

tooling/bundler/src/bundle/windows/nsis.rs

Lines changed: 44 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -258,16 +258,14 @@ fn build_nsis_app_installer(
258258
}),
259259
);
260260

261-
let languages_data = languages
262-
.iter()
263-
.filter_map(|lang| {
264-
if let Some(data) = get_lang_data(lang, custom_language_files.as_ref()) {
265-
Some(data)
261+
let mut languages_data = Vec::new();
262+
for lang in &languages {
263+
if let Some(data) = get_lang_data(lang, custom_language_files.as_ref())? {
264+
languages_data.push(data);
266265
} else {
267266
log::warn!("Custom tauri messages for {lang} are not translated.\nIf it is a valid language listed on <https://github.com/kichik/nsis/tree/9465c08046f00ccb6eda985abbdbf52c275c6c4d/Contrib/Language%20files>, please open a Tauri feature request\n or you can provide a custom language file for it in `tauri.conf.json > tauri > bundle > windows > nsis > custom_language_files`");
268-
None
269267
}
270-
}).collect::<Vec<_>>();
268+
}
271269

272270
data.insert("languages", to_json(languages.clone()));
273271
data.insert(
@@ -417,19 +415,14 @@ fn build_nsis_app_installer(
417415
.expect("Failed to setup handlebar template");
418416
}
419417
let installer_nsi_path = output_path.join("installer.nsi");
420-
write(
418+
write_ut16_le_with_bom(
421419
&installer_nsi_path,
422-
encoding_rs::UTF_8
423-
.encode(handlebars.render("installer.nsi", &data)?.as_str())
424-
.0,
420+
handlebars.render("installer.nsi", &data)?.as_str(),
425421
)?;
426422

427423
for (lang, data) in languages_data.iter() {
428-
if let Some((content, encoding)) = data {
429-
write(
430-
output_path.join(lang).with_extension("nsh"),
431-
encoding.encode(content).0,
432-
)?;
424+
if let Some(content) = data {
425+
write_ut16_le_with_bom(output_path.join(lang).with_extension("nsh"), content)?;
433426
}
434427
}
435428

@@ -553,113 +546,44 @@ fn generate_binaries_data(settings: &Settings) -> crate::Result<BinariesMap> {
553546
fn get_lang_data(
554547
lang: &str,
555548
custom_lang_files: Option<&HashMap<String, PathBuf>>,
556-
) -> Option<(
557-
String,
558-
Option<(&'static str, &'static encoding_rs::Encoding)>,
559-
)> {
560-
use encoding_rs::*;
561-
549+
) -> crate::Result<Option<(PathBuf, Option<&'static str>)>> {
562550
if let Some(path) = custom_lang_files.and_then(|h| h.get(lang)) {
563-
return Some((
564-
dunce::canonicalize(path)
565-
.unwrap()
566-
.to_string_lossy()
567-
.to_string(),
568-
None,
569-
));
551+
return Ok(Some((dunce::canonicalize(path)?, None)));
570552
}
571553

572-
let lang_file = format!("{lang}.nsh");
573-
match lang.to_lowercase().as_str() {
574-
"arabic" => Some((
575-
lang_file,
576-
Some((
577-
include_str!("./templates/nsis-languages/Arabic.nsh"),
578-
UTF_16LE,
579-
)),
580-
)),
581-
"dutch" => Some((
582-
lang_file,
583-
Some((include_str!("./templates/nsis-languages/Dutch.nsh"), UTF_8)),
584-
)),
585-
"english" => Some((
586-
lang_file,
587-
Some((
588-
include_str!("./templates/nsis-languages/English.nsh"),
589-
UTF_8,
590-
)),
591-
)),
592-
"japanese" => Some((
593-
lang_file,
594-
Some((
595-
include_str!("./templates/nsis-languages/Japanese.nsh"),
596-
UTF_8,
597-
)),
598-
)),
599-
"korean" => Some((
600-
lang_file,
601-
Some((include_str!("./templates/nsis-languages/Korean.nsh"), UTF_8)),
602-
)),
603-
"portuguesebr" => Some((
604-
lang_file,
605-
Some((
606-
include_str!("./templates/nsis-languages/PortugueseBR.nsh"),
607-
UTF_8,
608-
)),
609-
)),
610-
"tradchinese" => Some((
611-
lang_file,
612-
Some((
613-
include_str!("./templates/nsis-languages/TradChinese.nsh"),
614-
UTF_8,
615-
)),
616-
)),
617-
"simpchinese" => Some((
618-
lang_file,
619-
Some((
620-
include_str!("./templates/nsis-languages/SimpChinese.nsh"),
621-
UTF_8,
622-
)),
623-
)),
624-
"french" => Some((
625-
lang_file,
626-
Some((include_str!("./templates/nsis-languages/French.nsh"), UTF_8)),
554+
let lang_path = PathBuf::from(format!("{lang}.nsh"));
555+
let lang_content = match lang.to_lowercase().as_str() {
556+
"arabic" => Some(include_str!("./templates/nsis-languages/Arabic.nsh")),
557+
"dutch" => Some(include_str!("./templates/nsis-languages/Dutch.nsh")),
558+
"english" => Some(include_str!("./templates/nsis-languages/English.nsh")),
559+
"japanese" => Some(include_str!("./templates/nsis-languages/Japanese.nsh")),
560+
"korean" => Some(include_str!("./templates/nsis-languages/Korean.nsh")),
561+
"portuguesebr" => Some(include_str!("./templates/nsis-languages/PortugueseBR.nsh")),
562+
"tradchinese" => Some(include_str!("./templates/nsis-languages/TradChinese.nsh")),
563+
"simpchinese" => Some(include_str!("./templates/nsis-languages/SimpChinese.nsh")),
564+
"french" => Some(include_str!("./templates/nsis-languages/French.nsh")),
565+
"spanish" => Some(include_str!("./templates/nsis-languages/Spanish.nsh")),
566+
"spanishinternational" => Some(include_str!(
567+
"./templates/nsis-languages/SpanishInternational.nsh"
627568
)),
628-
"spanish" => Some((
629-
lang_file,
630-
Some((
631-
include_str!("./templates/nsis-languages/Spanish.nsh"),
632-
UTF_8,
633-
)),
634-
)),
635-
"spanishinternational" => Some((
636-
lang_file,
637-
Some((
638-
include_str!("./templates/nsis-languages/SpanishInternational.nsh"),
639-
UTF_8,
640-
)),
641-
)),
642-
"persian" => Some((
643-
lang_file,
644-
Some((
645-
include_str!("./templates/nsis-languages/Persian.nsh"),
646-
UTF_16LE,
647-
)),
648-
)),
649-
"turkish" => Some((
650-
lang_file,
651-
Some((
652-
include_str!("./templates/nsis-languages/Turkish.nsh"),
653-
UTF_8,
654-
)),
655-
)),
656-
"swedish" => Some((
657-
lang_file,
658-
Some((
659-
include_str!("./templates/nsis-languages/Swedish.nsh"),
660-
UTF_8,
661-
)),
662-
)),
663-
_ => None,
569+
"persian" => Some(include_str!("./templates/nsis-languages/Persian.nsh")),
570+
"turkish" => Some(include_str!("./templates/nsis-languages/Turkish.nsh")),
571+
"swedish" => Some(include_str!("./templates/nsis-languages/Swedish.nsh")),
572+
_ => return Ok(None),
573+
};
574+
575+
Ok(Some((lang_path, lang_content)))
576+
}
577+
578+
fn write_ut16_le_with_bom<P: AsRef<Path>>(path: P, content: &str) -> crate::Result<()> {
579+
use std::fs::File;
580+
use std::io::{BufWriter, Write};
581+
582+
let file = File::create(path)?;
583+
let mut output = BufWriter::new(file);
584+
output.write_all(&[0xFF, 0xFE])?; // the BOM part
585+
for utf16 in content.encode_utf16() {
586+
output.write_all(&utf16.to_le_bytes())?;
664587
}
588+
Ok(())
665589
}

tooling/bundler/src/bundle/windows/templates/nsis-languages/Persian.nsh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,4 @@ LangString webview2DownloadSuccess ${LANG_PERSIAN} "WebView2 بوت استرپر
2424
LangString webview2Downloading ${LANG_PERSIAN} "دانلود بوت استرپر WebView2..."
2525
LangString webview2InstallError ${LANG_PERSIAN} "ارور: نصب WebView2 با کد $1 شکست خورد"
2626
LangString webview2InstallSuccess ${LANG_PERSIAN} "WebView2 با موفقیت نصب شد"
27-
LangString deleteAppData ${LANG_PERSIAN} "حذف دیتا های اپلیکیشن"
27+
LangString deleteAppData ${LANG_PERSIAN} "حذف دیتا های اپلیکیشن"

tooling/cli/Cargo.lock

Lines changed: 37 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)