private void bgThread_GetUpdatesCompleted(object sender, RunWorkerCompletedEventArgs e) { if (RemoteUpdate.Result != null && RemoteUpdate.Result.DidTaskSucceed) { // Retrieve and display the current Microsoft update configuration from the registry. DisplayUpdateConfiguration(RemoteUpdateConfiguration.GetUpdateConfiguration()); if (RemoteUpdate.GetRebootState()) { RebootRequired.Text = "* This computer has a pending required reboot."; RebootRequired.Visibility = Visibility.Visible; } else { RebootRequired.Text = string.Empty; RebootRequired.Visibility = Visibility.Collapsed; } // Bind the returned list of installed updates to the DataGrid. dgUpdates.ItemsSource = e.Result as List <RemoteUpdate>; RemoteAdmin.SortDataGrid(dgUpdates); gridLoading.Visibility = Visibility.Collapsed; } else { // Something went wrong while retrieving updates. Display an error overlay. gridLoading.Visibility = Visibility.Collapsed; gridError.Visibility = Visibility.Visible; } }
/// <summary> /// Check for a new version on the remote server (github.com). /// </summary> /// <param name="minUpdateType"></param> /// <returns></returns> public static async Task <RemoteUpdate> CheckForRemoteUpdateAsync(UpdateType minUpdateType = UpdateType.Stable) { var remoteUpdate = new RemoteUpdate(); try { var currentVersion = Assembly.GetExecutingAssembly().GetName().Version; remoteUpdate.CanUpdate = false; var remoteUpdateFile = Environment.Is64BitProcess ? Global.ApplicationUpdateUri64 : Global.ApplicationUpdateUri; var remoteUpdateData = await DownloadRemoteUpdateFileAsync(remoteUpdateFile).ConfigureAwait(false); if (remoteUpdateData != null) { using (var remoteUpdateDataStream = new MemoryStream(remoteUpdateData)) { using (var remoteUpdateDataStreamReader = new StreamReader(remoteUpdateDataStream)) { var deserializer = new DeserializerBuilder().WithNamingConvention(CamelCaseNamingConvention.Instance).Build(); remoteUpdate = deserializer.Deserialize <RemoteUpdate>(remoteUpdateDataStreamReader); } } } if (remoteUpdate != null) { var status = remoteUpdate.Update.Version.CompareTo(currentVersion); // The local version is newer as the remote version if (status < 0) { remoteUpdate.CanUpdate = false; } //The local version is the same as the remote version else if (status == 0) { remoteUpdate.CanUpdate = false; } else { // the remote version is newer as the local version if ((int)minUpdateType >= (int)remoteUpdate.Update.Type) { remoteUpdate.CanUpdate = true; } else { remoteUpdate.CanUpdate = false; } } } } catch (Exception exception) { Log.Error(exception); remoteUpdate.CanUpdate = false; } return(remoteUpdate); }
public async Task CheckForRemoteUpdateTest() { _remoteUpdate = await ApplicationUpdater.CheckForRemoteUpdateAsync().ConfigureAwait(false); Assert.AreNotEqual(_remoteUpdate, null); Assert.AreNotEqual(_remoteUpdate.Update, null); Assert.AreNotEqual(_remoteUpdate.Update.Installer, null); Assert.AreNotEqual(_remoteUpdate.Update.Signature, null); Assert.AreEqual(_remoteUpdate.Update.Publickey, Global.ApplicationUpdatePublicKey); Assert.AreEqual(_remoteUpdate.Update.Installer.Name, "SimpleDNSCrypt.msi"); }
public async Task RunUpdateAsync(RemoteUpdate remoteUpdate) { try { _logger.Log("run update: start", Category.Info, Priority.Low); IsUpdating = true; UpdateProgressValue = 0; UpdateProgressStatus = ""; var destinationFilePath = Path.Combine(Path.GetTempPath(), remoteUpdate.Update.Installer.Name);; using var client = new HttpClientDownloadWithProgress(remoteUpdate.Update.Installer.Uri, destinationFilePath); client.ProgressChanged += (totalFileSize, totalBytesDownloaded, progressPercentage) => { UpdateProgressValue = (int)progressPercentage; UpdateProgressStatus = $"Downloading update {progressPercentage}% ({totalBytesDownloaded}/{totalFileSize})"; }; _logger.Log($"start download: {remoteUpdate.Update.Installer.Uri}", Category.Info, Priority.Medium); await client.StartDownload(); _logger.Log($"download completed: {remoteUpdate.Update.Installer.Uri}", Category.Info, Priority.Medium); if (!string.IsNullOrEmpty(destinationFilePath)) { if (File.Exists(destinationFilePath)) { _logger.Log($"start installation of: {destinationFilePath}", Category.Info, Priority.Low); UpdateProgressStatus = "Starting installation ..."; //automatic installation const string arguments = "/qb /passive /norestart"; var startInfo = new ProcessStartInfo(destinationFilePath) { Arguments = arguments, UseShellExecute = true }; Process.Start(startInfo); _logger.Log($"killing application", Category.Info, Priority.Low); Process.GetCurrentProcess().Kill(); } else { _logger.Log($"missing installation: {destinationFilePath}", Category.Warn, Priority.Medium); } } IsUpdating = false; _logger.Log("run update: start", Category.Info, Priority.Low); } catch (Exception exception) { _logger.Log($"RunUpdateAsync {exception.Message}", Category.Exception, Priority.High); } }
public static async Task <RemoteUpdate> CheckForRemoteUpdateAsync() { var remoteUpdate = new RemoteUpdate(); try { var currentVersion = Assembly.GetExecutingAssembly().GetName().Version; remoteUpdate.CanUpdate = false; var remoteUpdateData = await DownloadRemoteUpdateFileAsync().ConfigureAwait(false); if (remoteUpdateData != null) { using (var remoteUpdateDataStream = new MemoryStream(remoteUpdateData)) { using (var serverConfigFile = new StreamReader(remoteUpdateDataStream)) { var deserializer = new Deserializer(namingConvention: new CamelCaseNamingConvention()); remoteUpdate = deserializer.Deserialize <RemoteUpdate>(serverConfigFile); } } } if (remoteUpdate != null) { var status = remoteUpdate.Update.Version.CompareTo(currentVersion); // The local version is newer as the remote version if (status < 0) { remoteUpdate.CanUpdate = false; } //The local version is the same as the remote version else if (status == 0) { remoteUpdate.CanUpdate = false; } else { // the remote version is newer as the local version remoteUpdate.CanUpdate = true; } } } catch (Exception) { remoteUpdate.CanUpdate = false; } return(remoteUpdate); }
private void bgThread_UninstallUpdate(object sender, DoWorkEventArgs e) { // Uninstall a Microsoft update. e.Result = RemoteUpdate.UninstallUpdate(e.Argument as RemoteUpdate); }
private void bgThread_GetUpdates(object sender, DoWorkEventArgs e) { e.Result = RemoteUpdate.GetInstalledUpdates(); }
private void MenuUninstallUpdate_Click(object sender, RoutedEventArgs e) { // Get the clicked MenuItem var menuItem = (MenuItem)sender; // Get the ContextMenu to which the menuItem belongs var contextMenu = (ContextMenu)menuItem.Parent; // Find the PlacementTarget var item = (DataGrid)contextMenu.PlacementTarget; // Get the underlying item, cast as my object type. var update = (RemoteUpdate)item.SelectedItem; // Determine if the selected update can be uninstalled and if automatic updates are enabled. bool isUpdateValid = RemoteUpdate.ExtractKbNumber(update.UpdateId).Length > 0; bool isAutoUpdateEnabled = (tbAutoUpdates.Text == "Automatic Updates") ? true : false; // Get a reference to MainWindow along with the coordinates of the current user control. var mainWindow = Window.GetWindow(this); Point controlPosition = this.PointToScreen(new Point(0d, 0d)); // Setup a DialogResult which will build the confirmation dialog box. var dialog = new DialogResult(); dialog.DialogTitle = "Uninstall Update"; dialog.DialogBody = $"Are you sure you want to uninstall this update?{Environment.NewLine}{update.UpdateId}"; dialog.DialogIconPath = "/Resources/caution-48.png"; dialog.ButtonIconPath = "/Resources/cancelRed-24.png"; dialog.ButtonText = "Uninstall"; dialog.IsCancelVisible = true; if (isAutoUpdateEnabled) { dialog.DialogBody = "Automatic updates are enabled. The target computer might automatically re-install the update at a later time." + $"{Environment.NewLine}{Environment.NewLine}Do you still want to uninstall this update?{Environment.NewLine}{update.UpdateId}"; } if (!isUpdateValid) { dialog.DialogTitle = "Error"; dialog.DialogBody = "The selected update cannot be uninstalled."; dialog.DialogIconPath = "/Resources/error-48.png"; dialog.ButtonIconPath = "/Resources/checkmark-24.png"; dialog.ButtonText = "OK"; dialog.IsCancelVisible = false; } // Display confirmation dialog window. if (DialogWindow.DisplayDialog(mainWindow, dialog, controlPosition) == true && isUpdateValid) { // User confirmed they want to terminate the selected process. // Setup a background thread. var bgWorker = new BackgroundWorker(); bgWorker.DoWork += new DoWorkEventHandler(bgThread_UninstallUpdate); bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgThread_UninstallUpdateCompleted); // Launch background thread to terminate the selected process. tbOverlay.Text = "Uninstalling selected update..."; gridOverlay.Visibility = Visibility.Visible; mainWindow.IsEnabled = false; bgWorker.RunWorkerAsync(update); } }
public async Task CheckForUpdatesAsync() { var remoteUpdate = new RemoteUpdate(); try { _logger.Log("update check: start", Category.Info, Priority.Low); var currentVersion = Assembly.GetExecutingAssembly().GetName().Version; remoteUpdate.CanUpdate = false; using var client = new HttpClient() { DefaultRequestVersion = new Version(2, 0) }; var response = await client.GetByteArrayAsync(Global.RemoteUpdateCheckUrl); if (response != null) { using (var remoteUpdateDataStream = new MemoryStream(response)) { using var remoteUpdateDataStreamReader = new StreamReader(remoteUpdateDataStream); var deserializer = new DeserializerBuilder().WithNamingConvention(CamelCaseNamingConvention.Instance).Build(); remoteUpdate = deserializer.Deserialize <RemoteUpdate>(remoteUpdateDataStreamReader); } if (remoteUpdate != null) { var status = remoteUpdate.Update.Version.CompareTo(currentVersion); // The local version is newer as the remote version if (status < 0) { remoteUpdate.CanUpdate = false; _logger.Log($"update check: You are already using the latest version: {currentVersion}", Category.Info, Priority.Low); MessageQueue.Enqueue($"You are already using the latest version: {currentVersion}"); } //The local version is the same as the remote version else if (status == 0) { remoteUpdate.CanUpdate = false; _logger.Log($"update check: The local version is the same as the remote version: {currentVersion}", Category.Info, Priority.Low); MessageQueue.Enqueue($"You are already using the latest version: {currentVersion}"); } else { // the remote version is newer as the local version remoteUpdate.CanUpdate = true; _logger.Log($"update check: the remote version is newer as the local version: {currentVersion} < {remoteUpdate.Update.Version}", Category.Info, Priority.Low); MessageQueue.Enqueue($"A newer version exists: {remoteUpdate.Update.Version}", "Update Now", async() => await RunUpdateAsync(remoteUpdate)); } } else { _logger.Log($"failed to check for updates: invalid update file", Category.Warn, Priority.High); MessageQueue.Enqueue("Failed to check for updates"); } } else { _logger.Log($"failed to check for updates: no response from server", Category.Warn, Priority.High); MessageQueue.Enqueue("Failed to check for updates"); } _logger.Log("update check: end", Category.Info, Priority.Low); } catch (Exception exception) { MessageQueue.Enqueue("An error occurred when checking updates. Please check the logs."); _logger.Log($"CheckForUpdatesAsync {exception.Message}", Category.Exception, Priority.High); } }