예제 #1
0
        /// <summary>
        /// Saves the captured bitmap image as a screenshot to an image file.
        /// </summary>
        /// <param name="path">The filepath of the image file to write to.</param>
        /// <param name="format">The format of the image file.</param>
        /// <param name="component">The component of the screenshot to be saved. This could be the active window or a screen.</param>
        /// <param name="screenshotType">The type of screenshot to save. This could be the active window, a region, or a screen.</param>
        /// <param name="jpegQuality">The JPEG quality setting for JPEG images being saved.</param>
        /// <param name="viewId">The unique identifier to identify a particular region or screen.</param>
        /// <param name="bitmap">The bitmap image to write to the image file.</param>
        /// <param name="label">The current label being used at the time of capture which we will apply to the screenshot object.</param>
        /// <param name="windowTitle">The title of the window being captured.</param>
        /// <param name="processName">The process name of the application being captured.</param>
        /// <param name="screenshotCollection">A collection of screenshot objects.</param>
        /// <returns>A boolean to determine if we successfully saved the screenshot.</returns>
        public bool SaveScreenshot(string path, ImageFormat format, int component, ScreenshotType screenshotType, int jpegQuality,
                                   Guid viewId, Bitmap bitmap, string label, string windowTitle, string processName, ScreenshotCollection screenshotCollection)
        {
            try
            {
                int  filepathLengthLimit   = Convert.ToInt32(Settings.Application.GetByKey("FilepathLengthLimit", DefaultSettings.FilepathLengthLimit).Value);
                bool optimizeScreenCapture = Convert.ToBoolean(Settings.Application.GetByKey("OptimizeScreenCapture", DefaultSettings.OptimizeScreenCapture).Value);

                if (!string.IsNullOrEmpty(path))
                {
                    if (path.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");
                        path = path.Substring(0, filepathLengthLimit);
                    }

                    Log.WriteMessage("Attempting to write image to file at path \"" + path + "\"");

                    // This is a normal path used in Windows (such as "C:\screenshots\").
                    if (!path.StartsWith(FileSystem.PathDelimiter))
                    {
                        if (FileSystem.DriveReady(path))
                        {
                            int    lowDiskSpacePercentageThreshold = Convert.ToInt32(Settings.Application.GetByKey("LowDiskPercentageThreshold", DefaultSettings.LowDiskPercentageThreshold).Value);
                            double freeDiskSpacePercentage         = FileSystem.FreeDiskSpacePercentage(path);

                            Log.WriteDebugMessage("Percentage of free disk space on drive for \"" + path + "\" is " + (int)freeDiskSpacePercentage + "% and low disk percentage threshold is set to " + lowDiskSpacePercentageThreshold + "%");

                            if (freeDiskSpacePercentage > lowDiskSpacePercentageThreshold)
                            {
                                string dirName = FileSystem.GetDirectoryName(path);

                                if (!string.IsNullOrEmpty(dirName))
                                {
                                    if (!FileSystem.DirectoryExists(dirName))
                                    {
                                        FileSystem.CreateDirectory(dirName);

                                        Log.WriteDebugMessage("Directory \"" + dirName + "\" did not exist so it was created");
                                    }

                                    Screenshot lastScreenshotOfThisView = screenshotCollection.GetLastScreenshotOfView(viewId);

                                    Screenshot newScreenshotOfThisView = new Screenshot(windowTitle, DateTimeScreenshotsTaken)
                                    {
                                        ViewId         = viewId,
                                        Path           = path,
                                        Format         = format,
                                        Component      = component,
                                        ScreenshotType = screenshotType,
                                        ProcessName    = processName + ".exe",
                                        Label          = label
                                    };

                                    if (optimizeScreenCapture)
                                    {
                                        newScreenshotOfThisView.Hash = GetMD5Hash(bitmap, format);

                                        if (lastScreenshotOfThisView == null || string.IsNullOrEmpty(lastScreenshotOfThisView.Hash) ||
                                            !lastScreenshotOfThisView.Hash.Equals(newScreenshotOfThisView.Hash))
                                        {
                                            screenshotCollection.Add(newScreenshotOfThisView);

                                            SaveToFile(path, format, jpegQuality, bitmap);
                                        }
                                    }
                                    else
                                    {
                                        screenshotCollection.Add(newScreenshotOfThisView);

                                        SaveToFile(path, format, jpegQuality, bitmap);
                                    }
                                }
                            }
                            else
                            {
                                // There is not enough disk space on the drive so log an error message and change the system tray icon's colour to yellow.
                                Log.WriteErrorMessage($"Unable to save screenshot due to lack of available disk space on drive for {path} (at " + freeDiskSpacePercentage + "%) which is lower than the LowDiskPercentageThreshold setting that is currently set to " + lowDiskSpacePercentageThreshold + "%");

                                bool stopOnLowDiskError = Convert.ToBoolean(Settings.Application.GetByKey("StopOnLowDiskError", DefaultSettings.StopOnLowDiskError).Value);

                                if (stopOnLowDiskError)
                                {
                                    Log.WriteErrorMessage("Running screen capture session has stopped because application setting StopOnLowDiskError was set to True when the available disk space on any drive was lower than the value of LowDiskPercentageThreshold");

                                    ApplicationError = true;

                                    return(false);
                                }

                                ApplicationWarning = true;
                            }
                        }
                        else
                        {
                            // Drive isn't ready so log an error message.
                            Log.WriteErrorMessage($"Unable to save screenshot for \"{path}\" because the drive is not found or not ready");
                        }
                    }
                    else
                    {
                        // This is UNC network share path (such as "\\SERVER\screenshots\").
                        string dirName = FileSystem.GetDirectoryName(path);

                        if (!string.IsNullOrEmpty(dirName))
                        {
                            try
                            {
                                if (!FileSystem.DirectoryExists(dirName))
                                {
                                    FileSystem.CreateDirectory(dirName);

                                    Log.WriteDebugMessage("Directory \"" + dirName + "\" did not exist so it was created");
                                }

                                Screenshot lastScreenshotOfThisView = screenshotCollection.GetLastScreenshotOfView(viewId);

                                Screenshot newScreenshotOfThisView = new Screenshot(windowTitle, DateTimeScreenshotsTaken)
                                {
                                    ViewId         = viewId,
                                    Path           = path,
                                    Format         = format,
                                    Component      = component,
                                    ScreenshotType = screenshotType,
                                    ProcessName    = processName + ".exe",
                                    Label          = label
                                };

                                if (optimizeScreenCapture)
                                {
                                    newScreenshotOfThisView.Hash = GetMD5Hash(bitmap, format);

                                    if (lastScreenshotOfThisView == null || string.IsNullOrEmpty(lastScreenshotOfThisView.Hash) ||
                                        !lastScreenshotOfThisView.Hash.Equals(newScreenshotOfThisView.Hash))
                                    {
                                        screenshotCollection.Add(newScreenshotOfThisView);

                                        SaveToFile(path, format, jpegQuality, bitmap);
                                    }
                                }
                                else
                                {
                                    screenshotCollection.Add(newScreenshotOfThisView);

                                    SaveToFile(path, format, jpegQuality, bitmap);
                                }
                            }
                            catch (Exception)
                            {
                                // We don't want to stop the screen capture session at this point because there may be other components that
                                // can write to their given paths. If this is a misconfigured path for a particular component then just log an error.
                                Log.WriteErrorMessage($"Cannot write to \"{path}\" because the user may not have the appropriate permissions to access the path");
                            }
                        }
                    }
                }

                return(true);
            }
            catch (System.IO.PathTooLongException ex)
            {
                Log.WriteErrorMessage($"The path is too long. I see the path is \"{path}\" 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(true);
            }
            catch (Exception ex)
            {
                Log.WriteExceptionMessage("ScreenCapture::SaveScreenshot", ex);

                return(false);
            }
        }
예제 #2
0
        /// <summary>
        /// Saves the captured bitmap image as a screenshot to an image file.
        /// </summary>
        /// <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 bool SaveScreenshot(int jpegQuality, Screenshot screenshot, ScreenshotCollection screenshotCollection)
        {
            try
            {
                int filepathLengthLimit = Convert.ToInt32(Settings.Application.GetByKey("FilepathLengthLimit", DefaultSettings.FilepathLengthLimit).Value);

                if (!string.IsNullOrEmpty(screenshot.Path))
                {
                    if (screenshot.Path.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.Path = screenshot.Path.Substring(0, filepathLengthLimit);
                    }

                    Log.WriteMessage("Attempting to write image to file at path \"" + screenshot.Path + "\"");

                    // This is a normal path used in Windows (such as "C:\screenshots\").
                    if (!screenshot.Path.StartsWith(FileSystem.PathDelimiter))
                    {
                        if (FileSystem.DriveReady(screenshot.Path))
                        {
                            int    lowDiskSpacePercentageThreshold = Convert.ToInt32(Settings.Application.GetByKey("LowDiskPercentageThreshold", DefaultSettings.LowDiskPercentageThreshold).Value);
                            double freeDiskSpacePercentage         = FileSystem.FreeDiskSpacePercentage(screenshot.Path);

                            Log.WriteDebugMessage("Percentage of free disk space on drive for \"" + screenshot.Path + "\" is " + (int)freeDiskSpacePercentage + "% and low disk percentage threshold is set to " + lowDiskSpacePercentageThreshold + "%");

                            if (freeDiskSpacePercentage > lowDiskSpacePercentageThreshold)
                            {
                                AddScreenshotAndSaveToFile(jpegQuality, screenshot, screenshotCollection);
                            }
                            else
                            {
                                // There is not enough disk space on the drive so log an error message and change the system tray icon's colour to yellow.
                                Log.WriteErrorMessage($"Unable to save screenshot due to lack of available disk space on drive for {screenshot.Path} (at " + freeDiskSpacePercentage + "%) which is lower than the LowDiskPercentageThreshold setting that is currently set to " + lowDiskSpacePercentageThreshold + "%");

                                bool stopOnLowDiskError = Convert.ToBoolean(Settings.Application.GetByKey("StopOnLowDiskError", DefaultSettings.StopOnLowDiskError).Value);

                                if (stopOnLowDiskError)
                                {
                                    Log.WriteErrorMessage("Running screen capture session has stopped because application setting StopOnLowDiskError was set to True when the available disk space on any drive was lower than the value of LowDiskPercentageThreshold");

                                    ApplicationError = true;

                                    return(false);
                                }

                                ApplicationWarning = true;
                            }
                        }
                        else
                        {
                            // Drive isn't ready so log an error message.
                            Log.WriteErrorMessage($"Unable to save screenshot for \"{screenshot.Path}\" because the drive is not found or not ready");
                        }
                    }
                    else
                    {
                        // This is a UNC network share path (such as "\\SERVER\screenshots\").
                        AddScreenshotAndSaveToFile(jpegQuality, screenshot, screenshotCollection);
                    }
                }

                return(true);
            }
            catch (System.IO.PathTooLongException ex)
            {
                Log.WriteErrorMessage($"The path is too long. I see the path is \"{screenshot.Path}\" 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(true);
            }
            catch (Exception ex)
            {
                Log.WriteExceptionMessage("ScreenCapture::SaveScreenshot", ex);

                return(false);
            }
        }
예제 #3
0
        /// <summary>
        /// Saves the captured bitmap image as a screenshot to an image file.
        /// </summary>
        /// <param name="path">The filepath of the image file to write to.</param>
        /// <param name="format">The format of the image file.</param>
        /// <param name="component">The component of the screenshot to be saved. This could be the active window or a screen.</param>
        /// <param name="screenshotType">The type of screenshot to save. This could be the active window, a region, or a screen.</param>
        /// <param name="jpegQuality">The JPEG quality setting for JPEG images being saved.</param>
        /// <param name="viewId">The unique identifier to identify a particular region or screen.</param>
        /// <param name="bitmap">The bitmap image to write to the image file.</param>
        /// <param name="label">The current label being used at the time of capture which we will apply to the screenshot object.</param>
        /// <param name="windowTitle">The title of the window being captured.</param>
        /// <param name="processName">The process name of the application being captured.</param>
        /// <param name="screenshotCollection">A collection of screenshot objects.</param>
        /// <returns>A boolean to determine if we successfully saved the screenshot.</returns>
        public bool SaveScreenshot(string path, ImageFormat format, int component, ScreenshotType screenshotType, int jpegQuality,
                                   Guid viewId, Bitmap bitmap, string label, string windowTitle, string processName, ScreenshotCollection screenshotCollection)
        {
            try
            {
                if (!string.IsNullOrEmpty(path) && path.Length >= MAX_WINDOWS_PATH_LENGTH)
                {
                    // We just want to log a normal message and not stop the screen capture session because we want to continue
                    // for other components that are using paths which are still valid.
                    Log.WriteMessage($"No path available at \"{path}\" or path length exceeds {MAX_WINDOWS_PATH_LENGTH} characters");
                }

                if (!string.IsNullOrEmpty(path) && path.Length < MAX_WINDOWS_PATH_LENGTH)
                {
                    Log.WriteDebugMessage("Attempting to write image to file at path \"" + path + "\"");

                    // This is a normal path used in Windows (such as "C:\screenshots\").
                    if (!path.StartsWith(FileSystem.PathDelimiter))
                    {
                        if (FileSystem.DriveReady(path))
                        {
                            int    lowDiskSpacePercentageThreshold = Convert.ToInt32(Settings.Application.GetByKey("LowDiskPercentageThreshold", defaultValue: 1).Value);
                            double freeDiskSpacePercentage         = FileSystem.FreeDiskSpacePercentage(path);

                            Log.WriteDebugMessage("Percentage of free disk space on drive for \"" + path + "\" is " + (int)freeDiskSpacePercentage + "% and low disk percentage threshold is set to " + lowDiskSpacePercentageThreshold + "%");

                            if (freeDiskSpacePercentage > lowDiskSpacePercentageThreshold)
                            {
                                string dirName = FileSystem.GetDirectoryName(path);

                                if (!string.IsNullOrEmpty(dirName))
                                {
                                    if (!FileSystem.DirectoryExists(dirName))
                                    {
                                        FileSystem.CreateDirectory(dirName);

                                        Log.WriteDebugMessage("Directory \"" + dirName + "\" did not exist so it was created");
                                    }

                                    Screenshot screenshot = new Screenshot(DateTimeScreenshotsTaken, path, format, component, screenshotType, windowTitle, processName, viewId, label);

                                    screenshotCollection.Add(screenshot);

                                    SaveToFile(path, format, jpegQuality, bitmap);
                                }
                            }
                            else
                            {
                                // There is not enough disk space on the drive so stop the current running screen capture session and log an error message.
                                Log.WriteErrorMessage($"Unable to save screenshot due to lack of available disk space on drive for {path} (at " + freeDiskSpacePercentage + "%) which is lower than the LowDiskPercentageThreshold setting that is currently set to " + lowDiskSpacePercentageThreshold + "% so screen capture session is being stopped");

                                return(false);
                            }
                        }
                        else
                        {
                            // Drive isn't ready so log an error message.
                            Log.WriteErrorMessage($"Unable to save screenshot for \"{path}\" because the drive is not found or not ready");
                        }
                    }
                    else
                    {
                        // This is UNC network share path (such as "\\SERVER\screenshots\").
                        string dirName = FileSystem.GetDirectoryName(path);

                        if (!string.IsNullOrEmpty(dirName))
                        {
                            try
                            {
                                if (!FileSystem.DirectoryExists(dirName))
                                {
                                    FileSystem.CreateDirectory(dirName);

                                    Log.WriteDebugMessage("Directory \"" + dirName + "\" did not exist so it was created");
                                }

                                screenshotCollection.Add(new Screenshot(DateTimeScreenshotsTaken, path, format, component, screenshotType, windowTitle, processName, viewId, label));

                                SaveToFile(path, format, jpegQuality, bitmap);
                            }
                            catch (Exception)
                            {
                                // We don't want to stop the screen capture session at this point because there may be other components that
                                // can write to their given paths. If this is a misconfigured path for a particular component then just log an error.
                                Log.WriteErrorMessage($"Cannot write to \"{path}\" because the user may not have the appropriate permissions to access the path");
                            }
                        }
                    }
                }

                return(true);
            }
            catch (Exception ex)
            {
                Log.WriteExceptionMessage("ScreenCapture::SaveScreenshot", ex);

                return(false);
            }
        }
예제 #4
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);
            }
        }