internal async Task NoticeNewVersionAsync(string version) { var admins = await _userManager.GetUsersInRoleAsync(Roles.ServerAdmin); var adminUids = admins.Select(a => a.Id).ToArray(); var notif = new NewVersionNotification { Version = version }; using (var db = _contextFactory.CreateContext()) { foreach (var uid in adminUids) { var data = notif.ToData(uid); db.Notifications.Add(data); } await db.SaveChangesAsync(); } // propagate notification _eventAggregator.Publish(new NotificationEvent { ApplicationUserIds = adminUids, Notification = notif }); }
/// <summary> /// Checks for updates by comparing the current version number of Timelapse or the Editor with a version stored on the Timelapse website in an xml file in either /// timelapse_version.xml or timelapse_template_version.xml (as specified in the latestVersionAddress). /// Displays a notification with recent update information /// Optionally displays a message to the user (if showNoUpdatesMessage is false) indicating the status /// </summary> /// <param name="showNoUpdatesMessage"></param> /// <returns>True if an update is available, else false</returns> public bool TryCheckForNewVersionAndDisplayResultsAsNeeded(bool showNoUpdatesMessage) { string url = String.Empty; // THE URL where the new version is located Version latestVersionNumber = null; // if a new version is available, store the new version number here XmlReader reader = null; try { // This pattern follows recommended correction to CA3075: Insecure DTD Processing // provide the XmlReader with the URL of our xml document XmlReaderSettings settings = new XmlReaderSettings() { XmlResolver = null }; reader = XmlReader.Create(this.latestVersionAddress.AbsoluteUri, settings); reader.MoveToContent(); // skip the junk at the beginning // As the XmlTextReader moves only forward, we save current xml element name in elementName variable. // When we parse a text node, we refer to elementName to check what was the node name string elementName = String.Empty; // Check if the xml starts with a <timelapse> Element if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == Constant.VersionXml.Timelapse)) { // Read the various elements and their associated contents while (reader.Read()) { // when we find an element node, we remember its name if (reader.NodeType == XmlNodeType.Element) { elementName = reader.Name; } else { // for text nodes... if ((reader.NodeType == XmlNodeType.Text) && reader.HasValue) { // we check what the name of the node was switch (elementName) { case Constant.VersionXml.Version: // we keep the version info in xxx.xxx.xxx.xxx format as the Version class does the parsing for us latestVersionNumber = new Version(reader.Value); break; case Constant.VersionXml.Url: url = reader.Value; break; } } } } } } catch (Exception) { return(false); } finally { if (reader != null) { reader.Close(); } } // get the running version Version currentVersionNumber = VersionChecks.GetTimelapseCurrentVersionNumber(); // compare the versions if (currentVersionNumber < latestVersionNumber) { NewVersionNotification newVersionNotification = new NewVersionNotification(this.window, this.applicationName, currentVersionNumber, latestVersionNumber); bool?result = newVersionNotification.ShowDialog(); if (result == true) { // navigate the default web browser to our app homepage (the url comes from the xml content) ProcessExecution.TryProcessStart(new Uri(url)); } } else if (showNoUpdatesMessage) { Dialogs.NoUpdatesAvailableDialog(Application.Current.MainWindow, this.applicationName, currentVersionNumber); } return(true); }