fix: harden silent updater flow and release 0.1.24
This commit is contained in:
@@ -112,7 +112,7 @@ const DOWNLOAD_SIGNED_URL_EXPIRES_SECONDS = Math.max(
|
|||||||
10,
|
10,
|
||||||
Math.min(3600, Number(process.env.DOWNLOAD_SIGNED_URL_EXPIRES_SECONDS || 30))
|
Math.min(3600, Number(process.env.DOWNLOAD_SIGNED_URL_EXPIRES_SECONDS || 30))
|
||||||
);
|
);
|
||||||
const DEFAULT_DESKTOP_VERSION = process.env.DESKTOP_LATEST_VERSION || '0.1.23';
|
const DEFAULT_DESKTOP_VERSION = process.env.DESKTOP_LATEST_VERSION || '0.1.24';
|
||||||
const DEFAULT_DESKTOP_INSTALLER_URL = process.env.DESKTOP_INSTALLER_URL || '';
|
const DEFAULT_DESKTOP_INSTALLER_URL = process.env.DESKTOP_INSTALLER_URL || '';
|
||||||
const DEFAULT_DESKTOP_RELEASE_NOTES = process.env.DESKTOP_RELEASE_NOTES || '';
|
const DEFAULT_DESKTOP_RELEASE_NOTES = process.env.DESKTOP_RELEASE_NOTES || '';
|
||||||
const DESKTOP_INSTALLERS_DIR = path.resolve(__dirname, '../frontend/downloads');
|
const DESKTOP_INSTALLERS_DIR = path.resolve(__dirname, '../frontend/downloads');
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "desktop-client",
|
"name": "desktop-client",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.1.23",
|
"version": "0.1.24",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|||||||
2
desktop-client/src-tauri/Cargo.lock
generated
2
desktop-client/src-tauri/Cargo.lock
generated
@@ -693,7 +693,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "desktop-client"
|
name = "desktop-client"
|
||||||
version = "0.1.23"
|
version = "0.1.24"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"reqwest 0.12.28",
|
"reqwest 0.12.28",
|
||||||
"rusqlite",
|
"rusqlite",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "desktop-client"
|
name = "desktop-client"
|
||||||
version = "0.1.23"
|
version = "0.1.24"
|
||||||
description = "A Tauri App"
|
description = "A Tauri App"
|
||||||
authors = ["you"]
|
authors = ["you"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|||||||
@@ -1171,38 +1171,72 @@ fn api_silent_install_and_restart(installer_path: String) -> Result<BridgeRespon
|
|||||||
.map(|duration| duration.as_millis())
|
.map(|duration| duration.as_millis())
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
let script_path = temp_dir.join(format!("silent-update-{}.cmd", script_stamp));
|
let script_path = temp_dir.join(format!("silent-update-{}.cmd", script_stamp));
|
||||||
|
let log_path = temp_dir.join(format!("silent-update-{}.log", script_stamp));
|
||||||
|
|
||||||
let installer_text = installer.to_string_lossy().replace('"', "\"\"");
|
let installer_text = installer.to_string_lossy().replace('"', "\"\"");
|
||||||
let app_text = current_exe.to_string_lossy().replace('"', "\"\"");
|
let app_text = current_exe.to_string_lossy().replace('"', "\"\"");
|
||||||
|
let log_text = log_path.to_string_lossy().replace('"', "\"\"");
|
||||||
let script_content = format!(
|
let script_content = format!(
|
||||||
"@echo off\r\n\
|
"@echo off\r\n\
|
||||||
setlocal enableextensions\r\n\
|
setlocal enableextensions\r\n\
|
||||||
set \"INSTALLER={installer}\"\r\n\
|
set \"INSTALLER={installer}\"\r\n\
|
||||||
set \"APP_EXE={app_exe}\"\r\n\
|
set \"APP_EXE={app_exe}\"\r\n\
|
||||||
set \"APP_PID={app_pid}\"\r\n\
|
set \"APP_PID={app_pid}\"\r\n\
|
||||||
|
set \"LOG_FILE={log_file}\"\r\n\
|
||||||
|
echo [%%date%% %%time%%] update script started > \"%LOG_FILE%\"\r\n\
|
||||||
if not exist \"%INSTALLER%\" exit /b 1\r\n\
|
if not exist \"%INSTALLER%\" exit /b 1\r\n\
|
||||||
timeout /t 1 /nobreak >nul\r\n\
|
timeout /t 1 /nobreak >nul\r\n\
|
||||||
taskkill /PID %APP_PID% /T /F >nul 2>nul\r\n\
|
taskkill /PID %APP_PID% /F >nul 2>nul\r\n\
|
||||||
timeout /t 1 /nobreak >nul\r\n\
|
timeout /t 1 /nobreak >nul\r\n\
|
||||||
start \"\" /wait \"%INSTALLER%\" /S\r\n\
|
start \"\" /wait \"%INSTALLER%\" /S\r\n\
|
||||||
|
set \"INSTALL_EXIT=%ERRORLEVEL%\"\r\n\
|
||||||
|
echo [%%date%% %%time%%] installer exit code: %INSTALL_EXIT% >> \"%LOG_FILE%\"\r\n\
|
||||||
|
if not \"%INSTALL_EXIT%\"==\"0\" exit /b %INSTALL_EXIT%\r\n\
|
||||||
timeout /t 1 /nobreak >nul\r\n\
|
timeout /t 1 /nobreak >nul\r\n\
|
||||||
if exist \"%APP_EXE%\" start \"\" \"%APP_EXE%\"\r\n\
|
if exist \"%APP_EXE%\" start \"\" \"%APP_EXE%\"\r\n\
|
||||||
del \"%~f0\" >nul 2>nul\r\n",
|
del \"%~f0\" >nul 2>nul\r\n",
|
||||||
installer = installer_text,
|
installer = installer_text,
|
||||||
app_exe = app_text,
|
app_exe = app_text,
|
||||||
app_pid = current_pid
|
app_pid = current_pid,
|
||||||
|
log_file = log_text
|
||||||
);
|
);
|
||||||
fs::write(&script_path, script_content).map_err(|err| format!("写入更新脚本失败: {}", err))?;
|
fs::write(&script_path, script_content).map_err(|err| format!("写入更新脚本失败: {}", err))?;
|
||||||
|
let script_arg = format!("\"{}\"", script_path.to_string_lossy());
|
||||||
|
|
||||||
let mut updater_cmd = Command::new("cmd");
|
let mut updater_cmd = Command::new("cmd");
|
||||||
updater_cmd
|
updater_cmd
|
||||||
.arg("/D")
|
.arg("/D")
|
||||||
.arg("/C")
|
.arg("/C")
|
||||||
.arg(&script_path)
|
.arg(&script_arg)
|
||||||
.current_dir(&temp_dir)
|
.current_dir(&temp_dir)
|
||||||
.creation_flags(CREATE_NO_WINDOW)
|
.creation_flags(CREATE_NO_WINDOW)
|
||||||
.spawn()
|
.spawn()
|
||||||
.map_err(|err| format!("启动静默更新流程失败: {}", err))?;
|
.map_err(|err| format!("启动静默更新流程失败: {}", err))?;
|
||||||
|
|
||||||
|
let mut cleanup_entries: Vec<PathBuf> = fs::read_dir(&temp_dir)
|
||||||
|
.ok()
|
||||||
|
.into_iter()
|
||||||
|
.flat_map(|entries| entries.filter_map(Result::ok))
|
||||||
|
.map(|entry| entry.path())
|
||||||
|
.filter(|path| {
|
||||||
|
path.file_name()
|
||||||
|
.and_then(|name| name.to_str())
|
||||||
|
.map(|name| name.starts_with("silent-update-"))
|
||||||
|
.unwrap_or(false)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
cleanup_entries.sort_by_key(|path| {
|
||||||
|
fs::metadata(path)
|
||||||
|
.ok()
|
||||||
|
.and_then(|meta| meta.modified().ok())
|
||||||
|
.unwrap_or(SystemTime::UNIX_EPOCH)
|
||||||
|
});
|
||||||
|
if cleanup_entries.len() > 24 {
|
||||||
|
let remove_count = cleanup_entries.len().saturating_sub(24);
|
||||||
|
for stale_path in cleanup_entries.into_iter().take(remove_count) {
|
||||||
|
let _ = fs::remove_file(stale_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
@@ -1221,6 +1255,18 @@ del \"%~f0\" >nul 2>nul\r\n",
|
|||||||
Value::String("静默安装流程已启动,安装完成后将自动重启".to_string()),
|
Value::String("静默安装流程已启动,安装完成后将自动重启".to_string()),
|
||||||
);
|
);
|
||||||
data.insert("installerPath".to_string(), Value::String(path_text));
|
data.insert("installerPath".to_string(), Value::String(path_text));
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
{
|
||||||
|
data.insert(
|
||||||
|
"logPath".to_string(),
|
||||||
|
Value::String(
|
||||||
|
env::temp_dir()
|
||||||
|
.join("wanwan-cloud-desktop")
|
||||||
|
.to_string_lossy()
|
||||||
|
.to_string(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(BridgeResponse {
|
Ok(BridgeResponse {
|
||||||
ok: true,
|
ok: true,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://schema.tauri.app/config/2",
|
"$schema": "https://schema.tauri.app/config/2",
|
||||||
"productName": "玩玩云",
|
"productName": "玩玩云",
|
||||||
"version": "0.1.23",
|
"version": "0.1.24",
|
||||||
"identifier": "cn.workyai.wanwancloud.desktop",
|
"identifier": "cn.workyai.wanwancloud.desktop",
|
||||||
"build": {
|
"build": {
|
||||||
"beforeDevCommand": "npm run dev",
|
"beforeDevCommand": "npm run dev",
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ const syncState = reactive({
|
|||||||
nextRunAt: "",
|
nextRunAt: "",
|
||||||
});
|
});
|
||||||
const updateState = reactive({
|
const updateState = reactive({
|
||||||
currentVersion: "0.1.23",
|
currentVersion: "0.1.24",
|
||||||
latestVersion: "",
|
latestVersion: "",
|
||||||
available: false,
|
available: false,
|
||||||
mandatory: false,
|
mandatory: false,
|
||||||
@@ -1010,7 +1010,18 @@ async function installLatestUpdate(): Promise<boolean> {
|
|||||||
if (launchResponse.ok && launchResponse.data?.success) {
|
if (launchResponse.ok && launchResponse.data?.success) {
|
||||||
showToast("静默安装已启动,完成后会自动重启客户端", "success");
|
showToast("静默安装已启动,完成后会自动重启客户端", "success");
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
void getCurrentWindow().close();
|
const win = getCurrentWindow();
|
||||||
|
void (async () => {
|
||||||
|
try {
|
||||||
|
await win.close();
|
||||||
|
} catch {
|
||||||
|
try {
|
||||||
|
await win.destroy();
|
||||||
|
} catch {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
||||||
}, 400);
|
}, 400);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user