/// <summary>
        /// Loads the screenshots.
        /// </summary>
        public void Load(ImageFormatCollection imageFormatCollection, ScreenCollection screenCollection, RegionCollection regionCollection)
        {
            try
            {
                _mutexWriteFile.WaitOne();

                Log.Write("Loading screenshots from \"" + FileSystem.ScreenshotsFile + "\" (if this is a large file then it might take a while)");

                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 && !File.Exists(FileSystem.ScreenshotsFile))
                {
                    Log.Write("Could not find \"" + FileSystem.ScreenshotsFile + "\" so creating default version");

                    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.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.ScreenshotsFile + "\"");
                }

                if (_screenshotList != null && File.Exists(FileSystem.ScreenshotsFile))
                {
                    xDoc = new XmlDocument();

                    lock (xDoc)
                    {
                        xDoc.Load(FileSystem.ScreenshotsFile);

                        AppVersion  = xDoc.SelectSingleNode("/autoscreen").Attributes["app:version"]?.Value;
                        AppCodename = xDoc.SelectSingleNode("/autoscreen").Attributes["app:codename"]?.Value;

                        Log.Write("Getting screenshots from \"" + FileSystem.ScreenshotsFile + "\" using XPath query \"" + SCREENSHOT_XPATH + "\"");

                        XmlNodeList xScreeshots = xDoc.SelectNodes(SCREENSHOT_XPATH);

                        if (xScreeshots != null)
                        {
                            Log.Write("Loading " + xScreeshots.Count + " screenshots from \"" + FileSystem.ScreenshotsFile + "\" ...");

                            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);

                                            if (Log.DebugMode)
                                            {
                                                Log.Write("[" + screenshot.ViewId + "] View Id = " + screenshot.ViewId);
                                            }
                                            break;

                                        case SCREENSHOT_DATE:
                                            xReader.Read();
                                            screenshot.Date       = xReader.Value;
                                            screenshot.Slide.Date = xReader.Value;

                                            if (Log.DebugMode)
                                            {
                                                Log.Write("[" + screenshot.ViewId + "] Date = " + screenshot.Date);
                                            }
                                            break;

                                        case SCREENSHOT_TIME:
                                            xReader.Read();
                                            screenshot.Time = xReader.Value;

                                            if (Log.DebugMode)
                                            {
                                                Log.Write("[" + screenshot.ViewId + "] Time = " + screenshot.Time);
                                            }
                                            break;

                                        case SCREENSHOT_PATH:
                                            xReader.Read();
                                            screenshot.Path = xReader.Value;

                                            if (Log.DebugMode)
                                            {
                                                Log.Write("[" + screenshot.ViewId + "] Path = " + screenshot.Path);
                                            }
                                            break;

                                        case SCREENSHOT_FORMAT:
                                            xReader.Read();
                                            screenshot.Format = imageFormatCollection.GetByName(xReader.Value);

                                            if (Log.DebugMode)
                                            {
                                                Log.Write("[" + screenshot.ViewId + "] Format = " + screenshot.Format);
                                            }
                                            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;
                                            }

                                            if (Log.DebugMode)
                                            {
                                                Log.Write("[" + screenshot.ViewId + "] Component = " + screenshot.Component);
                                            }
                                            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;
                                            }

                                            if (Log.DebugMode)
                                            {
                                                Log.Write("[" + screenshot.ViewId + "] Component = " + screenshot.Component);
                                            }
                                            break;

                                        case SCREENSHOT_SLIDENAME:
                                            xReader.Read();
                                            screenshot.Slide.Name = xReader.Value;

                                            if (Log.DebugMode)
                                            {
                                                Log.Write("[" + screenshot.ViewId + "] Slide Name = " + screenshot.Slide.Name);
                                            }
                                            break;

                                        case SCREENSHOT_SLIDEVALUE:
                                            xReader.Read();
                                            screenshot.Slide.Value = xReader.Value;

                                            if (Log.DebugMode)
                                            {
                                                Log.Write("[" + screenshot.ViewId + "] Slide Value = " + screenshot.Slide.Value);
                                            }
                                            break;

                                        case SCREENSHOT_WINDOW_TITLE:
                                            xReader.Read();
                                            screenshot.WindowTitle = xReader.Value;

                                            if (Log.DebugMode)
                                            {
                                                Log.Write("[" + screenshot.ViewId + "] Window Title = " + screenshot.WindowTitle);
                                            }
                                            break;

                                        case SCREENSHOT_PROCESS_NAME:
                                            xReader.Read();
                                            screenshot.ProcessName = xReader.Value;

                                            if (Log.DebugMode)
                                            {
                                                Log.Write("[" + screenshot.ViewId + "] Process Name = " + screenshot.ProcessName);
                                            }
                                            break;

                                        case SCREENSHOT_LABEL:
                                            xReader.Read();
                                            screenshot.Label = xReader.Value;

                                            if (Log.DebugMode)
                                            {
                                                Log.Write("[" + screenshot.ViewId + "] Label = " + screenshot.Label);
                                            }
                                            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 \"" + FileSystem.ScreenshotsFile + "\"");
                        }

                        if (Settings.VersionManager.IsOldAppVersion(AppCodename, AppVersion))
                        {
                            Log.Write("Old application version discovered when loading \"" + FileSystem.ScreenshotsFile + "\"");

                            // 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.ScreenshotsFile);

                            Log.Write("Upgraded \"" + FileSystem.ScreenshotsFile + "\"");
                        }
                    }
                }

                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>
        ///
        /// </summary>
        /// <param name="keepScreenshotsForDays"></param>
        public void Save(int keepScreenshotsForDays)
        {
            try
            {
                _mutexWriteFile.WaitOne();

                lock (_screenshotList)
                {
                    if (_screenshotList != null && _screenshotList.Count > 0 && keepScreenshotsForDays > 0)
                    {
                        List <Screenshot> screenshotsToDelete = _screenshotList.Where(x => !string.IsNullOrEmpty(x.Date) && Convert.ToDateTime(x.Date) <= DateTime.Now.Date.AddDays(-keepScreenshotsForDays)).ToList();

                        if (screenshotsToDelete != null && screenshotsToDelete.Count > 0)
                        {
                            foreach (Screenshot screenshot in screenshotsToDelete)
                            {
                                XmlNodeList nodesToDelete = xDoc.SelectNodes(SCREENSHOT_XPATH + "[" + SCREENSHOT_DATE + "='" + screenshot.Date + "']");

                                foreach (XmlNode node in nodesToDelete)
                                {
                                    node.ParentNode.RemoveChild(node);
                                }

                                if (File.Exists(screenshot.Path))
                                {
                                    File.Delete(screenshot.Path);
                                }

                                _screenshotList.Remove(screenshot);
                            }
                        }
                    }

                    for (int i = 0; i < _screenshotList.Count; i++)
                    {
                        Screenshot screenshot = _screenshotList[i];

                        if (!screenshot.Saved && xDoc != null && screenshot?.Format != null && !string.IsNullOrEmpty(screenshot.Format.Name))
                        {
                            XmlElement xScreenshot = xDoc.CreateElement(XML_FILE_SCREENSHOT_NODE);

                            XmlElement xViedId = xDoc.CreateElement(SCREENSHOT_VIEWID);
                            xViedId.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;

                            xScreenshot.AppendChild(xViedId);
                            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);

                            XmlNode xScreenshots = xDoc.SelectSingleNode(SCREENSHOTS_XPATH);

                            if (xScreenshots != null)
                            {
                                if (xScreenshots.HasChildNodes)
                                {
                                    xScreenshots.InsertAfter(xScreenshot, xScreenshots.LastChild);
                                }
                                else
                                {
                                    xScreenshots.AppendChild(xScreenshot);
                                }

                                screenshot.Saved = true;

                                _screenshotList[i] = screenshot;
                            }
                        }
                    }

                    if (xDoc != null)
                    {
                        lock (xDoc)
                        {
                            xDoc.Save(FileSystem.ScreenshotsFile);
                        }
                    }
                }
            }
            finally
            {
                _mutexWriteFile.ReleaseMutex();
            }
        }
Example #3
0
        /// <summary>
        /// Saves the captured bitmap image as a screenshot to an image file.
        /// </summary>
        /// <param name="security">The security class.</param>
        /// <param name="jpegQuality">The JPEG quality setting for JPEG images being saved.</param>
        /// <param name="screenshot">The screenshot to save.</param>
        /// <param name="screenshotCollection">A collection of screenshot objects.</param>
        /// <returns>A boolean to determine if we successfully saved the screenshot.</returns>
        public int SaveScreenshot(Security security, int jpegQuality, Screenshot screenshot, ScreenshotCollection screenshotCollection)
        {
            int returnFlag = 0;

            try
            {
                int filepathLengthLimit = Convert.ToInt32(_config.Settings.Application.GetByKey("FilepathLengthLimit", _config.Settings.DefaultSettings.FilepathLengthLimit).Value);

                if (!string.IsNullOrEmpty(screenshot.FilePath))
                {
                    if (screenshot.FilePath.Length > filepathLengthLimit)
                    {
                        _log.WriteMessage($"File path length exceeds the configured length of {filepathLengthLimit} characters so value was truncated. Correct the value for the FilepathLengthLimit application setting to prevent truncation");
                        screenshot.FilePath = screenshot.FilePath.Substring(0, filepathLengthLimit);
                    }

                    // This is a normal path used in Windows (such as "C:\screenshots\").
                    if (!screenshot.FilePath.StartsWith(_fileSystem.PathDelimiter))
                    {
                        if (_fileSystem.DriveReady(screenshot.FilePath))
                        {
                            // The low disk mode we want to use (either check by percentage (0) or check the number of available bytes (1)).
                            int lowDiskMode = Convert.ToInt32(_config.Settings.Application.GetByKey("LowDiskMode", _config.Settings.DefaultSettings.LowDiskMode).Value);

                            // Low disk space threshold by percentage.
                            int    lowDiskPercentageThreshold = Convert.ToInt32(_config.Settings.Application.GetByKey("LowDiskPercentageThreshold", _config.Settings.DefaultSettings.LowDiskPercentageThreshold).Value);
                            double freeDiskSpacePercentage    = _fileSystem.FreeDiskSpacePercentage(screenshot.FilePath);

                            // Low disk space threshold in bytes.
                            long lowDiskBytesThreshold = Convert.ToInt64(_config.Settings.Application.GetByKey("LowDiskBytesThreshold", _config.Settings.DefaultSettings.LowDiskBytesThreshold).Value);
                            long freeDiskSpaceBytes    = _fileSystem.FreeDiskSpace(screenshot.FilePath);

                            _log.WriteDebugMessage("Percentage of free disk space on drive for \"" + screenshot.FilePath + "\" is " + (int)freeDiskSpacePercentage + "% and low disk percentage threshold is set to " + lowDiskPercentageThreshold + "%");
                            _log.WriteDebugMessage("Bytes of free disk space on drive for \"" + screenshot.FilePath + "\" is " + freeDiskSpaceBytes + " and low disk bytes threshold is set to " + lowDiskBytesThreshold);

                            // Check low disk space by percentage.
                            if (lowDiskMode == 0)
                            {
                                if (freeDiskSpacePercentage < lowDiskPercentageThreshold)
                                {
                                    return(NotEnoughDiskSpace(screenshot, returnFlag, freeDiskSpacePercentage, lowDiskPercentageThreshold, freeDiskSpaceBytes, lowDiskBytesThreshold));
                                }
                            }

                            // Check low disk space in bytes.
                            if (lowDiskMode == 1)
                            {
                                if (freeDiskSpaceBytes < lowDiskBytesThreshold)
                                {
                                    return(NotEnoughDiskSpace(screenshot, returnFlag, freeDiskSpacePercentage, lowDiskPercentageThreshold, freeDiskSpaceBytes, lowDiskBytesThreshold));
                                }
                            }

                            return(SaveToFile(security, jpegQuality, screenshot, screenshotCollection));
                        }
                        else
                        {
                            // Drive isn't ready so log an error message.
                            _log.WriteErrorMessage($"Unable to save screenshot for \"{screenshot.FilePath}\" because the drive is not found or not ready");

                            return(returnFlag | (int)ScreenSavingErrorLevels.DriveNotReady);
                        }
                    }
                    else
                    {
                        // This is a UNC network share path (such as "\\SERVER\screenshots\").
                        return(SaveToFile(security, jpegQuality, screenshot, screenshotCollection));
                    }
                }

                return(returnFlag & (int)ScreenSavingErrorLevels.None);
            }
            catch (PathTooLongException ex)
            {
                _log.WriteErrorMessage($"The path is too long. I see the path is \"{screenshot.FilePath}\" but the length exceeds what Windows can handle so the file could not be saved. There is probably an exception error from Windows explaining why");
                _log.WriteExceptionMessage("ScreenCapture::SaveScreenshot", ex);

                // This shouldn't be an error that should stop a screen capture session.
                return(returnFlag | (int)ScreenSavingErrorLevels.PathLengthExceeded);
            }
            catch (Exception ex)
            {
                _log.WriteExceptionMessage("ScreenCapture::SaveScreenshot", ex);

                return(returnFlag | (int)ScreenSavingErrorLevels.ExceptionCaught);
            }
        }