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; } } } /// /// Intercept mouse move on all the items of the form /// /// UI object which raised the event /// Mouse event parameters 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); } } /// /// Event handler for when the from is loaded. It will update the UI /// elements to the value stored in the config file /// 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(); } } } }