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 currentVersion = new Version(InteropEmu.GetMesenVersion());
Version latestVersion = new Version(xmlDoc.SelectSingleNode("VersionInfo/LatestVersion").InnerText); Version latestVersion = new Version(xmlDoc.SelectSingleNode("VersionInfo/LatestVersion").InnerText);
string changeLog = xmlDoc.SelectSingleNode("VersionInfo/ChangeLog").InnerText; string changeLog = xmlDoc.SelectSingleNode("VersionInfo/ChangeLog").InnerText;
string fileHash = xmlDoc.SelectSingleNode("VersionInfo/Sha1Hash").InnerText;
if(latestVersion > currentVersion) { if(latestVersion > currentVersion) {
this.BeginInvoke((MethodInvoker)(() => { this.BeginInvoke((MethodInvoker)(() => {
frmUpdatePrompt frmUpdate = new frmUpdatePrompt(currentVersion, latestVersion, changeLog); frmUpdatePrompt frmUpdate = new frmUpdatePrompt(currentVersion, latestVersion, changeLog, fileHash);
frmUpdate.ShowDialog(null, this); if(frmUpdate.ShowDialog(null, this) == DialogResult.OK) {
Application.Exit();
}
})); }));
} else if(displayResult) { } else if(displayResult) {
MessageBox.Show("You are running the latest version of Mesen.", "Mesen", MessageBoxButtons.OK, MessageBoxIcon.Information); 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.TabIndex = 0;
this.btnUpdate.Text = "Update"; this.btnUpdate.Text = "Update";
this.btnUpdate.UseVisualStyleBackColor = true; this.btnUpdate.UseVisualStyleBackColor = true;
this.btnUpdate.Click += new System.EventHandler(this.btnUpdate_Click);
// //
// frmUpdatePrompt // frmUpdatePrompt
// //

View file

@ -6,6 +6,7 @@ using System.Diagnostics;
using System.Drawing; using System.Drawing;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Security.Cryptography;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
@ -15,10 +16,14 @@ namespace Mesen.GUI.Forms
{ {
public partial class frmUpdatePrompt : BaseForm 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(); InitializeComponent();
_fileHash = fileHash;
lblCurrentVersionString.Text = currentVersion.ToString(); lblCurrentVersionString.Text = currentVersion.ToString();
lblLatestVersionString.Text = latestVersion.ToString(); lblLatestVersionString.Text = latestVersion.ToString();
txtChangelog.Text = changeLog.Replace("\n", Environment.NewLine); txtChangelog.Text = changeLog.Replace("\n", Environment.NewLine);
@ -30,24 +35,40 @@ namespace Mesen.GUI.Forms
btnUpdate.Focus(); btnUpdate.Focus();
} }
protected override void OnFormClosed(FormClosedEventArgs e) private void btnUpdate_Click(object sender, EventArgs e)
{ {
base.OnFormClosed(e); string destFilePath = Process.GetCurrentProcess().MainModule.FileName;
if(DialogResult == DialogResult.OK) { string srcFilePath = Path.Combine(ConfigManager.DownloadFolder, "Mesen." + lblLatestVersionString.Text + ".exe");
string destFilePath = Process.GetCurrentProcess().MainModule.FileName; string backupFilePath = Path.Combine(ConfigManager.BackupFolder, "Mesen." + lblCurrentVersionString.Text + ".exe");
string srcFilePath = Path.Combine(ConfigManager.DownloadFolder, "Mesen." + lblLatestVersionString.Text + ".exe"); string updateHelper = Path.Combine(ConfigManager.HomeFolder, "MesenUpdater.exe");
string backupFilePath = Path.Combine(ConfigManager.BackupFolder, "Mesen." + lblCurrentVersionString.Text + ".exe");
string updateHelper = Path.Combine(ConfigManager.HomeFolder, "MesenUpdater.exe");
if(!string.IsNullOrWhiteSpace(srcFilePath)) { if(!string.IsNullOrWhiteSpace(srcFilePath)) {
frmDownloadProgress frmDownload = new frmDownloadProgress("http://www.mesen.ca/Services/GetLatestVersion.php?a=download&&p=win", srcFilePath); frmDownloadProgress frmDownload = new frmDownloadProgress("http://www.mesen.ca/Services/GetLatestVersion.php?a=download&&p=win", srcFilePath);
if(frmDownload.ShowDialog() == DialogResult.OK) { 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)); 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) static void Main(string[] args)
{ {
string srcFile = args[0]; if(args.Length > 2) {
string destFile = args[1]; string srcFile = args[0];
string backupDestFile = args[2]; string destFile = args[1];
bool isAdmin = args.Length > 3 && args[3] == "admin"; string backupDestFile = args[2];
bool isAdmin = args.Length > 3 && args[3] == "admin";
int retryCount = 0; int retryCount = 0;
while(retryCount < 10) { while(retryCount < 10) {
try { try {
using(FileStream file = File.Open(destFile, FileMode.Open, FileAccess.ReadWrite, FileShare.Delete | FileShare.ReadWrite)) { } using(FileStream file = File.Open(destFile, FileMode.Open, FileAccess.ReadWrite, FileShare.Delete | FileShare.ReadWrite)) { }
break; break;
} catch { } catch {
retryCount++; retryCount++;
System.Threading.Thread.Sleep(1000); System.Threading.Thread.Sleep(1000);
}
} }
}
try {
File.Copy(destFile, backupDestFile, true);
File.Copy(srcFile, destFile, true);
} catch {
try { try {
if(!isAdmin) { File.Copy(destFile, backupDestFile, true);
ProcessStartInfo proc = new ProcessStartInfo(); File.Copy(srcFile, destFile, true);
proc.WindowStyle = ProcessWindowStyle.Normal; } catch {
proc.FileName = Process.GetCurrentProcess().MainModule.FileName; try {
proc.Arguments = string.Format("\"{0}\" \"{1}\" \"{2}\" admin", srcFile, destFile, backupDestFile); if(!isAdmin) {
proc.UseShellExecute = true; ProcessStartInfo proc = new ProcessStartInfo();
proc.Verb = "runas"; proc.WindowStyle = ProcessWindowStyle.Normal;
Process.Start(proc); proc.FileName = Process.GetCurrentProcess().MainModule.FileName;
return; proc.Arguments = string.Format("\"{0}\" \"{1}\" \"{2}\" admin", srcFile, destFile, backupDestFile);
} else { 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); MessageBox.Show("Update failed. Please try downloading and installing the new version manually.", "Mesen", MessageBoxButtons.OK, MessageBoxIcon.Error);
return; 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);
} }
} }
} }