diff --git a/build/capareport-server.spec b/build/capareport-server.spec index f117c7b..791c736 100644 --- a/build/capareport-server.spec +++ b/build/capareport-server.spec @@ -62,7 +62,7 @@ if onefile: bootloader_ignore_signals=False, strip=False, upx=True, - console=True, + console=False, disable_windowed_traceback=False, argv_emulation=False, target_arch=None, diff --git a/docs/project_context.md b/docs/project_context.md index a591535..895dac4 100644 --- a/docs/project_context.md +++ b/docs/project_context.md @@ -393,3 +393,10 @@ - Cleanup verification completed: `.venv\Scripts\python.exe -m compileall app`, `npm run build`, PowerShell AST parse for `scripts/build.ps1`, Docker-hosted `sh -n scripts/build.sh`, and `cargo check --manifest-path src-tauri\Cargo.toml` with a temporary sidecar placeholder all passed. Linux/macOS native server and desktop packages still need native OS verification. - `src-tauri/gen/schemas/` is intentionally tracked because `src-tauri/capabilities/default.json` references `../gen/schemas/desktop-schema.json`; do not ignore or delete these schema files during cleanup, otherwise VS Code JSON validation reports a missing schema. - `README.md` has been rewritten to document local startup, Server Portable, Tauri desktop, Docker, Linux/macOS build commands, configuration blocks, common APIs, and cleanup rules. Keep future build instructions in sync with `scripts/build.*`. + +## 2026-05-20: Tauri desktop console and installer language + +- `src-tauri/src/main.rs` uses `#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]` so Windows release builds use the GUI subsystem and do not open an extra console window when launched from Explorer or the installer shortcut. +- `build/capareport-server.spec` keeps Server Portable in console mode, but desktop one-file sidecar builds (`CAPAREPORT_ONEFILE=1`) use PyInstaller `console=False`; PyInstaller should select `runw.exe` for the sidecar so it also stays hidden behind the Tauri window. +- `src-tauri/tauri.conf.json` sets Windows installer localization through `bundle.windows.wix.language = "zh-CN"` and `bundle.windows.nsis.languages = ["SimpChinese"]`. NSIS language keys must use NSIS names such as `SimpChinese`, while WiX/MSI uses locale names such as `zh-CN`. +- Verification on Windows: `cargo check --manifest-path src-tauri\Cargo.toml` passed, `scripts\build.bat desktop` generated the MSI and NSIS bundles, PE subsystem checks reported `Windows GUI` for both `capacity-report-desktop.exe` and `capareport-server.exe`, and the generated NSIS script included `MUI_LANGUAGE "SimpChinese"`. diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index c9c9884..db42283 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -1,7 +1,9 @@ +#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] + +use std::error::Error; use std::fs; use std::path::{Path, PathBuf}; use std::sync::Mutex; -use std::error::Error; use tauri::{Manager, Runtime}; use tauri_plugin_shell::process::CommandChild; @@ -38,7 +40,9 @@ fn resource_candidates( app: &tauri::App, name: &str, ) -> Result, Box> { - let resource_path = app.path().resolve(name, tauri::path::BaseDirectory::Resource)?; + let resource_path = app + .path() + .resolve(name, tauri::path::BaseDirectory::Resource)?; let escaped_parent_path = app .path() .resolve(format!("_up_/{name}"), tauri::path::BaseDirectory::Resource)?; @@ -66,13 +70,14 @@ fn start_server(app: &tauri::App) -> Result<(), Box> { let (mut rx, child) = app .shell() .sidecar("capareport-server")? - .env("CAPAREPORT_BASE_DIR", data_dir.to_string_lossy().to_string()) + .env( + "CAPAREPORT_BASE_DIR", + data_dir.to_string_lossy().to_string(), + ) .args(["--host", "127.0.0.1", "--port", "19082"]) .spawn()?; - tauri::async_runtime::spawn(async move { - while rx.recv().await.is_some() {} - }); + tauri::async_runtime::spawn(async move { while rx.recv().await.is_some() {} }); let pid = child.pid(); let state = app.state::(); @@ -82,11 +87,7 @@ fn start_server(app: &tauri::App) -> Result<(), Box> { fn stop_server(app: &tauri::AppHandle) { let state = app.state::(); - let child = state - .0 - .lock() - .expect("server state lock poisoned") - .take(); + let child = state.0.lock().expect("server state lock poisoned").take(); if let Some(process) = child { #[cfg(target_os = "windows")] { diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 529918c..8c4cc28 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -37,6 +37,16 @@ "resources": [ "../Configure.json", "../ReportScript.sql" - ] + ], + "windows": { + "wix": { + "language": "zh-CN" + }, + "nsis": { + "languages": [ + "SimpChinese" + ] + } + } } }