/// <summary> /// Loads the screenshots. /// </summary> public void Load(ImageFormatCollection imageFormatCollection, ScreenCollection screenCollection, RegionCollection regionCollection) { try { _mutexWriteFile.WaitOne(); Log.Write("Loading screenshots from screenshots.xml"); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); if (_screenshotList == null) { _screenshotList = new List <Screenshot>(); Log.Write("Initialized screenshot list"); } if (_slideList == null) { _slideList = new List <Slide>(); Log.Write("Initialized slide list"); } if (_slideNameList == null) { _slideNameList = new List <string>(); Log.Write("Initialized slide name list"); } if (_screenshotList != null && Directory.Exists(FileSystem.ApplicationFolder) && !File.Exists(FileSystem.ApplicationFolder + FileSystem.ScreenshotsFile)) { Log.Write("Could not find \"" + FileSystem.ApplicationFolder + FileSystem.ScreenshotsFile + "\" so creating it"); XmlWriterSettings xSettings = new XmlWriterSettings { Indent = true, CloseOutput = true, CheckCharacters = true, Encoding = Encoding.UTF8, NewLineChars = Environment.NewLine, IndentChars = XML_FILE_INDENT_CHARS, NewLineHandling = NewLineHandling.Entitize, ConformanceLevel = ConformanceLevel.Document }; using (XmlWriter xWriter = XmlWriter.Create(FileSystem.ApplicationFolder + FileSystem.ScreenshotsFile, xSettings)) { xWriter.WriteStartDocument(); xWriter.WriteStartElement(XML_FILE_ROOT_NODE); xWriter.WriteAttributeString("app", "version", XML_FILE_ROOT_NODE, Settings.ApplicationVersion); xWriter.WriteAttributeString("app", "codename", XML_FILE_ROOT_NODE, Settings.ApplicationCodename); xWriter.WriteStartElement(XML_FILE_SCREENSHOTS_NODE); xWriter.WriteEndElement(); xWriter.WriteEndElement(); xWriter.WriteEndDocument(); xWriter.Flush(); xWriter.Close(); } Log.Write("Created \"" + FileSystem.ApplicationFolder + FileSystem.ScreenshotsFile + "\""); } if (_screenshotList != null && Directory.Exists(FileSystem.ApplicationFolder) && File.Exists(FileSystem.ApplicationFolder + FileSystem.ScreenshotsFile)) { xDoc = new XmlDocument(); lock (xDoc) { xDoc.Load(FileSystem.ApplicationFolder + FileSystem.ScreenshotsFile); AppVersion = xDoc.SelectSingleNode("/autoscreen").Attributes["app:version"]?.Value; AppCodename = xDoc.SelectSingleNode("/autoscreen").Attributes["app:codename"]?.Value; Log.Write("Getting screenshots from screenshots.xml using XPath query \"" + SCREENSHOT_XPATH + "\""); XmlNodeList xScreeshots = xDoc.SelectNodes(SCREENSHOT_XPATH); if (xScreeshots != null) { Log.Write("Loading each screenshot from screenshots.xml"); foreach (XmlNode xScreenshot in xScreeshots) { Screenshot screenshot = new Screenshot(); screenshot.Slide = new Slide(); XmlNodeReader xReader = new XmlNodeReader(xScreenshot); while (xReader.Read()) { if (xReader.IsStartElement()) { switch (xReader.Name) { case SCREENSHOT_VIEWID: xReader.Read(); screenshot.ViewId = Guid.Parse(xReader.Value); break; case SCREENSHOT_DATE: xReader.Read(); screenshot.Date = xReader.Value; screenshot.Slide.Date = xReader.Value; break; case SCREENSHOT_TIME: xReader.Read(); screenshot.Time = xReader.Value; break; case SCREENSHOT_PATH: xReader.Read(); screenshot.Path = xReader.Value; break; case SCREENSHOT_FORMAT: xReader.Read(); screenshot.Format = imageFormatCollection.GetByName(xReader.Value); break; // 2.1 used "screen" for its definition of each display/monitor whereas 2.2 uses "component". // Active Window is now represented by 0 rather than 5. case SCREENSHOT_SCREEN: if (Settings.VersionManager.IsOldAppVersion(AppCodename, AppVersion) && Settings.VersionManager.Versions.Get("Clara", "2.1.8.2") != null && string.IsNullOrEmpty(AppCodename) && string.IsNullOrEmpty(AppVersion)) { xReader.Read(); screenshot.Screen = Convert.ToInt32(xReader.Value); screenshot.Component = screenshot.Screen == 5 ? 0 : screenshot.Screen; } break; // We still want to support "component" since this was introduced in version 2.2 as the new representation for "screen". case SCREENSHOT_COMPONENT: xReader.Read(); screenshot.Component = Convert.ToInt32(xReader.Value); if (screenshot.Component == -1) { screenshot.ScreenshotType = ScreenshotType.Region; } else if (screenshot.Component == 0) { screenshot.ScreenshotType = ScreenshotType.ActiveWindow; } else { screenshot.ScreenshotType = ScreenshotType.Screen; } break; case SCREENSHOT_SLIDENAME: xReader.Read(); screenshot.Slide.Name = xReader.Value; break; case SCREENSHOT_SLIDEVALUE: xReader.Read(); screenshot.Slide.Value = xReader.Value; break; case SCREENSHOT_WINDOW_TITLE: xReader.Read(); screenshot.WindowTitle = xReader.Value; break; case SCREENSHOT_PROCESS_NAME: xReader.Read(); screenshot.ProcessName = xReader.Value; break; case SCREENSHOT_LABEL: xReader.Read(); screenshot.Label = xReader.Value; break; } } } xReader.Close(); if (Settings.VersionManager.IsOldAppVersion(AppCodename, AppVersion)) { if (Settings.VersionManager.Versions.Get("Clara", "2.1.8.2") != null && string.IsNullOrEmpty(AppCodename) && string.IsNullOrEmpty(AppVersion)) { // We need to associate the screenshot's view ID with the component's view ID // because this special ID value is used for figuring out what screenshot image to display. screenshot.ViewId = screenCollection.GetByComponent(screenshot.Component).ViewId; string windowTitle = "*Screenshot imported from an old version of Auto Screen Capture*"; Regex rgxOldSlidename = new Regex(@"^(?<Date>\d{4}-\d{2}-\d{2}) (?<Time>(?<Hour>\d{2})-(?<Minute>\d{2})-(?<Second>\d{2})-(?<Millisecond>\d{3}))"); string hour = rgxOldSlidename.Match(screenshot.Slide.Name).Groups["Hour"].Value; string minute = rgxOldSlidename.Match(screenshot.Slide.Name).Groups["Minute"].Value; string second = rgxOldSlidename.Match(screenshot.Slide.Name).Groups["Second"].Value; string millisecond = rgxOldSlidename.Match(screenshot.Slide.Name).Groups["Millisecond"].Value; screenshot.Date = rgxOldSlidename.Match(screenshot.Slide.Name).Groups["Date"].Value; screenshot.Time = hour + ":" + minute + ":" + second + "." + millisecond; screenshot.Slide.Name = "{date=" + screenshot.Date + "}{time=" + screenshot.Time + "}"; screenshot.Slide.Value = screenshot.Time + " [" + windowTitle + "]"; screenshot.WindowTitle = windowTitle; } // Remove all the existing XML child nodes from the old XML screenshot. xScreenshot.RemoveAll(); // Prepare the new XML child nodes for the old XML screenshot ... XmlElement xViewId = xDoc.CreateElement(SCREENSHOT_VIEWID); xViewId.InnerText = screenshot.ViewId.ToString(); XmlElement xDate = xDoc.CreateElement(SCREENSHOT_DATE); xDate.InnerText = screenshot.Date; XmlElement xTime = xDoc.CreateElement(SCREENSHOT_TIME); xTime.InnerText = screenshot.Time; XmlElement xPath = xDoc.CreateElement(SCREENSHOT_PATH); xPath.InnerText = screenshot.Path; XmlElement xFormat = xDoc.CreateElement(SCREENSHOT_FORMAT); xFormat.InnerText = screenshot.Format.Name; XmlElement xComponent = xDoc.CreateElement(SCREENSHOT_COMPONENT); xComponent.InnerText = screenshot.Component.ToString(); XmlElement xSlidename = xDoc.CreateElement(SCREENSHOT_SLIDENAME); xSlidename.InnerText = screenshot.Slide.Name; XmlElement xSlidevalue = xDoc.CreateElement(SCREENSHOT_SLIDEVALUE); xSlidevalue.InnerText = screenshot.Slide.Value; XmlElement xWindowTitle = xDoc.CreateElement(SCREENSHOT_WINDOW_TITLE); xWindowTitle.InnerText = screenshot.WindowTitle; XmlElement xProcessName = xDoc.CreateElement(SCREENSHOT_PROCESS_NAME); xProcessName.InnerText = screenshot.ProcessName; XmlElement xLabel = xDoc.CreateElement(SCREENSHOT_LABEL); xLabel.InnerText = screenshot.Label; // Create the new XML child nodes for the old XML screenshot so that it's now in the format of the new XML screenshot. xScreenshot.AppendChild(xViewId); xScreenshot.AppendChild(xDate); xScreenshot.AppendChild(xTime); xScreenshot.AppendChild(xPath); xScreenshot.AppendChild(xFormat); xScreenshot.AppendChild(xComponent); xScreenshot.AppendChild(xSlidename); xScreenshot.AppendChild(xSlidevalue); xScreenshot.AppendChild(xWindowTitle); xScreenshot.AppendChild(xProcessName); xScreenshot.AppendChild(xLabel); } if (!string.IsNullOrEmpty(screenshot.Date) && !string.IsNullOrEmpty(screenshot.Time) && !string.IsNullOrEmpty(screenshot.Path) && screenshot.Format != null && !string.IsNullOrEmpty(screenshot.Slide.Name) && !string.IsNullOrEmpty(screenshot.Slide.Value) && !string.IsNullOrEmpty(screenshot.WindowTitle)) { screenshot.Saved = true; Add(screenshot); } } } else { Log.Write("WARNING: Unable to load screenshots from screenshots.xml"); } if (Settings.VersionManager.IsOldAppVersion(AppCodename, AppVersion)) { Log.Write("Old application version discovered when loading screenshots.xml"); // We'll have to create the app:version and app:codename attributes for screenshots.xml if we're upgrading from "Clara". if (Settings.VersionManager.Versions.Get("Clara", "2.1.8.2") != null && string.IsNullOrEmpty(AppCodename) && string.IsNullOrEmpty(AppVersion)) { XmlAttribute attributeVersion = xDoc.CreateAttribute("app", "version", "autoscreen"); XmlAttribute attributeCodename = xDoc.CreateAttribute("app", "codename", "autoscreen"); attributeVersion.Value = Settings.ApplicationVersion; attributeCodename.Value = Settings.ApplicationCodename; xDoc.SelectSingleNode("/" + XML_FILE_ROOT_NODE).Attributes.Append(attributeVersion); xDoc.SelectSingleNode("/" + XML_FILE_ROOT_NODE).Attributes.Append(attributeCodename); } // Apply the latest version and codename if the version of Auto Screen Capture is older than this version. xDoc.SelectSingleNode("/" + XML_FILE_ROOT_NODE).Attributes["app:version"].Value = Settings.ApplicationVersion; xDoc.SelectSingleNode("/" + XML_FILE_ROOT_NODE).Attributes["app:codename"].Value = Settings.ApplicationCodename; xDoc.Save(FileSystem.ApplicationFolder + FileSystem.ScreenshotsFile); Log.Write("Upgraded screenshots.xml"); } } } stopwatch.Stop(); Log.Write("It took " + stopwatch.ElapsedMilliseconds + " milliseconds to load " + _screenshotList.Count + " screenshots"); } catch (Exception ex) { Log.Write("ScreenshotCollection::Load", ex); } finally { _mutexWriteFile.ReleaseMutex(); } }
/// <summary> /// Loads the screenshots. /// </summary> public static void Load(ImageFormatCollection imageFormatCollection, ScreenCollection screenCollection, RegionCollection regionCollection) { if (Directory.Exists(FileSystem.ApplicationFolder) && File.Exists(FileSystem.ApplicationFolder + FileSystem.ScreenshotsFile)) { xDoc = new XmlDocument(); xDoc.Load(FileSystem.ApplicationFolder + FileSystem.ScreenshotsFile); AppVersion = xDoc.SelectSingleNode("/autoscreen").Attributes["app:version"]?.Value; AppCodename = xDoc.SelectSingleNode("/autoscreen").Attributes["app:codename"]?.Value; XmlNodeList xScreeshots = xDoc.SelectNodes(SCREENSHOT_XPATH); foreach (XmlNode xScreenshot in xScreeshots) { Screenshot screenshot = new Screenshot(); screenshot.Slide = new Slide(); XmlNodeReader xReader = new XmlNodeReader(xScreenshot); while (xReader.Read()) { if (xReader.IsStartElement()) { switch (xReader.Name) { case SCREENSHOT_VIEWID: xReader.Read(); screenshot.ViewId = Guid.Parse(xReader.Value); break; case SCREENSHOT_DATE: xReader.Read(); screenshot.Date = xReader.Value; break; case SCREENSHOT_TIME: xReader.Read(); screenshot.Time = xReader.Value; break; case SCREENSHOT_PATH: xReader.Read(); screenshot.Path = xReader.Value; break; case SCREENSHOT_FORMAT: xReader.Read(); screenshot.Format = imageFormatCollection.GetByName(xReader.Value); break; // 2.1 used "screen" for its definition of each display/monitor whereas 2.2 uses "component". // Active Window is now represented by 0 rather than 5. case SCREENSHOT_SCREEN: if (Settings.VersionManager.IsOldAppVersion(AppVersion, AppCodename) && Settings.VersionManager.Versions.Get("Clara", "2.1.8.2") != null) { xReader.Read(); screenshot.Screen = Convert.ToInt32(xReader.Value); screenshot.Component = screenshot.Screen == 5 ? 0 : screenshot.Screen; } break; // We still want to support "component" since this was introduced in version 2.2 as the new representation for "screen". case SCREENSHOT_COMPONENT: xReader.Read(); screenshot.Component = Convert.ToInt32(xReader.Value); if (screenshot.Component == -1) { screenshot.ScreenshotType = ScreenshotType.Region; } else if (screenshot.Component == 0) { screenshot.ScreenshotType = ScreenshotType.ActiveWindow; } else { screenshot.ScreenshotType = ScreenshotType.Screen; } break; case SCREENSHOT_SLIDENAME: xReader.Read(); screenshot.Slide.Name = xReader.Value; break; case SCREENSHOT_SLIDEVALUE: xReader.Read(); screenshot.Slide.Value = xReader.Value; break; case SCREENSHOT_WINDOW_TITLE: xReader.Read(); screenshot.WindowTitle = xReader.Value; break; case SCREENSHOT_LABEL: xReader.Read(); screenshot.Label = xReader.Value; break; } } } xReader.Close(); if (Settings.VersionManager.IsOldAppVersion(AppVersion, AppCodename)) { if (Settings.VersionManager.Versions.Get("Clara", "2.1.8.2") != null) { // We need to associate the screenshot's view ID with the component's view ID // because this special ID value is used for figuring out what screenshot image to display. screenshot.ViewId = screenCollection.GetByComponent(screenshot.Component).ViewId; string windowTitle = "*Screenshot imported from an old version of Auto Screen Capture*"; Regex rgxOldSlidename = new Regex( @"^(?<Date>\d{4}-\d{2}-\d{2}) (?<Time>(?<Hour>\d{2})-(?<Minute>\d{2})-(?<Second>\d{2})-(?<Millisecond>\d{3}))"); string hour = rgxOldSlidename.Match(screenshot.Slide.Name).Groups["Hour"].Value; string minute = rgxOldSlidename.Match(screenshot.Slide.Name).Groups["Minute"].Value; string second = rgxOldSlidename.Match(screenshot.Slide.Name).Groups["Second"].Value; string millisecond = rgxOldSlidename.Match(screenshot.Slide.Name).Groups["Millisecond"] .Value; screenshot.Date = rgxOldSlidename.Match(screenshot.Slide.Name).Groups["Date"].Value; screenshot.Time = hour + ":" + minute + ":" + second + "." + millisecond; screenshot.Slide.Name = "{date=" + screenshot.Date + "}{time=" + screenshot.Time + "}"; screenshot.Slide.Value = screenshot.Time + " [" + windowTitle + "]"; screenshot.WindowTitle = windowTitle; } } if (!string.IsNullOrEmpty(screenshot.Date) && !string.IsNullOrEmpty(screenshot.Time) && !string.IsNullOrEmpty(screenshot.Path) && screenshot.Format != null && !string.IsNullOrEmpty(screenshot.Slide.Name) && !string.IsNullOrEmpty(screenshot.Slide.Value)) { Add(screenshot, screenCollection, regionCollection); } } // Write out the upgraded screenshots (if any were found). if (Settings.VersionManager.IsOldAppVersion(AppVersion, AppCodename)) { Save(); } } }
/// <summary> /// Loads the screenshots taken on a particular day from the screenshots.xml file. /// </summary> /// <param name="date">The date to load screenshots from.</param> public int LoadXmlFileAndAddScreenshots(string date) { try { _mutexWriteFile.WaitOne(); XmlNodeList xScreenshots = null; if (string.IsNullOrEmpty(date)) { return(1); } if (xDoc != null) { lock (xDoc) { AppVersion = xDoc.SelectSingleNode("/autoscreen").Attributes["app:version"]?.Value; AppCodename = xDoc.SelectSingleNode("/autoscreen").Attributes["app:codename"]?.Value; Log.WriteDebugMessage("Loading screenshots taken on " + date + " from \"" + FileSystem.ScreenshotsFile + "\" using XPath query \"" + SCREENSHOT_XPATH + "[date='" + date + "']" + "\""); xScreenshots = xDoc.SelectNodes(SCREENSHOT_XPATH + "[date='" + date + "']"); if (xScreenshots != null) { Log.WriteMessage("Loading " + xScreenshots.Count + " screenshots taken on " + date); int screenshotsLoadLimit = Convert.ToInt32(Settings.Application.GetByKey("ScreenshotsLoadLimit", DefaultSettings.ScreenshotsLoadLimit).Value); if (xScreenshots.Count >= screenshotsLoadLimit) { HelpTip.Message = "Cannot load screenshots taken on " + date + " as the number of screenshots being loaded (" + xScreenshots.Count + ") exceeds the allowed load limit (" + screenshotsLoadLimit + ")"; Log.WriteDebugMessage("Cannot load screenshots. The number of screenshots to be loaded (" + xScreenshots.Count + ") exceeded the number allowed set by ScreenshotsLoadLimit (" + screenshotsLoadLimit + ")"); return(2); } foreach (XmlNode xScreenshot in xScreenshots) { Screenshot screenshot = new Screenshot(); screenshot.Slide = new Slide(); XmlNodeReader xReader = new XmlNodeReader(xScreenshot); while (xReader.Read()) { if (xReader.IsStartElement() && !xReader.IsEmptyElement) { switch (xReader.Name) { case SCREENSHOT_VIEWID: xReader.Read(); screenshot.ViewId = Guid.Parse(xReader.Value); break; case SCREENSHOT_DATE: xReader.Read(); screenshot.Date = xReader.Value; screenshot.Slide.Date = xReader.Value; break; case SCREENSHOT_TIME: xReader.Read(); screenshot.Time = xReader.Value; break; case SCREENSHOT_PATH: xReader.Read(); screenshot.Path = xReader.Value; break; case SCREENSHOT_FORMAT: xReader.Read(); screenshot.Format = _imageFormatCollection.GetByName(xReader.Value); break; // 2.1 used "screen" for its definition of each display/monitor whereas 2.2 uses "component". // Active Window is now represented by 0 rather than 5. case SCREENSHOT_SCREEN: if (Settings.VersionManager.IsOldAppVersion(AppCodename, AppVersion) && Settings.VersionManager.Versions.Get("Clara", "2.1.8.2") != null && string.IsNullOrEmpty(AppCodename) && string.IsNullOrEmpty(AppVersion)) { xReader.Read(); screenshot.Screen = Convert.ToInt32(xReader.Value); screenshot.Component = screenshot.Screen == 5 ? 0 : screenshot.Screen; } break; // We still want to support "component" since this was introduced in version 2.2 as the new representation for "screen". case SCREENSHOT_COMPONENT: xReader.Read(); screenshot.Component = Convert.ToInt32(xReader.Value); if (screenshot.Component == -1) { screenshot.ScreenshotType = ScreenshotType.Region; } else if (screenshot.Component == 0) { screenshot.ScreenshotType = ScreenshotType.ActiveWindow; } else { screenshot.ScreenshotType = ScreenshotType.Screen; } break; case SCREENSHOT_SLIDENAME: xReader.Read(); screenshot.Slide.Name = xReader.Value; break; case SCREENSHOT_SLIDEVALUE: xReader.Read(); screenshot.Slide.Value = xReader.Value; break; case SCREENSHOT_WINDOW_TITLE: xReader.Read(); screenshot.WindowTitle = xReader.Value; break; case SCREENSHOT_PROCESS_NAME: xReader.Read(); screenshot.ProcessName = xReader.Value; break; case SCREENSHOT_LABEL: xReader.Read(); screenshot.Label = xReader.Value; break; } } } xReader.Close(); if (Settings.VersionManager.IsOldAppVersion(AppCodename, AppVersion)) { if (Settings.VersionManager.Versions.Get("Clara", "2.1.8.2") != null && string.IsNullOrEmpty(AppCodename) && string.IsNullOrEmpty(AppVersion)) { // We need to associate the screenshot's view ID with the component's view ID // because this special ID value is used for figuring out what screenshot image to display. screenshot.ViewId = _screenCollection.GetByComponent(screenshot.Component).ViewId; string windowTitle = "*Screenshot imported from an old version of " + Settings.ApplicationName + "*"; Regex rgxOldSlidename = new Regex(@"^(?<Date>\d{4}-\d{2}-\d{2}) (?<Time>(?<Hour>\d{2})-(?<Minute>\d{2})-(?<Second>\d{2})-(?<Millisecond>\d{3}))"); string hour = rgxOldSlidename.Match(screenshot.Slide.Name).Groups["Hour"].Value; string minute = rgxOldSlidename.Match(screenshot.Slide.Name).Groups["Minute"].Value; string second = rgxOldSlidename.Match(screenshot.Slide.Name).Groups["Second"].Value; string millisecond = rgxOldSlidename.Match(screenshot.Slide.Name).Groups["Millisecond"].Value; screenshot.Date = rgxOldSlidename.Match(screenshot.Slide.Name).Groups["Date"].Value; screenshot.Time = hour + ":" + minute + ":" + second + "." + millisecond; screenshot.Slide.Name = "{date=" + screenshot.Date + "}{time=" + screenshot.Time + "}"; screenshot.Slide.Value = screenshot.Time + " [" + windowTitle + "]"; screenshot.WindowTitle = windowTitle; } // Remove all the existing XML child nodes from the old XML screenshot. xScreenshot.RemoveAll(); // Prepare the new XML child nodes for the old XML screenshot ... XmlElement xViewId = xDoc.CreateElement(SCREENSHOT_VIEWID); xViewId.InnerText = screenshot.ViewId.ToString(); XmlElement xDate = xDoc.CreateElement(SCREENSHOT_DATE); xDate.InnerText = screenshot.Date; XmlElement xTime = xDoc.CreateElement(SCREENSHOT_TIME); xTime.InnerText = screenshot.Time; XmlElement xPath = xDoc.CreateElement(SCREENSHOT_PATH); xPath.InnerText = screenshot.Path; XmlElement xFormat = xDoc.CreateElement(SCREENSHOT_FORMAT); xFormat.InnerText = screenshot.Format.Name; XmlElement xComponent = xDoc.CreateElement(SCREENSHOT_COMPONENT); xComponent.InnerText = screenshot.Component.ToString(); XmlElement xSlidename = xDoc.CreateElement(SCREENSHOT_SLIDENAME); xSlidename.InnerText = screenshot.Slide.Name; XmlElement xSlidevalue = xDoc.CreateElement(SCREENSHOT_SLIDEVALUE); xSlidevalue.InnerText = screenshot.Slide.Value; XmlElement xWindowTitle = xDoc.CreateElement(SCREENSHOT_WINDOW_TITLE); xWindowTitle.InnerText = screenshot.WindowTitle; XmlElement xProcessName = xDoc.CreateElement(SCREENSHOT_PROCESS_NAME); xProcessName.InnerText = screenshot.ProcessName; XmlElement xLabel = xDoc.CreateElement(SCREENSHOT_LABEL); xLabel.InnerText = screenshot.Label; // Create the new XML child nodes for the old XML screenshot so that it's now in the format of the new XML screenshot. xScreenshot.AppendChild(xViewId); xScreenshot.AppendChild(xDate); xScreenshot.AppendChild(xTime); xScreenshot.AppendChild(xPath); xScreenshot.AppendChild(xFormat); xScreenshot.AppendChild(xComponent); xScreenshot.AppendChild(xSlidename); xScreenshot.AppendChild(xSlidevalue); xScreenshot.AppendChild(xWindowTitle); xScreenshot.AppendChild(xProcessName); xScreenshot.AppendChild(xLabel); } if (!string.IsNullOrEmpty(screenshot.Date) && !string.IsNullOrEmpty(screenshot.Time) && !string.IsNullOrEmpty(screenshot.Path) && screenshot.Format != null && !string.IsNullOrEmpty(screenshot.Slide.Name) && !string.IsNullOrEmpty(screenshot.Slide.Value) && !string.IsNullOrEmpty(screenshot.WindowTitle)) { // Since we're loading existing screenshots from the XML document each screenshot needs to be flagged as being "Saved" // because they were already saved to the file before loading them. The "Saved" flag should only be used when we're // saving new screenshots to avoid saving the entire screenshots collection. // // In other words, any screenshot flagged with a "Saved" value of "true" will be treated as if it is already in the file. // A screenshot flagged with a "Saved" value of "false" will be treated as a new screenshot that should be saved to the file. screenshot.Saved = true; Add(screenshot); } } } else { Log.WriteDebugMessage("WARNING: Unable to load screenshots taken on " + date + " from \"" + FileSystem.ScreenshotsFile + "\""); } } } return(0); } catch (Exception ex) { Log.WriteExceptionMessage("ScreenshotCollection::LoadXmlFileAndAddScreenshots", ex); return(-1); } finally { _mutexWriteFile.ReleaseMutex(); } }