SafeDispatch/SharedUI/Update/UpdateForm.cs

392 lines
15 KiB
C#

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Net;
using System.Threading;
using System.Diagnostics;
using SafeMobileLib;
using System.IO;
namespace SharedUI
{
public partial class UpdateForm : Form
{
private AutoUpdate updater;
private enum CurrentStatus { CHECKING, AVAILABLE, DOWNLOADING, READY_TO_INSTALL, LATEST, FAILED }
private CurrentStatus currentState = CurrentStatus.CHECKING;
private App app;
private Boolean isDevelop;
public bool IsDevelop
{
get { return isDevelop; }
set { isDevelop = value; }
}
[DllImportAttribute("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
[DllImportAttribute("user32.dll")]
public static extern bool ReleaseCapture();
public const int WM_NCLBUTTONDOWN = 0xA1;
public const int HT_CAPTION = 0x2;
private bool shouldCheck = false;
public UpdateForm(App application, bool shouldCheck)
{
InitializeComponent();
/*
Type type = typeof(PictureBox);
if(type.Namespace.Equals("MotoRepeater"))
pictureBox2.Image = global::MotoRepeater.Properties.Resources.software;
else if (type.Namespace.Equals("AppServer"))
pictureBox2.Image = global::AppServer.Properties.Resources.software;
else if (type.Namespace.Equals("MotoTrbo_GW"))
pictureBox2.Image = global::MotoTrbo_GW.Properties.Resources.software;
*/
var directory = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
string path = directory + "\\";
if (Directory.Exists(path + "images"))
{
(new DirectoryInfo(path + "images")).Attributes = FileAttributes.Directory | FileAttributes.Hidden;
pictureBox2.Image = System.Drawing.Image.FromFile(path + "images\\software.png");
pictureBoxClose.Image = System.Drawing.Image.FromFile(path + "images\\close.png");
}
this.app = application;
this.shouldCheck = shouldCheck;
}
private void pictureBoxClose_Click(object sender, EventArgs e)
{
if (currentState == CurrentStatus.DOWNLOADING)
updater?.CancelUpdate();
this.Close();
}
private void UpdateUIForStatus(CurrentStatus status)
{
currentState = status;
switch (status)
{
case CurrentStatus.CHECKING:
{
labelMainOperation.Text = "Checking updates...";
labelCurrentStatus.Text = "Please wait while checking for new " + App.GetAppName(app) + " version.";
btCancel.Text = "Close";
labelCurrentSize.Text = "";
progressBar.Visible = false;
progressBar.Value = 0;
labelCurrentSize.Visible = false;
labelTotalSize.Visible = false;
btUpgrade.Visible = false;
break;
}
case CurrentStatus.AVAILABLE:
{
labelMainOperation.Text = "Updates available";
labelCurrentStatus.Text = $"Version {updater.GetAvailableVersion()} of {App.GetAppName(app)} available. Update now to get the latest features and improvements";
btCancel.Text = "Not now";
btUpgrade.Text = "Download";
progressBar.Visible = false;
labelCurrentSize.Visible = false;
labelTotalSize.Visible = false;
btUpgrade.Visible = true;
break;
}
case CurrentStatus.READY_TO_INSTALL:
{
labelMainOperation.Text = "Updates are ready to install";
labelCurrentStatus.Text = $"The version {updater.GetAvailableVersion()} of {App.GetAppName(app)} is ready to install now. \n\n "
+ "It won't take long to upgrade - and you'll get all the latest improvements and fixes.";
btCancel.Text = "Not now";
btUpgrade.Text = "Upgrade";
progressBar.Visible = false;
labelCurrentSize.Visible = false;
labelTotalSize.Visible = false;
btUpgrade.Visible = true;
break;
}
case CurrentStatus.DOWNLOADING:
{
labelMainOperation.Text = "Downloading updates...";
labelCurrentStatus.Text = $"Please wait while the {App.GetAppName(app)} update is being downloaded.";
btCancel.Text = "Cancel";
progressBar.Visible = true;
labelCurrentSize.Visible = true;
labelTotalSize.Visible = true;
btUpgrade.Visible = false;
break;
}
case CurrentStatus.LATEST:
{
labelMainOperation.Text = "Up to date";
labelCurrentStatus.Text = "You have the latest version of " + App.GetAppName(app) + " installed.";
btCancel.Text = "Close";
labelCurrentSize.Text = "";
progressBar.Visible = false;
progressBar.Value = 0;
labelCurrentSize.Visible = false;
labelTotalSize.Visible = false;
btUpgrade.Visible = false;
break;
}
case CurrentStatus.FAILED:
{
labelMainOperation.Text = "Download failed";
labelCurrentStatus.Text = "Failed to download the update for " + App.GetAppName(app) + " . Please try again or contact support. ";
btUpgrade.Text = "Retry";
btCancel.Text = "Close";
labelCurrentSize.Text = "";
progressBar.Visible = false;
progressBar.Value = 0;
labelCurrentSize.Visible = false;
labelTotalSize.Visible = false;
btUpgrade.Visible = true;
break;
}
}
}
/// <summary>
/// Intercept mouse move on all the items of the form
/// </summary>
/// <param name="sender">UI object which raised the event</param>
/// <param name="e">Mouse event parameters</param>
private void SettingsForm_MouseMove(object sender, MouseEventArgs e)
{
// move form window if mouse moved with mouse pressed
if (e.Button == MouseButtons.Left)
{
ReleaseCapture();
SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
}
}
/// <summary>
/// Event handler for when the from is loaded. It will update the UI
/// elements to the value stored in the config file
/// </summary>
private void SettingsForm_Load(object sender, EventArgs e)
{
updater = new AutoUpdate(app) { IsDevelop = isDevelop };
updater.OnNewVersionAvailable += delegate (String version)
{
if(updater.UpdateDownloaded)
{
if (InvokeRequired)
this.Invoke((MethodInvoker)delegate ()
{
UpdateUIForStatus(CurrentStatus.READY_TO_INSTALL);
});
else
UpdateUIForStatus(CurrentStatus.READY_TO_INSTALL);
}
else
if (InvokeRequired)
this.Invoke((MethodInvoker)delegate ()
{
UpdateUIForStatus(CurrentStatus.AVAILABLE);
});
else
UpdateUIForStatus(CurrentStatus.AVAILABLE);
};
updater.OnLatestVersionAvailable += delegate ()
{
if (InvokeRequired)
this.Invoke((MethodInvoker)delegate ()
{
UpdateUIForStatus(CurrentStatus.LATEST);
});
else
UpdateUIForStatus(CurrentStatus.LATEST);
};
// register for progress changed
updater.OnProgressChanged += delegate (DownloadProgressChangedEventArgs ee)
{
string totalBytes = (ee.TotalBytesToReceive / 1024d).ToString("0.00");
string bytesReceived = (ee.BytesReceived / 1024d).ToString("0.00");
if (InvokeRequired)
{
this.Invoke((MethodInvoker)delegate ()
{
// Update the label with how much data have been downloaded so far and the total size of the file we are currently downloading
labelCurrentSize.Text = "downloaded " + ee.ProgressPercentage + "% (" + bytesReceived + " KB)";
labelTotalSize.Text = "File size " + totalBytes + " KB";
/*
labelDownloaded.Text = string.Format("{0} MB's / {1} MB's",
(e.BytesReceived / 1024d / 1024d).ToString("0.00"),
(e.TotalBytesToReceive / 1024d / 1024d).ToString("0.00"));*/
// Update the progressbar percentage only when the value is not the same.
progressBar.Value = ee.ProgressPercentage;
});
}
else
{
// Update the label with how much data have been downloaded so far and the total size of the file we are currently downloading
labelCurrentSize.Text = "downloaded " + ee.ProgressPercentage + "% (" + bytesReceived + " KB)";
labelTotalSize.Text = "File size " + totalBytes + " KB";
/*
labelDownloaded.Text = string.Format("{0} MB's / {1} MB's",
(e.BytesReceived / 1024d / 1024d).ToString("0.00"),
(e.TotalBytesToReceive / 1024d / 1024d).ToString("0.00"));*/
// Update the progressbar percentage only when the value is not the same.
progressBar.Value = ee.ProgressPercentage;
}
};
updater.OnDownloadCompleted += delegate (string filePath)
{
if (InvokeRequired)
this.Invoke((MethodInvoker)delegate ()
{
UpdateUIForStatus(CurrentStatus.READY_TO_INSTALL);
});
else
UpdateUIForStatus(CurrentStatus.READY_TO_INSTALL);
};
// failed to download the update
updater.OnDownloadFailed += delegate (Exception ex)
{
if (InvokeRequired)
this.Invoke((MethodInvoker)delegate ()
{
UpdateUIForStatus(CurrentStatus.FAILED);
});
else
UpdateUIForStatus(CurrentStatus.FAILED);
};
if (shouldCheck)
{
if (InvokeRequired)
this.Invoke((MethodInvoker)delegate ()
{
UpdateUIForStatus(CurrentStatus.CHECKING);
});
else
UpdateUIForStatus(CurrentStatus.CHECKING);
// updater.CheckUpdate();
}
else
{
if (InvokeRequired)
this.Invoke((MethodInvoker)delegate ()
{
UpdateUIForStatus(CurrentStatus.AVAILABLE);
});
else
UpdateUIForStatus(CurrentStatus.AVAILABLE);
}
}
private void btCancel_Click(object sender, EventArgs e)
{
if (currentState == CurrentStatus.DOWNLOADING)
updater?.CancelUpdate();
this.Close();
}
private void btUpgrade_Click(object sender, EventArgs e)
{
if (currentState == CurrentStatus.AVAILABLE || currentState == CurrentStatus.FAILED)
{
if (InvokeRequired)
this.Invoke((MethodInvoker)delegate ()
{
UpdateUIForStatus(CurrentStatus.DOWNLOADING);
});
else
UpdateUIForStatus(CurrentStatus.DOWNLOADING);
updater.Download();
}
else if(currentState == CurrentStatus.READY_TO_INSTALL)
{
//MotoTrbo_GW.Program.isRunning = false;
// close current process
Thread th = new Thread(new ThreadStart(delegate ()
{
Process p = new Process();
ProcessStartInfo info = new ProcessStartInfo();
info.CreateNoWindow = true;
info.FileName = "cmd.exe";
info.RedirectStandardInput = true;
info.RedirectStandardOutput = true;
info.UseShellExecute = false;
p.StartInfo = info;
p.Start();
StreamWriter sw = p.StandardInput;
if (sw.BaseStream.CanWrite)
{
//get the full location of the assembly with DaoTests in it
string fullPath = System.Reflection.Assembly.GetAssembly(typeof(UpdateForm)).Location;
//get the folder that's in
string theDirectory = Path.GetDirectoryName(fullPath);
String msiCmd = "msiexec /i " + '"' + updater.DownloadedFilePath + '"' + " TARGETDIR=" + '"' + theDirectory + '"';
sw.WriteLine(msiCmd);
}
sw.Close();
p.WaitForExit();
// start the msi file
//Process.Start(updater.DownloadedFilePath);
//Process.Start(System.Reflection.Assembly.GetExecutingAssembly().Location, Program.isConsoleEnabled ? " -c" : "");
Process oldProcess = Process.GetCurrentProcess();
oldProcess.Kill();
Application.Exit();
Thread.Sleep(300);
}));
th.Start();
}
}
}
}