Mesen2/UI/Utilities/UpdateHelper.cs

99 lines
2.7 KiB
C#

using Avalonia.Threading;
using Mesen.Config;
using Mesen.Interop;
using Mesen.Windows;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Mesen.Utilities
{
public static class UpdateHelper
{
public static bool LaunchUpdate(string srcFile)
{
string destFile = Program.ExePath;
Version installedVersion = EmuApi.GetMesenVersion();
string backupFilePath = Path.Combine(ConfigManager.BackupFolder, "Mesen." + installedVersion.ToString(3));
if(OperatingSystem.IsWindows()) {
backupFilePath += ".exe";
}
try {
//Use the downloaded .exe as an updater
if(File.Exists(srcFile) && new FileInfo(srcFile).Length > 0) {
Process.Start(srcFile, string.Format("--update \"{0}\" \"{1}\" \"{2}\"", srcFile, destFile, backupFilePath));
return true;
} else {
//Download failed, mismatching hashes
Dispatcher.UIThread.Post(() => {
MesenMsgBox.Show(null, "UpdateDownloadFailed", MessageBoxButtons.OK, MessageBoxIcon.Error);
});
}
} catch(Exception ex) {
Dispatcher.UIThread.Post(() => {
MesenMsgBox.ShowException(ex);
});
}
return false;
}
public static void AttemptUpdate(string srcFile, string destFile, string backupFile, bool isAdmin)
{
//Wait a bit for the application to shut down before trying to kill it
System.Threading.Thread.Sleep(1000);
try {
Process currentProcess = Process.GetCurrentProcess();
foreach(Process process in Process.GetProcesses()) {
if(currentProcess != process) {
try {
if(process.MainModule?.FileName == destFile) {
process.Kill();
}
} catch { }
}
}
} catch { }
int retryCount = 0;
while(retryCount < 10) {
try {
using(FileStream file = File.Open(destFile, FileMode.Open, FileAccess.ReadWrite, FileShare.Delete | FileShare.ReadWrite)) { }
break;
} catch {
retryCount++;
System.Threading.Thread.Sleep(200);
}
}
try {
//Backup current version
File.Copy(destFile, backupFile, true);
//Update with downloaded version
File.Copy(srcFile, destFile, true);
//Start new version
Process.Start(destFile);
} catch {
try {
//Something failed, try again with admin rights (if we aren't already running as an admin)
if(!isAdmin) {
ProcessStartInfo proc = new ProcessStartInfo();
proc.WindowStyle = ProcessWindowStyle.Normal;
proc.FileName = Program.ExePath;
proc.Arguments = string.Format("--update \"{0}\" \"{1}\" \"{2}\" admin", srcFile, destFile, backupFile);
proc.UseShellExecute = true;
proc.Verb = "runas";
Process.Start(proc);
}
} catch {
}
}
}
}
}