Auto updates: Fixed issue with MesenUpdater being started twice + Added Sha1 hash check

This commit is contained in:
Souryo 2016-02-10 18:58:13 -05:00
parent 1647f0c8c0
commit 2e7191d9c0
4 changed files with 76 additions and 46 deletions

View file

@ -1052,10 +1052,14 @@ namespace Mesen.GUI.Forms
Version currentVersion = new Version(InteropEmu.GetMesenVersion());
Version latestVersion = new Version(xmlDoc.SelectSingleNode("VersionInfo/LatestVersion").InnerText);
string changeLog = xmlDoc.SelectSingleNode("VersionInfo/ChangeLog").InnerText;
string fileHash = xmlDoc.SelectSingleNode("VersionInfo/Sha1Hash").InnerText;
if(latestVersion > currentVersion) {
this.BeginInvoke((MethodInvoker)(() => {
frmUpdatePrompt frmUpdate = new frmUpdatePrompt(currentVersion, latestVersion, changeLog);
frmUpdate.ShowDialog(null, this);
frmUpdatePrompt frmUpdate = new frmUpdatePrompt(currentVersion, latestVersion, changeLog, fileHash);
if(frmUpdate.ShowDialog(null, this) == DialogResult.OK) {
Application.Exit();
}
}));
} else if(displayResult) {
MessageBox.Show("You are running the latest version of Mesen.", "Mesen", MessageBoxButtons.OK, MessageBoxIcon.Information);

View file

@ -161,6 +161,7 @@
this.btnUpdate.TabIndex = 0;
this.btnUpdate.Text = "Update";
this.btnUpdate.UseVisualStyleBackColor = true;
this.btnUpdate.Click += new System.EventHandler(this.btnUpdate_Click);
//
// frmUpdatePrompt
//

View file

@ -6,6 +6,7 @@ using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
@ -15,10 +16,14 @@ namespace Mesen.GUI.Forms
{
public partial class frmUpdatePrompt : BaseForm
{
public frmUpdatePrompt(Version currentVersion, Version latestVersion, string changeLog)
private string _fileHash;
public frmUpdatePrompt(Version currentVersion, Version latestVersion, string changeLog, string fileHash)
{
InitializeComponent();
_fileHash = fileHash;
lblCurrentVersionString.Text = currentVersion.ToString();
lblLatestVersionString.Text = latestVersion.ToString();
txtChangelog.Text = changeLog.Replace("\n", Environment.NewLine);
@ -30,24 +35,40 @@ namespace Mesen.GUI.Forms
btnUpdate.Focus();
}
protected override void OnFormClosed(FormClosedEventArgs e)
private void btnUpdate_Click(object sender, EventArgs e)
{
base.OnFormClosed(e);
if(DialogResult == DialogResult.OK) {
string destFilePath = Process.GetCurrentProcess().MainModule.FileName;
string srcFilePath = Path.Combine(ConfigManager.DownloadFolder, "Mesen." + lblLatestVersionString.Text + ".exe");
string backupFilePath = Path.Combine(ConfigManager.BackupFolder, "Mesen." + lblCurrentVersionString.Text + ".exe");
string updateHelper = Path.Combine(ConfigManager.HomeFolder, "MesenUpdater.exe");
string destFilePath = Process.GetCurrentProcess().MainModule.FileName;
string srcFilePath = Path.Combine(ConfigManager.DownloadFolder, "Mesen." + lblLatestVersionString.Text + ".exe");
string backupFilePath = Path.Combine(ConfigManager.BackupFolder, "Mesen." + lblCurrentVersionString.Text + ".exe");
string updateHelper = Path.Combine(ConfigManager.HomeFolder, "MesenUpdater.exe");
if(!string.IsNullOrWhiteSpace(srcFilePath)) {
frmDownloadProgress frmDownload = new frmDownloadProgress("http://www.mesen.ca/Services/GetLatestVersion.php?a=download&&p=win", srcFilePath);
if(frmDownload.ShowDialog() == DialogResult.OK) {
if(!string.IsNullOrWhiteSpace(srcFilePath)) {
frmDownloadProgress frmDownload = new frmDownloadProgress("http://www.mesen.ca/Services/GetLatestVersion.php?a=download&&p=win", srcFilePath);
if(frmDownload.ShowDialog() == DialogResult.OK) {
FileInfo fileInfo = new FileInfo(srcFilePath);
if(fileInfo.Length > 0 && GetSha1Hash(srcFilePath) == _fileHash) {
Process.Start(updateHelper, string.Format("\"{0}\" \"{1}\" \"{2}\"", srcFilePath, destFilePath, backupFilePath));
Application.Exit();
} else {
//Download failed, mismatching hashes
MessageBox.Show("Download failed - the file appears to be corrupted. Please visit the Mesen website to download the latest version manually.", "Mesen", MessageBoxButtons.OK, MessageBoxIcon.Error);
DialogResult = DialogResult.Cancel;
}
}
}
}
private string GetSha1Hash(string filename)
{
using(SHA1Managed sha1 = new SHA1Managed()) {
byte[] hash = sha1.ComputeHash(File.ReadAllBytes(filename));
var sb = new StringBuilder(hash.Length * 2);
foreach(byte b in hash) {
sb.Append(b.ToString("x2"));
}
return sb.ToString();
}
}
}
}

View file

@ -13,46 +13,50 @@ namespace MesenUpdater
{
static void Main(string[] args)
{
string srcFile = args[0];
string destFile = args[1];
string backupDestFile = args[2];
bool isAdmin = args.Length > 3 && args[3] == "admin";
if(args.Length > 2) {
string srcFile = args[0];
string destFile = args[1];
string backupDestFile = args[2];
bool isAdmin = args.Length > 3 && args[3] == "admin";
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(1000);
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(1000);
}
}
}
try {
File.Copy(destFile, backupDestFile, true);
File.Copy(srcFile, destFile, true);
} catch {
try {
if(!isAdmin) {
ProcessStartInfo proc = new ProcessStartInfo();
proc.WindowStyle = ProcessWindowStyle.Normal;
proc.FileName = Process.GetCurrentProcess().MainModule.FileName;
proc.Arguments = string.Format("\"{0}\" \"{1}\" \"{2}\" admin", srcFile, destFile, backupDestFile);
proc.UseShellExecute = true;
proc.Verb = "runas";
Process.Start(proc);
return;
} else {
File.Copy(destFile, backupDestFile, true);
File.Copy(srcFile, destFile, true);
} catch {
try {
if(!isAdmin) {
ProcessStartInfo proc = new ProcessStartInfo();
proc.WindowStyle = ProcessWindowStyle.Normal;
proc.FileName = Process.GetCurrentProcess().MainModule.FileName;
proc.Arguments = string.Format("\"{0}\" \"{1}\" \"{2}\" admin", srcFile, destFile, backupDestFile);
proc.UseShellExecute = true;
proc.Verb = "runas";
Process.Start(proc);
return;
} else {
MessageBox.Show("Update failed. Please try downloading and installing the new version manually.", "Mesen", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
} catch {
MessageBox.Show("Update failed. Please try downloading and installing the new version manually.", "Mesen", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
} catch {
MessageBox.Show("Update failed. Please try downloading and installing the new version manually.", "Mesen", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
Process.Start(destFile);
} else {
MessageBox.Show("Please run Mesen directly to update.", "Mesen");
}
Process.Start(destFile);
}
}
}