Skip to content

Commit 3e15503

Browse files
committed
2.4.1.9 - Screenshots that fail to upload to an SFTP server will try to upload to the same SFTP server in the next capture cycle until the upload is successful.
1 parent 0ef886d commit 3e15503

File tree

6 files changed

+116
-22
lines changed

6 files changed

+116
-22
lines changed

ScreenCapture.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -720,10 +720,14 @@ public Bitmap GetActiveWindowBitmap(int resolutionRatio, bool mouse)
720720
int width = rect.Width - rect.X;
721721
int height = rect.Height - rect.Y;
722722

723-
_log.WriteDebugMessage($"Attempting to capture active window image using width={width}, height={height}, resolutionRatio={resolutionRatio}, mouse={mouse}");
724-
725723
if (width > 0 && height > 0)
726724
{
725+
// We don't need to log this message if the resolution ratio is 0 since if it is 0 then it's most likely a test of the screen capture method.
726+
if (resolutionRatio > 0)
727+
{
728+
_log.WriteDebugMessage($"Attempting to capture active window image using width={width}, height={height}, resolutionRatio={resolutionRatio}, mouse={mouse}");
729+
}
730+
727731
if (resolutionRatio < IMAGE_RESOLUTION_RATIO_MIN || resolutionRatio > IMAGE_RESOLUTION_RATIO_MAX)
728732
{
729733
resolutionRatio = 100;

changelog.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Auto Screen Capture by Gavin Kendall
22

33

4-
2.4.1.9 Screenshots count is reset when screenshots limit is reached to avoid falling into an infinite loop. New trigger actions Restart Screen Capture, Delete Screenshots By Cycle Count, and Delete Screenshots From Oldest Capture Cycle. New command "-restart". New macro tag "%capturenow%".
4+
2.4.1.9 Screenshots count is reset when screenshots limit is reached to avoid falling into an infinite loop. New trigger actions Restart Screen Capture, Delete Screenshots By Cycle Count, and Delete Screenshots From Oldest Capture Cycle. New command "-restart". New macro tag "%capturenow%". Screenshots that fail to upload to an SFTP server will try to upload to the same SFTP server in the next capture cycle until the upload is successful.
55
2.4.1.8 Delete Screenshots trigger uses ScreenshotsFolder instead of DefaultScreenshotsFolder. Sending a test email from Email Settings logs any exception error and the Send Test Email button is enabled again after an exception has been caught. Email Settings form accepts multiple email addresses in TO, CC, and BCC fields using either ; or , as a separator.
66
2.4.1.7 Hash included in Screenshot Metadata. Additional debug logging has been included in the screen capture methods.
77
2.4.1.6 $AppDataLocal$ and $AppDataRoaming$ introduced for autoscreen.conf and autoscreen.conf included as part of installation so that an installation of the application can run under normal user privileges without needing to run autoscreen.exe as Administrator from "C:\Program Files" or "C:\Program Files (x86)" since the data files are being written to the user's local or roaming app data folder (AppData\Local by default).

help/help-2.rtf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7699,7 +7699,7 @@ ad7bbdad7bbda57bbda57bbda57b000000040000002701ffff030000000000
76997699
I love the Blade movies and I don't care what anyone says but the music in the "Bloodbath" nightclub scene of the first movie is still cool.\par
77007700
The biggest feature implemented in 2.4 was the ability to encrypt and decrypt screenshots. The interface was cleaned up and more user-friendly notes were included. This version introduces the "Auto Adapt" feature for screens so that the position and size of each screen is automatically adjusted based on changes made to the display setup.\par
77017701
Here's every change in the 2.4 "Blade" series (starting with the most recent change):\par
7702-
\cf1\f1\fs19\lang1033 2.4.1.9 Screenshots count is reset when screenshots limit is reached to avoid falling into an infinite loop. New trigger actions Restart Screen Capture, \f2 Delete Screenshots By Cycle Count, and Delete Screenshots From Oldest Capture Cycle\f1 . New command "-restart". \f2 New macro tag "%capturenow%".\f1\par
7702+
\cf1\f1\fs19\lang1033 2.4.1.9 Screenshots count is reset when screenshots limit is reached to avoid falling into an infinite loop. New trigger actions Restart Screen Capture, \f2 Delete Screenshots By Cycle Count, and Delete Screenshots From Oldest Capture Cycle\f1 . New command "-restart". \f2 New macro tag "%capturenow%".\f1 \f2 Screenshots that fail to upload to an SFTP server will try to upload to the same SFTP server \f1 in the next capture cycle\f2 \f1 until\f2 \f1 the upload is successful.\par
77037703
2.4.1.8 \f2 Delete Screenshots trigger uses ScreenshotsFolder instead of DefaultScreenshotsFolder. Sending a test email from Email Settings logs any exception error and the Send Test Email button is enabled again after an exception has been caught. Email Settings form accepts multiple email addresses in TO, CC, and BCC fields using either ; or , as a separator.\f1\par
77047704
2.4.1.7 \f2 Hash included in Screenshot Metadata. Additional debug logging has been included in the screen capture methods.\f1\lang9\par
77057705
2.4.1.6 $AppDataLocal$ and $AppDataRoaming$ introduced for autoscreen.conf and autoscreen.conf included as part \lang1033 of \f2\lang9 installation so that an installation of the application can run under normal user privileges without needing to run autoscreen.exe as Administrator from "C:\\Program Files" or "C:\\Program Files (x86)" since the data files are being written to the user's local or roaming app data folder\f1\lang1033 (AppData\\Local by default)\f2\lang9 .\par

interface/main/FormMain-ScreenCapture.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ private bool SaveScreenshot(Bitmap bitmap, object screenOrRegion)
425425
/// </summary>
426426
private void ScreenshotTakenWithSuccess()
427427
{
428-
_log.WriteDebugMessage("Running triggers of condition type ScreenshotTaken");
428+
_log.WriteDebugMessage("Running triggers of condition type AfterScreenshotTaken");
429429

430430
RunTriggersOfConditionType(TriggerConditionType.AfterScreenshotTaken);
431431
}

interface/main/FormMain-Screenshots.cs

Lines changed: 106 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,20 @@
1919
// along with this program. If not, see <https://www.gnu.org/licenses/>.
2020
//-----------------------------------------------------------------------
2121
using System;
22+
using System.Collections.Generic;
2223
using System.ComponentModel;
2324
using System.Diagnostics;
2425
using System.Drawing;
26+
using System.IO;
2527
using System.Windows.Forms;
2628

2729
namespace AutoScreenCapture
2830
{
2931
public partial class FormMain : Form
3032
{
33+
// A dictionary of failed uploads containing filepaths and hosts.
34+
private Dictionary<string, string> _failedUploads = new Dictionary<string, string>();
35+
3136
/// <summary>
3237
/// Saves screenshot references every five minutes (300000 milliseconds).
3338
/// </summary>
@@ -908,7 +913,7 @@ private bool EmailScreenshot(Screenshot screenshot, bool prompt)
908913
}
909914
else
910915
{
911-
_log.WriteDebugMessage("Password = [I'm not going to log this so check the application settings file]");
916+
_log.WriteDebugMessage("Password = [I'm not revealing this here]");
912917
}
913918

914919
string from = Settings.SMTP.GetByKey("EmailMessageFrom", _config.Settings.DefaultSettings.EmailMessageFrom).Value.ToString();
@@ -1090,7 +1095,7 @@ private bool FileTransferScreenshot(Screenshot screenshot)
10901095
}
10911096
else
10921097
{
1093-
_log.WriteDebugMessage("Password = [I'm not going to log this so check the user settings file]");
1098+
_log.WriteDebugMessage("Password = [I'm not revealing this here]");
10941099
}
10951100

10961101
if (string.IsNullOrEmpty(host) ||
@@ -1119,43 +1124,121 @@ private bool FileTransferScreenshot(Screenshot screenshot)
11191124
{
11201125
_log.WriteDebugMessage("Could not establish a connection with the file server");
11211126

1127+
// Add the screenshot filepath and host to a dictionary of failed uploads so we'll attempt to upload the screenshot for that host later.
1128+
if (!_failedUploads.ContainsKey(screenshot.Path))
1129+
{
1130+
_log.WriteDebugMessage($"Screenshot ({screenshot.Path}) has been added to the dictionary of failed uploads because a connection to the file server could not be established at this time so an attempt to retry the upload will occur in the next capture cycle");
1131+
1132+
_failedUploads.Add(screenshot.Path, host);
1133+
}
1134+
11221135
return false;
11231136
}
11241137
}
11251138

11261139
// Make sure we are connected to the file server. If we were not connected earlier then a connection request would have been sent prior to this check.
11271140
if (_sftpClient.IsConnected)
11281141
{
1129-
string destinationPath = System.IO.Path.GetFileName(screenshot.Path);
1130-
1131-
_log.WriteDebugMessage("Attempting to upload screenshot to file server");
1132-
_log.WriteDebugMessage("Source: " + screenshot.Path);
1133-
_log.WriteDebugMessage("Destination: " + destinationPath);
1142+
// This is necessary since we are going to be removing entries from the _failedUploads dictionary while enumerating the collection
1143+
// so instead of modifying the collection that we're enumerating it's better to simply enumerate over a copy of the filepaths.
1144+
string[] pathsOfFailedUploads = new string[_failedUploads.Count];
1145+
_failedUploads.Keys.CopyTo(pathsOfFailedUploads, 0);
11341146

1135-
if (_sftpClient.UploadFile(screenshot.Path, destinationPath))
1136-
{
1137-
_log.WriteDebugMessage("Successfully uploaded screenshot");
1138-
}
1139-
else
1147+
foreach (string path in pathsOfFailedUploads)
11401148
{
1141-
_log.WriteDebugMessage("Failed to upload screenshot");
1149+
if (_failedUploads.ContainsKey(path))
1150+
{
1151+
if (_failedUploads.TryGetValue(path, out string hostAssociatedWithPath))
1152+
{
1153+
_log.WriteDebugMessage($"Screenshot ({path}) was found in dictionary of failed uploads");
11421154

1143-
return false;
1155+
// Make sure that the host associated with the path is equal to the host we're currently handling
1156+
// so we don't accidentally upload the screenshot to the wrong SFTP server just in case the user changes hosts.
1157+
if (hostAssociatedWithPath.Equals(host))
1158+
{
1159+
if (UploadScreenshot(host, path))
1160+
{
1161+
_log.WriteDebugMessage($"This screenshot previously failed to upload. It has now been successfully uploaded to {host}");
1162+
}
1163+
}
1164+
else
1165+
{
1166+
_log.WriteDebugMessage($"This screenshot previously failed to upload. It could not be uploaded to {host} at the moment because the screenshot is intended for {hostAssociatedWithPath}");
1167+
}
1168+
}
1169+
}
11441170
}
1171+
1172+
// Upload the screenshot we're currently handling.
1173+
return UploadScreenshot(host, screenshot.Path);
11451174
}
11461175

1147-
return true;
1176+
return false;
11481177
}
11491178
catch (Exception ex)
11501179
{
11511180
_screenCapture.ApplicationError = true;
11521181

11531182
_log.WriteExceptionMessage("FormMain-Screenshots::FileTransferScreenshot", ex);
11541183

1184+
// We can't simply say that the SFTP client is now disconnected so we just need to nullify the SFTP client.
1185+
_sftpClient = null;
1186+
1187+
return false;
1188+
}
1189+
}
1190+
1191+
/// <summary>
1192+
/// Uploads a screenshot image file to the SFTP server given the provided local path of the screenshot.
1193+
/// </summary>
1194+
/// <param name="host">The hostname for the SFTP server.</param>
1195+
/// <param name="path">The filepath of the screenshot.</param>
1196+
/// <returns>True if the upload was successful. False if the upload failed.</returns>
1197+
private bool UploadScreenshot(string host, string path)
1198+
{
1199+
string destinationPath = Path.GetFileName(path);
1200+
1201+
_log.WriteDebugMessage("Attempting to upload screenshot to file server");
1202+
_log.WriteDebugMessage("Source: " + path);
1203+
_log.WriteDebugMessage("Destination: " + destinationPath);
1204+
1205+
if (_sftpClient.UploadFile(path, destinationPath))
1206+
{
1207+
_log.WriteDebugMessage("Successfully uploaded screenshot");
1208+
1209+
// Remove the path from the dictionary of failed uploads if we were successful in uploading the file to the SFTP server.
1210+
if (_failedUploads.ContainsKey(path))
1211+
{
1212+
_log.WriteDebugMessage($"Screenshot ({path}) has been removed from the dictionary of failed uploads because the upload was successful");
1213+
1214+
_failedUploads.Remove(path);
1215+
}
1216+
}
1217+
else
1218+
{
1219+
_log.WriteDebugMessage("Failed to upload screenshot");
1220+
1221+
// Add the screenshot filepath and host to a dictionary of failed uploads so we'll attempt to upload the screenshot later.
1222+
if (!_failedUploads.ContainsKey(path))
1223+
{
1224+
_log.WriteDebugMessage($"Screenshot ({path}) has been added to the dictionary of failed uploads because the upload failed at this time so an attempt to retry the upload will occur in the next capture cycle");
1225+
1226+
_failedUploads.Add(path, host);
1227+
}
1228+
1229+
// We can't simply say that the SFTP client is now disconnected so we just need to nullify the SFTP client.
1230+
_sftpClient = null;
1231+
11551232
return false;
11561233
}
1234+
1235+
return true;
11571236
}
11581237

1238+
/// <summary>
1239+
/// Uploads a screenshot to an SFTP server based on a trigger action type.
1240+
/// </summary>
1241+
/// <param name="triggerActionType">The trigger action type to use.</param>
11591242
private void FileTransferScreenshot(TriggerActionType triggerActionType)
11601243
{
11611244
if (triggerActionType == TriggerActionType.FileTransferScreenshot && _screenCapture.Running)
@@ -1164,7 +1247,14 @@ private void FileTransferScreenshot(TriggerActionType triggerActionType)
11641247

11651248
if (lastScreenshotOfThisView != null && lastScreenshotOfThisView.Slide != null && !string.IsNullOrEmpty(lastScreenshotOfThisView.Path))
11661249
{
1167-
FileTransferScreenshot(lastScreenshotOfThisView);
1250+
if (FileTransferScreenshot(lastScreenshotOfThisView))
1251+
{
1252+
_log.WriteDebugMessage($"The screenshot ({lastScreenshotOfThisView.Path}) was successfully uploaded");
1253+
}
1254+
else
1255+
{
1256+
_log.WriteDebugMessage($"The screenshot ({lastScreenshotOfThisView.Path}) failed to upload");
1257+
}
11681258
}
11691259
}
11701260
}

interface/trigger/FormTrigger.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -999,7 +999,7 @@ private void ShowActionHelpText()
999999

10001000
// DeleteScreenshotsFromOldestCaptureCycle
10011001
case 36:
1002-
textBoxActionHelp.Text = "Delete screenshots from the oldest capture cycle. You can use this action to perform a rolling delete if you also set the Limit (in Setup) and use the Limit Reached condition. Run a screen capture session for a while first to define the required set of cycles and then trigger this action to start doing the rolling delete.";
1002+
textBoxActionHelp.Text = "Delete screenshots from the oldest capture cycle. You can use this action to perform a rolling delete if you also use the After Screenshot Taken condition. Run a screen capture session for a while first to define the required set of cycles and then trigger this action to start doing the rolling delete.";
10031003
break;
10041004
}
10051005
}

0 commit comments

Comments
 (0)