mirror of
https://gitlab.com/vyla-entertainment/home.git
synced 2026-11-09 19:57:20 -05:00
maybe created auto updater?
This commit is contained in:
4
main.js
4
main.js
@@ -276,14 +276,14 @@ async function start() {
|
|||||||
if (release && release.installer && process.platform === 'win32' && process.env.VYLA_DEV !== '1') {
|
if (release && release.installer && process.platform === 'win32' && process.env.VYLA_DEV !== '1') {
|
||||||
const appVersion = process.env.VYLA_APP_VERSION || '0.0.0';
|
const appVersion = process.env.VYLA_APP_VERSION || '0.0.0';
|
||||||
const tried = updateClient.readCache().selfUpdate || {};
|
const tried = updateClient.readCache().selfUpdate || {};
|
||||||
const recentlyTried = tried.version === release.installer.version && Date.now() - (tried.at || 0) < 24 * 60 * 60 * 1000;
|
const recentlyTried = tried.version === release.installer.version && Date.now() - (tried.at || 0) < 10 * 60 * 1000;
|
||||||
if (isNewer(release.installer.version, appVersion) && !recentlyTried) {
|
if (isNewer(release.installer.version, appVersion) && !recentlyTried) {
|
||||||
try {
|
try {
|
||||||
const dest = path.join(APPDATA_DIR, `vyla-installer-${normalizeVer(release.installer.version)}.exe`);
|
const dest = path.join(APPDATA_DIR, `vyla-installer-${normalizeVer(release.installer.version)}.exe`);
|
||||||
sendToTauri('status', { message: 'Downloading launcher update...' });
|
sendToTauri('status', { message: 'Downloading launcher update...' });
|
||||||
await downloadVerified('launcher', release.installer, dest);
|
await downloadVerified('launcher', release.installer, dest);
|
||||||
updateClient.writeCache({ selfUpdate: { version: release.installer.version, at: Date.now() } });
|
updateClient.writeCache({ selfUpdate: { version: release.installer.version, at: Date.now() } });
|
||||||
sendToTauri('status', { message: 'Installing launcher update...' });
|
sendToTauri('status', { message: 'Removing old version and installing the latest...' });
|
||||||
sendToTauri('self-update', { path: dest });
|
sendToTauri('self-update', { path: dest });
|
||||||
await sleep(30000);
|
await sleep(30000);
|
||||||
sendToTauri('notice', { message: 'Launcher update did not start. Continuing on the current version.' });
|
sendToTauri('notice', { message: 'Launcher update did not start. Continuing on the current version.' });
|
||||||
|
|||||||
@@ -564,6 +564,87 @@ const LINK_HANDLER_SCRIPT: &str = r##"
|
|||||||
})();
|
})();
|
||||||
"##;
|
"##;
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
const REINSTALL_SCRIPT: &str = r##"
|
||||||
|
param([int]$ProcId,[string]$Installer,[string]$InstallDir,[string]$ExePath)
|
||||||
|
$ErrorActionPreference = 'SilentlyContinue'
|
||||||
|
function Log($m) { Add-Content -LiteralPath (Join-Path $env:TEMP 'vyla-reinstall.log') -Value "$(Get-Date -Format s) $m" }
|
||||||
|
Log "start pid=$ProcId installer=$Installer dir=$InstallDir exe=$ExePath"
|
||||||
|
$setup = Join-Path $env:TEMP 'vyla-setup.exe'
|
||||||
|
Copy-Item -LiteralPath $Installer -Destination $setup -Force
|
||||||
|
if (-not (Test-Path -LiteralPath $setup)) { exit 1 }
|
||||||
|
Wait-Process -Id $ProcId -Timeout 30
|
||||||
|
Get-Process | Where-Object { $_.Path -and $_.Path.StartsWith($InstallDir, [System.StringComparison]::OrdinalIgnoreCase) } | Stop-Process -Force
|
||||||
|
Start-Sleep -Seconds 2
|
||||||
|
$un = Join-Path $InstallDir 'uninstall.exe'
|
||||||
|
if (Test-Path -LiteralPath $un) {
|
||||||
|
Start-Process -FilePath $un -ArgumentList '/S', "_?=$InstallDir" -Wait
|
||||||
|
}
|
||||||
|
$targets = @($InstallDir, "$env:APPDATA\vyla-home", "$env:APPDATA\com.vyla.home", "$env:LOCALAPPDATA\com.vyla.home", "$env:LOCALAPPDATA\vyla-home")
|
||||||
|
foreach ($t in $targets) {
|
||||||
|
for ($i = 0; $i -lt 5; $i++) {
|
||||||
|
if (-not (Test-Path -LiteralPath $t)) { break }
|
||||||
|
Remove-Item -LiteralPath $t -Recurse -Force
|
||||||
|
if (Test-Path -LiteralPath $t) { Start-Sleep -Seconds 1 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Log "uninstall and cleanup done, installing"
|
||||||
|
Start-Process -FilePath $setup -ArgumentList '/S', "/D=$InstallDir" -Wait
|
||||||
|
Log "installer finished"
|
||||||
|
Remove-Item -LiteralPath $setup -Force
|
||||||
|
$target = $null
|
||||||
|
for ($i = 0; $i -lt 40; $i++) {
|
||||||
|
if (Test-Path -LiteralPath $ExePath) { $target = $ExePath; break }
|
||||||
|
$found = Get-ChildItem -LiteralPath $InstallDir -Filter '*.exe' | Where-Object { $_.Name -notmatch 'uninstall|node' } | Select-Object -First 1
|
||||||
|
if ($found) { $target = $found.FullName; break }
|
||||||
|
Start-Sleep -Milliseconds 500
|
||||||
|
}
|
||||||
|
Log "launch target: $target"
|
||||||
|
if ($target) {
|
||||||
|
Start-Process -FilePath $target -WorkingDirectory (Split-Path -Parent $target)
|
||||||
|
Start-Sleep -Seconds 4
|
||||||
|
if (-not (Get-Process | Where-Object { $_.Path -eq $target })) {
|
||||||
|
Log "not running, retrying via explorer"
|
||||||
|
Start-Process -FilePath 'explorer.exe' -ArgumentList "`"$target`""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Log "done"
|
||||||
|
"##;
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
fn run_clean_reinstall(installer: &std::path::Path) -> bool {
|
||||||
|
use std::os::windows::process::CommandExt;
|
||||||
|
let exe = match std::env::current_exe() {
|
||||||
|
Ok(e) => e,
|
||||||
|
Err(_) => return false,
|
||||||
|
};
|
||||||
|
let dir = match exe.parent() {
|
||||||
|
Some(d) => d.to_path_buf(),
|
||||||
|
None => return false,
|
||||||
|
};
|
||||||
|
if !dir.join("uninstall.exe").exists() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
let script = std::env::temp_dir().join("vyla-reinstall.ps1");
|
||||||
|
if std::fs::write(&script, REINSTALL_SCRIPT).is_err() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Command::new("powershell")
|
||||||
|
.args(["-NoProfile", "-ExecutionPolicy", "Bypass", "-WindowStyle", "Hidden", "-File"])
|
||||||
|
.arg(&script)
|
||||||
|
.arg("-ProcId")
|
||||||
|
.arg(std::process::id().to_string())
|
||||||
|
.arg("-Installer")
|
||||||
|
.arg(installer)
|
||||||
|
.arg("-InstallDir")
|
||||||
|
.arg(clean_path(&dir))
|
||||||
|
.arg("-ExePath")
|
||||||
|
.arg(clean_path(&exe))
|
||||||
|
.creation_flags(0x08000000 | 0x00000200)
|
||||||
|
.spawn()
|
||||||
|
.is_ok()
|
||||||
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
fn win_minimize(window: tauri::Window) -> Result<(), String> {
|
fn win_minimize(window: tauri::Window) -> Result<(), String> {
|
||||||
window.minimize().map_err(|e| e.to_string())
|
window.minimize().map_err(|e| e.to_string())
|
||||||
@@ -949,21 +1030,18 @@ fn main() {
|
|||||||
&& name.ends_with(".exe")
|
&& name.ends_with(".exe")
|
||||||
&& p.exists()
|
&& p.exists()
|
||||||
{
|
{
|
||||||
let state: State<NodeServices> = w.state();
|
|
||||||
if let Ok(mut lock) = state.0.lock() {
|
|
||||||
if let Some(mut child) = lock.take() {
|
|
||||||
kill_child_process(&mut child);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let mut installer = Command::new(&p);
|
|
||||||
installer.args(["/S", "/UPDATE"]);
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
{
|
{
|
||||||
use std::os::windows::process::CommandExt;
|
if run_clean_reinstall(&p) {
|
||||||
installer.creation_flags(0x00000008 | 0x00000200);
|
let state: State<NodeServices> = w.state();
|
||||||
|
if let Ok(mut lock) = state.0.lock() {
|
||||||
|
if let Some(mut child) = lock.take() {
|
||||||
|
kill_child_process(&mut child);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
w.app_handle().exit(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
let _ = installer.spawn();
|
|
||||||
w.app_handle().exit(0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -358,7 +358,8 @@ class UpdateClient {
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
const release = releases.slice().sort((a, b) => cmp(b.tag_name, a.tag_name))[0];
|
const ordered = releases.slice().sort((a, b) => cmp(b.tag_name, a.tag_name));
|
||||||
|
const release = ordered[0];
|
||||||
const links = release.assets && release.assets.links ? release.assets.links : [];
|
const links = release.assets && release.assets.links ? release.assets.links : [];
|
||||||
const manifestAsset = links.find((a) => a.name === 'manifest.json');
|
const manifestAsset = links.find((a) => a.name === 'manifest.json');
|
||||||
|
|
||||||
@@ -403,6 +404,10 @@ class UpdateClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!installer) {
|
||||||
|
installer = await this.findInstaller(ordered, release.tag_name);
|
||||||
|
}
|
||||||
|
|
||||||
const out = {
|
const out = {
|
||||||
version: release.tag_name,
|
version: release.tag_name,
|
||||||
sha256: manifest.sha256 || null,
|
sha256: manifest.sha256 || null,
|
||||||
@@ -414,6 +419,28 @@ class UpdateClient {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async findInstaller(ordered, skipTag) {
|
||||||
|
for (const r of ordered.slice(0, 6)) {
|
||||||
|
if (r.tag_name === skipTag) continue;
|
||||||
|
const rl = r.assets && r.assets.links ? r.assets.links : [];
|
||||||
|
const ma = rl.find((a) => a.name === 'manifest.json');
|
||||||
|
if (!ma) continue;
|
||||||
|
try {
|
||||||
|
const m = await this.fetchAssetJson(ma.url);
|
||||||
|
if (!m.installer || !verifyManifest(m)) continue;
|
||||||
|
const link = rl.find((a) => a.name === m.installer.file);
|
||||||
|
if (!link) continue;
|
||||||
|
return {
|
||||||
|
url: link.url,
|
||||||
|
sha256: m.installer.sha256,
|
||||||
|
size: m.installer.size,
|
||||||
|
version: m.installer.version
|
||||||
|
};
|
||||||
|
} catch (e) { }
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
async downloadUpdate(release, destPath, onProgress) {
|
async downloadUpdate(release, destPath, onProgress) {
|
||||||
await this.downloadFile(release.url, destPath, onProgress);
|
await this.downloadFile(release.url, destPath, onProgress);
|
||||||
return destPath;
|
return destPath;
|
||||||
|
|||||||
Reference in New Issue
Block a user