fix: daw_engine khong chay tren Windows - bundle resources sai layout

Spawn.log cho thay: resource_dir()/daw_engine/daw_engine.exe exists=false
tren ca ban cai lan target/release - engine KHONG duoc bundle dung cho.

Goc re (doc source tauri-utils/src/resources.rs + tauri-cli/src/interface/rust.rs):
- bundle.resources dang ARRAY ['resources/daw_engine']: ResourcePaths::new
  (Slice) -> target = resource_relpath(path) GIU TIEN TO 'resources/'
  -> engine nam o /resources/daw_engine/...
- lib.rs cu tim o /daw_engine/... -> exists=false.

Fix:
- tauri.conf.json: resources dang MAP {'resources/daw_engine': 'daw_engine/'}
  -> resources_map -> Walk mode, dest.join(strip_prefix) -> giu nguyen cay
  _internal, dich chuan /daw_engine/ (xac nhan tauri-cli
  BundleResources::Map -> settings.resources_map, dong 1467-1469).
- lib.rs: do them 3 vi tri fallback (legacy resources/ prefix, portable
  exe_dir, dev exe_dir/../resources) + log diagnostic day du vao spawn.log
  (liet ke noi dung resource_dir/exe_dir khi khong tim thay).
- build_windows.ps1: them huong dan xac minh spawn.log sau khi cai dat.
This commit is contained in:
2026-08-09 10:48:09 +00:00
parent 29ebbfc1c0
commit 0c0aadb8ee
4 changed files with 139 additions and 34 deletions
+10
View File
@@ -91,6 +91,16 @@ Nguyên nhân nặng cũ: `librosa` kéo theo `numba`+`llvmlite` (~171MB) + `sci
NSIS không còn lỗi mmapping; `hooks.nsh` cài VC++ Redistributable (MSI không NSIS không còn lỗi mmapping; `hooks.nsh` cài VC++ Redistributable (MSI không
chạy hooks → máy thiếu VC++ → daw_engine.exe không chạy — đây là nguyên nhân chạy hooks → máy thiếu VC++ → daw_engine.exe không chạy — đây là nguyên nhân
"build xong không chạy daw_engine" trên Windows). "build xong không chạy daw_engine" trên Windows).
- **Fix layout resources (bản 1.1.1 — `exists=false` trong spawn.log)**:
`bundle.resources` dạng ARRAY `["resources/daw_engine"]` copy engine tới
`$RESOURCE_DIR/resources/daw_engine/...` (giữ tiền tố `resources/` — đọc
source `tauri-utils/src/resources.rs`) trong khi lib.rs tìm ở
`$RESOURCE_DIR/daw_engine/...` → `exists=false`. Đổi sang dạng MAP
`{"resources/daw_engine": "daw_engine/"}` (Walk mode, giữ nguyên cây
`_internal`, đích chuẩn `daw_engine/`). `src-tauri/src/lib.rs` đồng thời dò
thêm 3 vị trí fallback (legacy/portable/dev) + ghi diagnostic đầy đủ vào
`%APPDATA%/SonicForgeDAW/logs/spawn.log` (liệt kê nội dung resource_dir khi
không tìm thấy).
Lệnh build 1 lệnh mỗi OS: Lệnh build 1 lệnh mỗi OS:
```bash ```bash
+6
View File
@@ -87,3 +87,9 @@ Write-Host ""
Write-Host "== DONE ==" Write-Host "== DONE =="
Write-Host " NSIS: src-tauri\target\release\bundle\nsis\SonicForgeDAW_1.0.0_x64-setup.exe" Write-Host " NSIS: src-tauri\target\release\bundle\nsis\SonicForgeDAW_1.0.0_x64-setup.exe"
Write-Host " MSI : src-tauri\target\release\bundle\msi\SonicForgeDAW_1.0.0_x64_en-US.msi" Write-Host " MSI : src-tauri\target\release\bundle\msi\SonicForgeDAW_1.0.0_x64_en-US.msi"
Write-Host ""
Write-Host "== XAC MINH SAU KHI CAI DAT (quan trong) =="
Write-Host " Mo %APPDATA%\SonicForgeDAW\logs\spawn.log - phai thay:"
Write-Host " [resource_dir/daw_engine (map layout)] ...exists=True"
Write-Host " Neu exists=False: bundle resources KHONG vao installer (chay lai buoc [4/6])."
Write-Host " Engine phai nam o: <thu muc cai dat>\daw_engine\daw_engine.exe"
+116 -27
View File
@@ -1,34 +1,90 @@
// SonicForge DAW — desktop shell: spawn/terminate daw_engine.exe sidecar. // SonicForge DAW — desktop shell: spawn/terminate daw_engine sidecar.
//
// QUAN TRONG (fix bản 1.1.1 — engine không chạy trên Windows):
// tauri.conf.json bundle.resources giờ dùng dạng MAP:
// { "resources/daw_engine": "daw_engine/" }
// vì dạng ARRAY ("resources/daw_engine") copy file tới
// $RESOURCE_DIR/resources/daw_engine/... (giữ tiền tố "resources/"),
// trong khi code cũ tìm ở $RESOURCE_DIR/daw_engine/... -> exists=false.
// Dạng map (Walk mode) giữ nguyên cây thư mục (_internal) dưới đích
// "daw_engine/" — đúng layout lib.rs chờ.
// Ngoài ra lib.rs còn dò THÊM các vị trí fallback (legacy/portable/dev)
// và ghi đầy đủ diagnostic vào %APPDATA%/SonicForgeDAW/logs/spawn.log.
use tauri::Manager; use tauri::Manager;
use tauri_plugin_shell::process::CommandChild; use tauri_plugin_shell::process::CommandChild;
use tauri_plugin_shell::ShellExt; use tauri_plugin_shell::ShellExt;
use std::path::{Path, PathBuf};
use std::sync::Mutex; use std::sync::Mutex;
struct EngineProcess(Mutex<Option<CommandChild>>); struct EngineProcess(Mutex<Option<CommandChild>>);
/// Các vị trí có thể chứa daw_engine, theo thứ tự ưu tiên.
fn engine_candidates(res_dir: &Path, exe_dir: &Path) -> Vec<(PathBuf, String)> {
let exe_name = if cfg!(windows) { "daw_engine.exe" } else { "daw_engine" };
vec![
// 1. Layout chuẩn (resources map): $RESOURCE/daw_engine/daw_engine.exe
(
res_dir.join("daw_engine").join(exe_name),
"resource_dir/daw_engine (map layout)".into(),
),
// 2. Legacy (resources array cũ giữ tiền tố resources/)
(
res_dir.join("resources").join("daw_engine").join(exe_name),
"resource_dir/resources/daw_engine (legacy array)".into(),
),
// 3. Portable: engine đặt cạnh exe
(
exe_dir.join("daw_engine").join(exe_name),
"exe_dir/daw_engine (portable)".into(),
),
// 4. Dev mode: target/{debug,release} -> src-tauri/resources
(
exe_dir.join("..").join("resources").join("daw_engine").join(exe_name),
"exe_dir/../resources/daw_engine (dev)".into(),
),
]
}
fn list_dir_snippet(dir: &Path) -> String {
let mut s = String::new();
match std::fs::read_dir(dir) {
Ok(rd) => {
let mut n = 0;
for e in rd.flatten() {
if n > 0 {
s.push_str(", ");
}
s.push_str(&e.file_name().to_string_lossy());
n += 1;
if n >= 15 {
s.push_str(", ...");
break;
}
}
}
Err(_) => s.push_str("<khong doc duoc dir>"),
}
s
}
#[cfg_attr(mobile, tauri::mobile_entry_point)] #[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() { pub fn run() {
tauri::Builder::default() tauri::Builder::default()
.plugin(tauri_plugin_shell::init()) .plugin(tauri_plugin_shell::init())
.plugin(tauri_plugin_dialog::init()) .plugin(tauri_plugin_dialog::init())
.setup(|app| { .setup(|app| {
// 1. Spawn daw_engine (PyInstaller ONEDIR bundle — khong giai nen
// moi lan chay nhu onefile, khoi dong nhanh). Bundle qua Tauri
// resources: resource_dir()/daw_engine/daw_engine(.exe)
let res_dir = app let res_dir = app
.path() .path()
.resource_dir() .resource_dir()
.expect("resource dir not found"); .expect("resource dir not found");
let engine_dir = res_dir.join("daw_engine"); let exe_dir = std::env::current_exe()
let engine_exe = if cfg!(windows) { .ok()
engine_dir.join("daw_engine.exe") .and_then(|p| p.parent().map(|d| d.to_path_buf()))
} else { .unwrap_or_default();
engine_dir.join("daw_engine") let candidates = engine_candidates(&res_dir, &exe_dir);
};
// Ghi log spawn de chan doan (UI khong duoc panic/thoat — chi log). // Ghi log spawn de chan doan — vao %APPDATA%/SonicForgeDAW/logs/
// Ghi vao %APPDATA%/SonicForgeDAW/logs/spawn.log (thu muc luon ton // spawn.log (thu muc luon ton tai), KHONG ghi vao engine_dir.
// tai) — KHONG ghi vao engine_dir vi thu muc do co the khong duoc
// bundle vao installer (resources loi) -> ghi am tham that bai.
let log_dir = std::env::var("APPDATA").unwrap_or_else(|_| ".".into()); let log_dir = std::env::var("APPDATA").unwrap_or_else(|_| ".".into());
let spawn_log_path = std::path::Path::new(&log_dir) let spawn_log_path = std::path::Path::new(&log_dir)
.join("SonicForgeDAW") .join("SonicForgeDAW")
@@ -37,12 +93,31 @@ pub fn run() {
if let Some(parent) = spawn_log_path.parent() { if let Some(parent) = spawn_log_path.parent() {
let _ = std::fs::create_dir_all(parent); let _ = std::fs::create_dir_all(parent);
} }
let log_line = format!(
"spawn daw_engine: {} exists={}\nresource_dir={}\n", let mut log_line = format!(
engine_exe.display(), "resource_dir={}\nexe_dir={}\n",
engine_exe.exists(), res_dir.display(),
res_dir.display() exe_dir.display()
); );
let mut found: Option<(PathBuf, String)> = None;
for (path, label) in &candidates {
let exists = path.exists();
log_line.push_str(&format!(
" [{label}] {} exists={}\n",
path.display(),
exists
));
if found.is_none() && exists {
found = Some((path.clone(), label.clone()));
}
}
if found.is_none() {
log_line.push_str(&format!(
" NOT FOUND — resource_dir contents: {}\n exe_dir contents: {}\n",
list_dir_snippet(&res_dir),
list_dir_snippet(&exe_dir)
));
}
if let Ok(mut f) = std::fs::OpenOptions::new() if let Ok(mut f) = std::fs::OpenOptions::new()
.create(true) .create(true)
.append(true) .append(true)
@@ -51,26 +126,40 @@ pub fn run() {
use std::io::Write; use std::io::Write;
let _ = f.write_all(log_line.as_bytes()); let _ = f.write_all(log_line.as_bytes());
} }
match app.shell().command(&engine_exe)
match found {
Some((engine_exe, label)) => {
match app
.shell()
.command(&engine_exe)
.env("SF_PARENT_PID", std::process::id().to_string()) .env("SF_PARENT_PID", std::process::id().to_string())
.spawn() { .spawn()
{
Ok((_rx, child)) => { Ok((_rx, child)) => {
app.manage(EngineProcess(Mutex::new(Some(child)))); app.manage(EngineProcess(Mutex::new(Some(child))));
println!("Python Background Engine started (localhost:8000, auto-fallback 8000-8010)"); println!(
"Python Background Engine started ({label}): {}",
engine_exe.display()
);
} }
Err(e) => { Err(e) => {
// Khong panic: UI van mo, engine loi se hien trong UI loader println!("Failed to spawn daw_engine {engine_exe:?}: {e}");
// ("Khong tim thay SonicForge Engine"). Log ro de chan doan. app.manage(EngineProcess(Mutex::new(None)));
println!("Failed to spawn daw_engine: {e}"); }
}
}
None => {
println!(
"daw_engine binary not found in any candidate path — xem spawn.log de biet chi tiet"
);
app.manage(EngineProcess(Mutex::new(None))); app.manage(EngineProcess(Mutex::new(None)));
} }
} }
Ok(()) Ok(())
}) })
.on_window_event(|window, event| { .on_window_event(|window, event| {
// 2. Terminate sidecar khi DAW window dong — tranh orphan process // Terminate sidecar khi DAW window dong — tranh orphan process
if let tauri::WindowEvent::Destroyed = event { if let tauri::WindowEvent::Destroyed = event {
// Lay child ra khoi lock, guard drop ngay tai day (trach E0597)
let child = window let child = window
.state::<EngineProcess>() .state::<EngineProcess>()
.0 .0
+3 -3
View File
@@ -32,9 +32,9 @@
"icons/128x128@2x.png", "icons/128x128@2x.png",
"icons/favicon.ico" "icons/favicon.ico"
], ],
"resources": [ "resources": {
"resources/daw_engine" "resources/daw_engine": "daw_engine/"
], },
"externalBin": [], "externalBin": [],
"windows": { "windows": {
"nsis": { "nsis": {