/// <summary> /// Saves the tags. /// </summary> public void SaveToXmlFile() { try { XmlWriterSettings xSettings = new XmlWriterSettings(); xSettings.Indent = true; xSettings.CloseOutput = true; xSettings.CheckCharacters = true; xSettings.Encoding = Encoding.UTF8; xSettings.NewLineChars = Environment.NewLine; xSettings.IndentChars = XML_FILE_INDENT_CHARS; xSettings.NewLineHandling = NewLineHandling.Entitize; xSettings.ConformanceLevel = ConformanceLevel.Document; if (string.IsNullOrEmpty(FileSystem.TagsFile)) { FileSystem.TagsFile = FileSystem.DefaultTagsFile; if (FileSystem.FileExists(FileSystem.ConfigFile)) { FileSystem.AppendToFile(FileSystem.ConfigFile, "\nTagsFile=" + FileSystem.TagsFile); } } if (FileSystem.FileExists(FileSystem.TagsFile)) { FileSystem.DeleteFile(FileSystem.TagsFile); } using (XmlWriter xWriter = XmlWriter.Create(FileSystem.TagsFile, 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_TAGS_NODE); foreach (Tag tag in base.Collection) { xWriter.WriteStartElement(XML_FILE_TAG_NODE); xWriter.WriteElementString(TAG_ACTIVE, tag.Active.ToString()); xWriter.WriteElementString(TAG_NAME, tag.Name); xWriter.WriteElementString(TAG_DESCRIPTION, tag.Description); xWriter.WriteElementString(TAG_NOTES, tag.Notes); xWriter.WriteElementString(TAG_TYPE, tag.Type.ToString()); xWriter.WriteElementString(TAG_DATETIME_FORMAT_VALUE, tag.DateTimeFormatValue); xWriter.WriteElementString(TAG_TIME_OF_DAY_MORNING_START, tag.TimeOfDayMorningStart.ToString()); xWriter.WriteElementString(TAG_TIME_OF_DAY_MORNING_END, tag.TimeOfDayMorningEnd.ToString()); xWriter.WriteElementString(TAG_TIME_OF_DAY_AFTERNOON_START, tag.TimeOfDayAfternoonStart.ToString()); xWriter.WriteElementString(TAG_TIME_OF_DAY_AFTERNOON_END, tag.TimeOfDayAfternoonEnd.ToString()); xWriter.WriteElementString(TAG_TIME_OF_DAY_EVENING_START, tag.TimeOfDayEveningStart.ToString()); xWriter.WriteElementString(TAG_TIME_OF_DAY_EVENING_END, tag.TimeOfDayEveningEnd.ToString()); xWriter.WriteElementString(TAG_TIME_OF_DAY_MORNING_VALUE, tag.TimeOfDayMorningValue); xWriter.WriteElementString(TAG_TIME_OF_DAY_AFTERNOON_VALUE, tag.TimeOfDayAfternoonValue); xWriter.WriteElementString(TAG_TIME_OF_DAY_EVENING_VALUE, tag.TimeOfDayEveningValue); xWriter.WriteElementString(TAG_TIME_OF_DAY_EVENING_EXTENDS_TO_NEXT_MORNING, tag.EveningExtendsToNextMorning.ToString()); xWriter.WriteEndElement(); } xWriter.WriteEndElement(); xWriter.WriteEndElement(); xWriter.WriteEndDocument(); xWriter.Flush(); xWriter.Close(); } } catch (Exception ex) { Log.WriteExceptionMessage("TagCollection::SaveToXmlFile", ex); } }
/// <summary> /// Loads the image schedules from the schedules.xml file. /// </summary> public bool LoadXmlFileAndAddSchedules() { try { if (FileSystem.FileExists(FileSystem.SchedulesFile)) { Log.WriteDebugMessage("Schedules file \"" + FileSystem.SchedulesFile + "\" found. Attempting to load XML document"); XmlDocument xDoc = new XmlDocument(); xDoc.Load(FileSystem.SchedulesFile); Log.WriteDebugMessage("XML document loaded"); AppVersion = xDoc.SelectSingleNode("/autoscreen").Attributes["app:version"]?.Value; AppCodename = xDoc.SelectSingleNode("/autoscreen").Attributes["app:codename"]?.Value; XmlNodeList xSchedules = xDoc.SelectNodes(SCHEDULE_XPATH); foreach (XmlNode xSchedule in xSchedules) { Schedule schedule = new Schedule(); XmlNodeReader xReader = new XmlNodeReader(xSchedule); while (xReader.Read()) { if (xReader.IsStartElement() && !xReader.IsEmptyElement) { switch (xReader.Name) { case SCHEDULE_NAME: xReader.Read(); schedule.Name = xReader.Value; break; case SCHEDULE_ACTIVE: xReader.Read(); schedule.Active = Convert.ToBoolean(xReader.Value); break; case SCHEDULE_MODE_ONETIME: xReader.Read(); schedule.ModeOneTime = Convert.ToBoolean(xReader.Value); break; case SCHEDULE_MODE_PERIOD: xReader.Read(); schedule.ModePeriod = Convert.ToBoolean(xReader.Value); break; case SCHEDULE_CAPTUREAT: xReader.Read(); schedule.CaptureAt = Convert.ToDateTime(xReader.Value); break; case SCHEDULE_STARTAT: xReader.Read(); schedule.StartAt = Convert.ToDateTime(xReader.Value); break; case SCHEDULE_STOPAT: xReader.Read(); schedule.StopAt = Convert.ToDateTime(xReader.Value); break; case SCHEDULE_MONDAY: xReader.Read(); schedule.Monday = Convert.ToBoolean(xReader.Value); break; case SCHEDULE_TUESDAY: xReader.Read(); schedule.Tuesday = Convert.ToBoolean(xReader.Value); break; case SCHEDULE_WEDNESDAY: xReader.Read(); schedule.Wednesday = Convert.ToBoolean(xReader.Value); break; case SCHEDULE_THURSDAY: xReader.Read(); schedule.Thursday = Convert.ToBoolean(xReader.Value); break; case SCHEDULE_FRIDAY: xReader.Read(); schedule.Friday = Convert.ToBoolean(xReader.Value); break; case SCHEDULE_SATURDAY: xReader.Read(); schedule.Saturday = Convert.ToBoolean(xReader.Value); break; case SCHEDULE_SUNDAY: xReader.Read(); schedule.Sunday = Convert.ToBoolean(xReader.Value); break; case SCHEDULE_NOTES: xReader.Read(); schedule.Notes = xReader.Value; break; } } } xReader.Close(); // Change the data for each Schedule that's being loaded if we've detected that // the XML document is from an older version of the application. if (Settings.VersionManager.IsOldAppVersion(AppCodename, AppVersion)) { Log.WriteDebugMessage("An old version of the schedules.xml file was detected. Attempting upgrade to new schema."); Version v2300 = Settings.VersionManager.Versions.Get("Boombayah", "2.3.0.0"); Version configVersion = Settings.VersionManager.Versions.Get(AppCodename, AppVersion); if (v2300 != null && configVersion != null && configVersion.VersionNumber < v2300.VersionNumber) { Log.WriteDebugMessage("Dalek 2.2.4.6 or older detected"); // This is a new property for Schedule that was introduced in 2.3.0.0 // so any version before 2.3.0.0 needs to have it during an upgrade. schedule.Active = true; } } if (!string.IsNullOrEmpty(schedule.Name)) { Add(schedule); } } if (Settings.VersionManager.IsOldAppVersion(AppCodename, AppVersion)) { Log.WriteDebugMessage("Schedules file detected as an old version"); SaveToXmlFile(); } } else { Log.WriteDebugMessage("WARNING: Unable to load schedules"); // If we can't find the schedules.xml file we'll need to have a "Special Schedule" schedule created to be compatible with old commands like -startat and -stopat. Log.WriteDebugMessage("Creating default Special Schedule for use with command line arguments such as -startat and -stopat"); DateTime dtNow = DateTime.Now; Schedule specialSchedule = new Schedule() { Name = SpecialScheduleName, Active = false, ModeOneTime = true, ModePeriod = false, CaptureAt = dtNow, StartAt = dtNow, StopAt = dtNow, Notes = "This schedule is used for the command line arguments -captureat, -startat, and -stopat." }; if (Settings.VersionManager != null && Settings.VersionManager.OldUserSettings != null) { // If we're importing the schedule settings from a previous version of Auto Screen Capture we'll need to update the "Special Schedule" and enable it. SettingCollection oldUserSettings = Settings.VersionManager.OldUserSettings; bool captureStartAt = Convert.ToBoolean(oldUserSettings.GetByKey("BoolCaptureStartAt", DefaultSettings.BoolCaptureStartAt).Value); bool captureStopAt = Convert.ToBoolean(oldUserSettings.GetByKey("BoolCaptureStopAt", DefaultSettings.BoolCaptureStopAt).Value); DateTime dtStartAt = Convert.ToDateTime(oldUserSettings.GetByKey("DateTimeCaptureStartAt", DefaultSettings.DateTimeCaptureStartAt).Value); DateTime dtStopAt = Convert.ToDateTime(oldUserSettings.GetByKey("DateTimeCaptureStopAt", DefaultSettings.DateTimeCaptureStopAt).Value); // Days bool captureOnTheseDays = Convert.ToBoolean(oldUserSettings.GetByKey("BoolCaptureOnTheseDays", DefaultSettings.BoolCaptureOnTheseDays).Value); bool sunday = Convert.ToBoolean(oldUserSettings.GetByKey("BoolCaptureOnSunday", DefaultSettings.BoolCaptureOnSunday).Value); bool monday = Convert.ToBoolean(oldUserSettings.GetByKey("BoolCaptureOnMonday", DefaultSettings.BoolCaptureOnMonday).Value); bool tuesday = Convert.ToBoolean(oldUserSettings.GetByKey("BoolCaptureOnTuesday", DefaultSettings.BoolCaptureOnTuesday).Value); bool wednesday = Convert.ToBoolean(oldUserSettings.GetByKey("BoolCaptureOnWednesday", DefaultSettings.BoolCaptureOnWednesday).Value); bool thursday = Convert.ToBoolean(oldUserSettings.GetByKey("BoolCaptureOnThursday", DefaultSettings.BoolCaptureOnThursday).Value); bool friday = Convert.ToBoolean(oldUserSettings.GetByKey("BoolCaptureOnFriday", DefaultSettings.BoolCaptureOnFriday).Value); bool saturday = Convert.ToBoolean(oldUserSettings.GetByKey("BoolCaptureOnSaturday", DefaultSettings.BoolCaptureOnSaturday).Value); specialSchedule.ModeOneTime = false; specialSchedule.ModePeriod = true; if (captureStartAt) { specialSchedule.Active = true; specialSchedule.StartAt = dtStartAt; } if (captureStopAt) { specialSchedule.Active = true; specialSchedule.StopAt = dtStopAt; } if (captureOnTheseDays) { specialSchedule.Sunday = sunday; specialSchedule.Monday = monday; specialSchedule.Tuesday = tuesday; specialSchedule.Wednesday = wednesday; specialSchedule.Thursday = thursday; specialSchedule.Friday = friday; specialSchedule.Saturday = saturday; } specialSchedule.Notes += " Your schedule from a previous version of the application has been imported."; } Add(specialSchedule); SaveToXmlFile(); } return(true); } catch (Exception ex) { Log.WriteExceptionMessage("ScheduleCollection::LoadXmlFileAndAddSchedules", ex); return(false); } }
/// <summary> /// Loads the tags. /// </summary> public void LoadXmlFileAndAddTags() { try { Log.WriteDebugMessage(":: LoadXmlFileAndAddTags Start ::"); if (FileSystem.FileExists(FileSystem.TagsFile)) { Log.WriteDebugMessage("Tags file \"" + FileSystem.TagsFile + "\" found. Attempting to load XML document"); XmlDocument xDoc = new XmlDocument(); xDoc.Load(FileSystem.TagsFile); Log.WriteDebugMessage("XML document loaded"); AppVersion = xDoc.SelectSingleNode("/autoscreen").Attributes["app:version"]?.Value; AppCodename = xDoc.SelectSingleNode("/autoscreen").Attributes["app:codename"]?.Value; XmlNodeList xTags = xDoc.SelectNodes(TAG_XPATH); foreach (XmlNode xTag in xTags) { Tag tag = new Tag(); XmlNodeReader xReader = new XmlNodeReader(xTag); while (xReader.Read()) { if (xReader.IsStartElement() && !xReader.IsEmptyElement) { switch (xReader.Name) { case TAG_NAME: xReader.Read(); tag.Name = xReader.Value; if (!tag.Name.StartsWith("%")) { tag.Name = "%" + tag.Name; } if (!tag.Name.EndsWith("%")) { tag.Name += "%"; } break; case TAG_DESCRIPTION: xReader.Read(); tag.Description = xReader.Value; break; case TAG_NOTES: xReader.Read(); tag.Notes = xReader.Value; break; case TAG_TYPE: xReader.Read(); string value = xReader.Value; // Change the data for each Tag that's being loaded if we've detected that // the XML document is from an older version of the application. if (Settings.VersionManager.IsOldAppVersion(AppCodename, AppVersion)) { Log.WriteDebugMessage("An old version of the tags.xml file was detected. Attempting upgrade to new schema."); Version v2300 = Settings.VersionManager.Versions.Get("Boombayah", "2.3.0.0"); Version configVersion = Settings.VersionManager.Versions.Get(AppCodename, AppVersion); if (v2300 != null && configVersion != null && configVersion.VersionNumber < v2300.VersionNumber) { Log.WriteDebugMessage("Dalek 2.2.4.6 or older detected"); // Starting with 2.3.0.0 the DateTimeFormatFunction type became the DateTimeFormatExpression type. value = value.Replace("DateTimeFormatFunction", "DateTimeFormatExpression"); } } tag.Type = (TagType)Enum.Parse(typeof(TagType), value); break; case TAG_DATETIME_FORMAT_VALUE: xReader.Read(); tag.DateTimeFormatValue = xReader.Value; break; case TAG_TIME_OF_DAY_MORNING_START: xReader.Read(); tag.TimeOfDayMorningStart = Convert.ToDateTime(xReader.Value); break; case TAG_TIME_OF_DAY_MORNING_END: xReader.Read(); tag.TimeOfDayMorningEnd = Convert.ToDateTime(xReader.Value); break; case TAG_TIME_OF_DAY_AFTERNOON_START: xReader.Read(); tag.TimeOfDayAfternoonStart = Convert.ToDateTime(xReader.Value); break; case TAG_TIME_OF_DAY_AFTERNOON_END: xReader.Read(); tag.TimeOfDayAfternoonEnd = Convert.ToDateTime(xReader.Value); break; case TAG_TIME_OF_DAY_EVENING_START: xReader.Read(); tag.TimeOfDayEveningStart = Convert.ToDateTime(xReader.Value); break; case TAG_TIME_OF_DAY_EVENING_END: xReader.Read(); tag.TimeOfDayEveningEnd = Convert.ToDateTime(xReader.Value); break; case TAG_TIME_OF_DAY_MORNING_VALUE: xReader.Read(); tag.TimeOfDayMorningValue = xReader.Value; break; case TAG_TIME_OF_DAY_AFTERNOON_VALUE: xReader.Read(); tag.TimeOfDayAfternoonValue = xReader.Value; break; case TAG_TIME_OF_DAY_EVENING_VALUE: xReader.Read(); tag.TimeOfDayEveningValue = xReader.Value; break; case TAG_TIME_OF_DAY_EVENING_EXTENDS_TO_NEXT_MORNING: xReader.Read(); tag.EveningExtendsToNextMorning = Convert.ToBoolean(xReader.Value); break; case TAG_ACTIVE: xReader.Read(); tag.Active = Convert.ToBoolean(xReader.Value); break; } } } xReader.Close(); // Change the data for each Tag that's being loaded if we've detected that // the XML document is from an older version of the application. if (Settings.VersionManager.IsOldAppVersion(AppCodename, AppVersion)) { Log.WriteDebugMessage("An old version of the tags.xml file was detected. Attempting upgrade to new schema."); Version v2300 = Settings.VersionManager.Versions.Get("Boombayah", "2.3.0.0"); Version configVersion = Settings.VersionManager.Versions.Get(AppCodename, AppVersion); if (v2300 != null && configVersion != null && configVersion.VersionNumber < v2300.VersionNumber) { Log.WriteDebugMessage("Dalek 2.2.4.6 or older detected"); // This is a new property for Tag that was introduced in 2.3.0.0 // so any version before 2.3.0.0 needs to have it during an upgrade. tag.Active = true; // "Description" is a new property for Tag that was introduced in 2.3.0.0 switch (tag.Type) { case TagType.ActiveWindowTitle: tag.Description = "The title of the active window"; break; case TagType.DateTimeFormat: tag.Description = "A value representing either a date, a time, or a combination of the date and time (" + tag.Name + ")"; break; case TagType.ImageFormat: tag.Description = "The image format of the screenshot (such as jpeg or png)"; break; case TagType.ScreenCaptureCycleCount: tag.Description = "The number of capture cycles during a screen capture session"; break; case TagType.ScreenName: tag.Description = "The name of the screen or region"; break; case TagType.ScreenNumber: tag.Description = "The screen number. For example, the first display is screen number 1"; break; case TagType.User: tag.Description = "The name of the user (" + tag.Name + ")"; break; case TagType.Machine: tag.Description = "The name of the computer (" + tag.Name + ")"; break; case TagType.TimeOfDay: tag.Description = "The macro to use for a specific time of day"; break; case TagType.DateTimeFormatExpression: tag.Description = "An expression which represents a time that is either ahead or behind the current time (" + tag.Name + ")"; break; } } } if (!string.IsNullOrEmpty(tag.Name)) { Add(tag); } } if (Settings.VersionManager.IsOldAppVersion(AppCodename, AppVersion)) { Log.WriteDebugMessage("Tags file detected as an old version"); SaveToXmlFile(); } } else { Log.WriteDebugMessage($"WARNING: {FileSystem.TagsFile} not found. Creating default tags"); // Setup a few "built in" tags by default. Add(new Tag("name", "The name of the screen or region", TagType.ScreenName, active: true)); Add(new Tag("screen", "The screen number. For example, the first display is screen 1 and the second display is screen 2", TagType.ScreenNumber, active: true)); Add(new Tag("format", "The image format such as jpeg or png", TagType.ImageFormat, active: true)); Add(new Tag("date", "The current date (%date%)", TagType.DateTimeFormat, MacroParser.DateFormat, active: true)); Add(new Tag("time", "The current time (%time%)", TagType.DateTimeFormat, MacroParser.TimeFormatForWindows, active: true)); Add(new Tag("year", "The current year (%year%)", TagType.DateTimeFormat, MacroParser.YearFormat, active: true)); Add(new Tag("month", "The current month (%month%)", TagType.DateTimeFormat, MacroParser.MonthFormat, active: true)); Add(new Tag("day", "The current day (%day%)", TagType.DateTimeFormat, MacroParser.DayFormat, active: true)); Add(new Tag("hour", "The current hour (%hour%)", TagType.DateTimeFormat, MacroParser.HourFormat, active: true)); Add(new Tag("minute", "The current minute (%minute%)", TagType.DateTimeFormat, MacroParser.MinuteFormat, active: true)); Add(new Tag("second", "The current second (%second%)", TagType.DateTimeFormat, MacroParser.SecondFormat, active: true)); Add(new Tag("millisecond", "The current millisecond (%millisecond%)", TagType.DateTimeFormat, MacroParser.MillisecondFormat, active: true)); Add(new Tag("lastyear", "The previous year (%lastyear%)", TagType.DateTimeFormatExpression, "{year-1}", active: true)); Add(new Tag("lastmonth", "The previous month (%lastmonth%)", TagType.DateTimeFormatExpression, "{month-1}", active: true)); Add(new Tag("yesterday", "The previous day (%yesterday%)", TagType.DateTimeFormatExpression, "{day-1}", active: true)); Add(new Tag("tomorrow", "The next day (%tomorrow%)", TagType.DateTimeFormatExpression, "{day+1}", active: true)); Add(new Tag("6hoursbehind", "Six hours behind the current hour (%6hoursbehind%)", TagType.DateTimeFormatExpression, "{hour-6}", active: true)); Add(new Tag("6hoursahead", "Six hours ahead the current hour (%6hoursahead%)", TagType.DateTimeFormatExpression, "{hour+6}", active: true)); Add(new Tag("count", "The number of capture cycles during a running screen capture session. For example, the first round of screenshots taken is the first cycle count or count 1", TagType.ScreenCaptureCycleCount, active: true)); Add(new Tag("user", "The user using this computer (%user%)", TagType.User, active: true)); Add(new Tag("machine", "The name of the computer (%machine%)", TagType.Machine, active: true)); Add(new Tag("title", "The title of the active window", TagType.ActiveWindowTitle, active: true)); Add(new Tag("timeofday", "The macro to use at a specific time of day so you can have a macro for the morning, a macro for the afternoon, and a macro for the evening. At the moment it is %timeofday%", TagType.TimeOfDay, active: true)); SaveToXmlFile(); } Log.WriteDebugMessage(":: LoadXmlFileAndAddTags End ::"); } catch (Exception ex) { Log.WriteExceptionMessage("TagCollection::LoadXmlFileAndAddTags", ex); } }
private void FormScreen_Load(object sender, EventArgs e) { textBoxScreenName.Focus(); HelpMessage("This is where to configure a screen capture. Select a source and a component then change the display properties and image attributes"); _toolTip.SetToolTip(checkBoxMouse, "You can include the mouse pointer in your screenshots if the \"Include mouse pointer\" option is checked"); _toolTip.SetToolTip(comboBoxFormat, "Change the image format for the screenshots taken by this screen capture. JPEG is the recommended image format"); _toolTip.SetToolTip(checkBoxActive, "You can capture this screen if Active is checked (turned on)"); _toolTip.SetToolTip(buttonScreenBrowseFolder, "Browse for a folder where screenshots of this screen capture will be saved to"); _toolTip.SetToolTip(buttonMacroTags, "Open a list of available macro tags. You can keep the Macro Tags window open while you modify your macro"); comboBoxFormat.Items.Clear(); pictureBoxPreview.Image = null; foreach (ImageFormat imageFormat in ImageFormatCollection) { comboBoxFormat.Items.Add(imageFormat.Name); } comboBoxScreenSource.Items.Clear(); comboBoxScreenSource.Items.Add("Auto Screen Capture"); comboBoxScreenSource.Items.Add("Graphics Card"); comboBoxScreenSource.Items.Add("Operating System"); if (ScreenObject != null) { Text = "Change Screen"; textBoxScreenName.Text = ScreenObject.Name; textBoxFolder.Text = FileSystem.CorrectScreenshotsFolderPath(ScreenObject.Folder); textBoxMacro.Text = ScreenObject.Macro; comboBoxScreenSource.SelectedIndex = ScreenObject.Source; comboBoxFormat.SelectedItem = ScreenObject.Format.Name; numericUpDownJpegQuality.Value = ScreenObject.JpegQuality; numericUpDownResolutionRatio.Value = ScreenObject.ResolutionRatio; checkBoxMouse.Checked = ScreenObject.Mouse; checkBoxActive.Checked = ScreenObject.Active; numericUpDownX.Value = ScreenObject.X; numericUpDownY.Value = ScreenObject.Y; numericUpDownWidth.Value = ScreenObject.Width; numericUpDownHeight.Value = ScreenObject.Height; } else { Text = "Add Screen"; textBoxScreenName.Text = "Screen " + (ScreenCollection.Count + 1); textBoxFolder.Text = FileSystem.ScreenshotsFolder; textBoxMacro.Text = MacroParser.DefaultMacro; comboBoxScreenSource.SelectedIndex = 1; comboBoxFormat.SelectedItem = ScreenCapture.DefaultImageFormat; numericUpDownJpegQuality.Value = 100; numericUpDownResolutionRatio.Value = 100; checkBoxMouse.Checked = true; checkBoxActive.Checked = true; numericUpDownX.Value = 0; numericUpDownY.Value = 0; numericUpDownWidth.Value = 0; numericUpDownHeight.Value = 0; } UpdatePreviewMacro(); UpdatePreviewImage(ScreenCapture); }
/// <summary> /// Saves the image schedules in the collection to the schedules.xml file. /// </summary> public bool SaveToXmlFile() { try { 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 }; if (string.IsNullOrEmpty(FileSystem.SchedulesFile)) { FileSystem.SchedulesFile = FileSystem.DefaultSchedulesFile; FileSystem.AppendToFile(FileSystem.ConfigFile, "\nSchedulesFile=" + FileSystem.SchedulesFile); } if (FileSystem.FileExists(FileSystem.SchedulesFile)) { FileSystem.DeleteFile(FileSystem.SchedulesFile); } using (XmlWriter xWriter = XmlWriter.Create(FileSystem.SchedulesFile, 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_SCHEDULES_NODE); foreach (Schedule schedule in base.Collection) { xWriter.WriteStartElement(XML_FILE_SCHEDULE_NODE); xWriter.WriteElementString(SCHEDULE_ACTIVE, schedule.Active.ToString()); xWriter.WriteElementString(SCHEDULE_NAME, schedule.Name); xWriter.WriteElementString(SCHEDULE_MODE_ONETIME, schedule.ModeOneTime.ToString()); xWriter.WriteElementString(SCHEDULE_MODE_PERIOD, schedule.ModePeriod.ToString()); xWriter.WriteElementString(SCHEDULE_CAPTUREAT, schedule.CaptureAt.ToString()); xWriter.WriteElementString(SCHEDULE_STARTAT, schedule.StartAt.ToString()); xWriter.WriteElementString(SCHEDULE_STOPAT, schedule.StopAt.ToString()); xWriter.WriteElementString(SCHEDULE_MONDAY, schedule.Monday.ToString()); xWriter.WriteElementString(SCHEDULE_TUESDAY, schedule.Tuesday.ToString()); xWriter.WriteElementString(SCHEDULE_WEDNESDAY, schedule.Wednesday.ToString()); xWriter.WriteElementString(SCHEDULE_THURSDAY, schedule.Thursday.ToString()); xWriter.WriteElementString(SCHEDULE_FRIDAY, schedule.Friday.ToString()); xWriter.WriteElementString(SCHEDULE_SATURDAY, schedule.Saturday.ToString()); xWriter.WriteElementString(SCHEDULE_SUNDAY, schedule.Sunday.ToString()); xWriter.WriteElementString(SCHEDULE_NOTES, schedule.Notes); xWriter.WriteEndElement(); } xWriter.WriteEndElement(); xWriter.WriteEndElement(); xWriter.WriteEndDocument(); xWriter.Flush(); xWriter.Close(); } return(true); } catch (Exception ex) { Log.WriteExceptionMessage("ScheduleCollection::SaveToXmlFile", ex); return(false); } }
/// <summary> /// Loads the triggers. /// </summary> public bool LoadXmlFileAndAddTriggers() { try { if (FileSystem.FileExists(FileSystem.TriggersFile)) { XmlDocument xDoc = new XmlDocument(); xDoc.Load(FileSystem.TriggersFile); AppVersion = xDoc.SelectSingleNode("/autoscreen").Attributes["app:version"]?.Value; AppCodename = xDoc.SelectSingleNode("/autoscreen").Attributes["app:codename"]?.Value; XmlNodeList xTriggers = xDoc.SelectNodes(TRIGGER_XPATH); foreach (XmlNode xTrigger in xTriggers) { Trigger trigger = new Trigger(); XmlNodeReader xReader = new XmlNodeReader(xTrigger); while (xReader.Read()) { if (xReader.IsStartElement() && !xReader.IsEmptyElement) { switch (xReader.Name) { case TRIGGER_NAME: xReader.Read(); trigger.Name = xReader.Value; break; case TRIGGER_CONDITION: xReader.Read(); trigger.ConditionType = (TriggerConditionType)Enum.Parse(typeof(TriggerConditionType), xReader.Value); break; case TRIGGER_ACTION: xReader.Read(); trigger.ActionType = (TriggerActionType)Enum.Parse(typeof(TriggerActionType), xReader.Value); break; // This is purely for backwards compatibility with older versions. // We no longer use Editor. We use ModuleItem now (since 2.3.0.0). case TRIGGER_EDITOR: xReader.Read(); trigger.ModuleItem = xReader.Value; break; case TRIGGER_ACTIVE: xReader.Read(); trigger.Active = Convert.ToBoolean(xReader.Value); break; case TRIGGER_DATE: xReader.Read(); trigger.Date = Convert.ToDateTime(xReader.Value); break; case TRIGGER_TIME: xReader.Read(); trigger.Time = Convert.ToDateTime(xReader.Value); break; case TRIGGER_DAY: xReader.Read(); trigger.Day = xReader.Value; break; case TRIGGER_SCREEN_CAPTURE_INTERVAL: xReader.Read(); trigger.ScreenCaptureInterval = Convert.ToInt32(xReader.Value); break; case TRIGGER_MODULE_ITEM: xReader.Read(); trigger.ModuleItem = xReader.Value; break; } } } xReader.Close(); // Change the data for each Trigger that's being loaded if we've detected that // the XML document is from an older version of the application. if (Settings.VersionManager.IsOldAppVersion(AppCodename, AppVersion)) { Log.WriteDebugMessage("An old version of the triggers.xml file was detected. Attempting upgrade to new schema."); Version v2300 = Settings.VersionManager.Versions.Get("Boombayah", "2.3.0.0"); Version configVersion = Settings.VersionManager.Versions.Get(AppCodename, AppVersion); if (v2300 != null && configVersion != null && configVersion.VersionNumber < v2300.VersionNumber) { Log.WriteDebugMessage("Dalek 2.2.4.6 or older detected"); // These are new properties for Trigger that were introduced in 2.3.0.0 // so any version before 2.3.0.0 needs to have them during an upgrade. trigger.Active = true; trigger.Date = DateTime.Now; trigger.Time = DateTime.Now; trigger.ScreenCaptureInterval = 0; } } if (!string.IsNullOrEmpty(trigger.Name)) { Add(trigger); } } if (Settings.VersionManager.IsOldAppVersion(AppCodename, AppVersion)) { SaveToXmlFile(); } } else { Log.WriteDebugMessage("WARNING: Unable to load triggers"); Trigger triggerApplicationStartShowInterface = new Trigger() { Active = true, Name = "Application Startup -> Show", ConditionType = TriggerConditionType.ApplicationStartup, ActionType = TriggerActionType.ShowInterface, Date = DateTime.Now, Time = DateTime.Now, ScreenCaptureInterval = 0 }; Trigger triggerScreenCaptureStartedHideInterface = new Trigger() { Active = true, Name = "Capture Started -> Hide", ConditionType = TriggerConditionType.ScreenCaptureStarted, ActionType = TriggerActionType.HideInterface, Date = DateTime.Now, Time = DateTime.Now, ScreenCaptureInterval = 0 }; Trigger triggerScreenCaptureStoppedShowInterface = new Trigger() { Active = true, Name = "Capture Stopped -> Show", ConditionType = TriggerConditionType.ScreenCaptureStopped, ActionType = TriggerActionType.ShowInterface, Date = DateTime.Now, Time = DateTime.Now, ScreenCaptureInterval = 0 }; Trigger triggerInterfaceClosingExitApplication = new Trigger() { Active = true, Name = "Interface Closing -> Exit", ConditionType = TriggerConditionType.InterfaceClosing, ActionType = TriggerActionType.ExitApplication, Date = DateTime.Now, Time = DateTime.Now, ScreenCaptureInterval = 0 }; Trigger triggerLimitReachedStopScreenCapture = new Trigger() { Active = true, Name = "Limit Reached -> Stop", ConditionType = TriggerConditionType.LimitReached, ActionType = TriggerActionType.StopScreenCapture, Date = DateTime.Now, Time = DateTime.Now, ScreenCaptureInterval = 0 }; // Setup a few "built in" triggers by default. Add(triggerApplicationStartShowInterface); Add(triggerScreenCaptureStartedHideInterface); Add(triggerScreenCaptureStoppedShowInterface); Add(triggerInterfaceClosingExitApplication); Add(triggerLimitReachedStopScreenCapture); SaveToXmlFile(); } return(true); } catch (Exception ex) { Log.WriteExceptionMessage("TriggerCollection::LoadXmlFileAndAddTriggers", ex); return(false); } }
/// <summary> /// Saves the triggers. /// </summary> public bool SaveToXmlFile() { try { XmlWriterSettings xSettings = new XmlWriterSettings(); xSettings.Indent = true; xSettings.CloseOutput = true; xSettings.CheckCharacters = true; xSettings.Encoding = Encoding.UTF8; xSettings.NewLineChars = Environment.NewLine; xSettings.IndentChars = XML_FILE_INDENT_CHARS; xSettings.NewLineHandling = NewLineHandling.Entitize; xSettings.ConformanceLevel = ConformanceLevel.Document; if (string.IsNullOrEmpty(FileSystem.TriggersFile)) { FileSystem.TriggersFile = FileSystem.DefaultTriggersFile; if (FileSystem.FileExists(FileSystem.ConfigFile)) { FileSystem.AppendToFile(FileSystem.ConfigFile, "\nTriggersFile=" + FileSystem.TriggersFile); } } if (FileSystem.FileExists(FileSystem.TriggersFile)) { FileSystem.DeleteFile(FileSystem.TriggersFile); } using (XmlWriter xWriter = XmlWriter.Create(FileSystem.TriggersFile, 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_TRIGGERS_NODE); foreach (Trigger trigger in base.Collection) { xWriter.WriteStartElement(XML_FILE_TRIGGER_NODE); xWriter.WriteElementString(TRIGGER_ACTIVE, trigger.Active.ToString()); xWriter.WriteElementString(TRIGGER_NAME, trigger.Name); xWriter.WriteElementString(TRIGGER_CONDITION, trigger.ConditionType.ToString()); xWriter.WriteElementString(TRIGGER_ACTION, trigger.ActionType.ToString()); xWriter.WriteElementString(TRIGGER_DATE, trigger.Date.ToString()); xWriter.WriteElementString(TRIGGER_TIME, trigger.Time.ToString()); xWriter.WriteElementString(TRIGGER_DAY, string.IsNullOrEmpty(trigger.Day) ? "Weekday" : trigger.Day.ToString()); xWriter.WriteElementString(TRIGGER_SCREEN_CAPTURE_INTERVAL, trigger.ScreenCaptureInterval.ToString()); xWriter.WriteElementString(TRIGGER_MODULE_ITEM, trigger.ModuleItem); xWriter.WriteEndElement(); } xWriter.WriteEndElement(); xWriter.WriteEndElement(); xWriter.WriteEndDocument(); xWriter.Flush(); xWriter.Close(); } return(true); } catch (Exception ex) { Log.WriteExceptionMessage("TriggerCollection::SaveToXmlFile", ex); return(false); } }
// A generic method for building a module. private void BuildModule <T>(IEnumerable <T> list, TabPage tabPage, EventHandler eventHandlerForAddNew, EventHandler eventHandlerForRemoveSelected, EventHandler eventhandlerForChange) { int xPos = 5; int yPos = 3; const int HEIGHT = 20; const int CHECKBOX_WIDTH = 20; const int CHECKBOX_HEIGHT = 20; const int X_POS_ICON = 20; const int SMALL_IMAGE_WIDTH = 20; const int SMALL_IMAGE_HEIGHT = 20; const int SMALL_BUTTON_WIDTH = 21; const int SMALL_BUTTON_HEIGHT = 21; const int X_POS_TEXTBOX = 48; const int X_POS_BUTTON = 178; const int TEXTBOX_WIDTH = 125; const int Y_POS_INCREMENT = 23; const int TEXTBOX_MAX_LENGTH = 50; tabPage.Controls.Clear(); // The button for adding a new object (this could be a Screen, Region, Editor, Trigger, or Tag). Button buttonAddNew = new Button { Size = new Size(SMALL_BUTTON_WIDTH, SMALL_BUTTON_HEIGHT), Location = new Point(xPos, yPos), Image = Properties.Resources.add, FlatStyle = FlatStyle.Flat, BackColor = Color.Transparent, ForeColor = Color.Transparent, ImageAlign = ContentAlignment.MiddleCenter, TabStop = false }; buttonAddNew.Click += eventHandlerForAddNew; tabPage.Controls.Add(buttonAddNew); // Render the button for removing multiple selected objects. Button buttonRemoveSelected = new Button { Size = new Size(SMALL_IMAGE_WIDTH, SMALL_IMAGE_HEIGHT), Location = new Point(xPos + 27, yPos), Image = Properties.Resources.delete, FlatStyle = FlatStyle.Flat, BackColor = Color.Transparent, ForeColor = Color.Transparent, ImageAlign = ContentAlignment.MiddleCenter, TabStop = false }; buttonRemoveSelected.Click += eventHandlerForRemoveSelected; tabPage.Controls.Add(buttonRemoveSelected); // Move down a bit. yPos += 28; // Populate the tab page with each object from the list of objects. foreach (T @object in list) { // Add a checkbox so that the user has the ability to remove the selected object. CheckBox checkbox = new CheckBox { Size = new Size(CHECKBOX_WIDTH, CHECKBOX_HEIGHT), Location = new Point(xPos, yPos), Tag = @object, TabStop = false }; tabPage.Controls.Add(checkbox); Type t = @object.GetType(); // Find the "Name" property of the object. Every object of type Screen, Editor, Region, etc. has this property. string text = t.GetProperty("Name").GetValue(@object, null).ToString(); // Editors have application icons so we'd like to display those in the list on the tab page. if (t.Equals(typeof(Editor))) { string application = t.GetProperty("Application").GetValue(@object, null).ToString(); PictureBox appIcon = new PictureBox { Size = new Size(SMALL_IMAGE_WIDTH, SMALL_IMAGE_HEIGHT), Location = new Point(xPos + X_POS_ICON, yPos), SizeMode = PictureBoxSizeMode.StretchImage }; if (FileSystem.FileExists(application)) { // Add an image showing the application icon of the Editor if we can find the application's path. appIcon.Image = Icon.ExtractAssociatedIcon(application).ToBitmap(); } tabPage.Controls.Add(appIcon); } else { // Show the status of the object in a label and make the background color green if it's enabled or red if it's disabled. Label labelEnabledStatus = new Label { Size = new Size(SMALL_IMAGE_WIDTH, SMALL_IMAGE_HEIGHT), Location = new Point(xPos + X_POS_ICON, yPos), Tag = @object, TabStop = false, BorderStyle = BorderStyle.FixedSingle }; // Types of Screen, Region, Tag, Schedule, and Trigger have an "Active" property // so we change the color of the label background depending on the value of "Active". if (t.Equals(typeof(Screen)) || t.Equals(typeof(Region)) || t.Equals(typeof(Tag)) || t.Equals(typeof(Schedule)) || t.Equals(typeof(Trigger))) { bool enabled = (bool)t.GetProperty("Active").GetValue(@object, null); labelEnabledStatus.BackColor = enabled ? Color.PaleGreen : Color.PaleVioletRed; } labelEnabledStatus.Click += enabledStatus_Click; tabPage.Controls.Add(labelEnabledStatus); } // Add another read-only text box showing the name of the object. TextBox textBoxObjectName = new TextBox { Width = TEXTBOX_WIDTH, Height = HEIGHT, MaxLength = TEXTBOX_MAX_LENGTH, Location = new Point(xPos + X_POS_TEXTBOX, yPos), Text = text, ReadOnly = true, TabStop = false }; tabPage.Controls.Add(textBoxObjectName); // Add a button so that the user can change the object. Button buttonChange = new Button { Size = new Size(SMALL_BUTTON_WIDTH, SMALL_BUTTON_HEIGHT), Location = new Point(xPos + X_POS_BUTTON, yPos), Image = Properties.Resources.configure, FlatStyle = FlatStyle.Flat, BackColor = Color.Transparent, ForeColor = Color.Transparent, ImageAlign = ContentAlignment.MiddleCenter, Tag = @object, TabStop = false }; buttonChange.Click += eventhandlerForChange; tabPage.Controls.Add(buttonChange); // Move down the tab page so we're ready to loop around again and add the next object to it. yPos += Y_POS_INCREMENT; } }
private void RunScreenCaptures() { try { foreach (Screen screen in _formScreen.ScreenCollection) { if (screen.Active) { if (screen.Component == 0) { MacroParser.screenCapture = _screenCapture; // Active Window if (!string.IsNullOrEmpty(_screenCapture.ActiveWindowTitle)) { // Do not contiune if the active window title needs to be checked and the active window title // does not contain the text defined in "Active Window Title Capture Text" and CaptureNow is false. // CaptureNow could be set to "true" during a "Capture Now / Archive" or "Capture Now / Edit" option // so, in that case, we want to capture the screen and save the screenshot regardless of the title text. if (checkBoxActiveWindowTitle.Checked && !string.IsNullOrEmpty(textBoxActiveWindowTitle.Text) && !_screenCapture.ActiveWindowTitle.ToLower().Contains(textBoxActiveWindowTitle.Text.ToLower()) && !_screenCapture.CaptureNow) { return; } _screenCapture.CaptureNow = false; if (_screenCapture.GetScreenImages(screen.Component, 0, 0, 0, 0, false, screen.ResolutionRatio, out Bitmap bitmap)) { if (_screenCapture.SaveScreenshot( path: FileSystem.CorrectScreenshotsFolderPath(MacroParser.ParseTags(screen.Folder, _formTag.TagCollection)) + MacroParser.ParseTags(preview: false, screen.Name, screen.Macro, screen.Component, screen.Format, _screenCapture.ActiveWindowTitle, _formTag.TagCollection), format: screen.Format, component: screen.Component, screenshotType: ScreenshotType.ActiveWindow, jpegQuality: screen.JpegQuality, viewId: screen.ViewId, bitmap: bitmap, label: checkBoxScreenshotLabel.Checked ? comboBoxScreenshotLabel.Text : string.Empty, windowTitle: _screenCapture.ActiveWindowTitle, processName: _screenCapture.ActiveWindowProcessName, screenshotCollection: _screenshotCollection )) { ScreenshotTakenWithSuccess(); } else { ScreenshotTakenWithFailure(); break; } } } } else { if (_formScreen.ScreenDictionary.ContainsKey(screen.Component)) { MacroParser.screenCapture = _screenCapture; if (!string.IsNullOrEmpty(_screenCapture.ActiveWindowTitle)) { // Do not contiune if the active window title needs to be checked and the active window title // does not contain the text defined in "Active Window Title Capture Text" and CaptureNow is false. // CaptureNow could be set to "true" during a "Capture Now / Archive" or "Capture Now / Edit" option // so, in that case, we want to capture the screen and save the screenshot regardless of the title text. if (checkBoxActiveWindowTitle.Checked && !string.IsNullOrEmpty(textBoxActiveWindowTitle.Text) && !_screenCapture.ActiveWindowTitle.ToLower().Contains(textBoxActiveWindowTitle.Text.ToLower()) && !_screenCapture.CaptureNow) { return; } _screenCapture.CaptureNow = false; // Screen X if (_screenCapture.GetScreenImages(screen.Component, _formScreen.ScreenDictionary[screen.Component].Bounds.X, _formScreen.ScreenDictionary[screen.Component].Bounds.Y, _formScreen.ScreenDictionary[screen.Component].Bounds.Width, _formScreen.ScreenDictionary[screen.Component].Bounds.Height, screen.Mouse, screen.ResolutionRatio, out Bitmap bitmap)) { if (_screenCapture.SaveScreenshot( path: FileSystem.CorrectScreenshotsFolderPath(MacroParser.ParseTags(screen.Folder, _formTag.TagCollection)) + MacroParser.ParseTags(preview: false, screen.Name, screen.Macro, screen.Component, screen.Format, _screenCapture.ActiveWindowTitle, _formTag.TagCollection), format: screen.Format, component: screen.Component, screenshotType: ScreenshotType.Screen, jpegQuality: screen.JpegQuality, viewId: screen.ViewId, bitmap: bitmap, label: checkBoxScreenshotLabel.Checked ? comboBoxScreenshotLabel.Text : string.Empty, windowTitle: _screenCapture.ActiveWindowTitle, processName: _screenCapture.ActiveWindowProcessName, screenshotCollection: _screenshotCollection )) { ScreenshotTakenWithSuccess(); } else { ScreenshotTakenWithFailure(); break; } } } } } } } } catch (Exception ex) { _screenCapture.ApplicationError = true; Log.WriteExceptionMessage("FormMain-Screens::RunScreenCaptures", ex); } }
/// <summary> /// Writes a message (whether it be an error or just a general message) and the exception (if any). /// </summary> /// <param name="message">The message to write.</param> /// <param name="writeError">Determines if we write the message to the error file in the debug folder.</param> /// <param name="ex">The exception received from the .NET Framework.</param> private static void Write(string message, bool writeError, Exception ex) { try { _mutexWriteFile.WaitOne(); string appVersion = "[(v" + DefaultSettings.ApplicationVersion + ") "; if (string.IsNullOrEmpty(FileSystem.DebugFolder)) { FileSystem.DebugFolder = AppDomain.CurrentDomain.BaseDirectory + @"!autoscreen" + FileSystem.PathDelimiter + "debug" + FileSystem.PathDelimiter; } if (string.IsNullOrEmpty(FileSystem.LogsFolder)) { FileSystem.LogsFolder = FileSystem.DebugFolder + "logs" + FileSystem.PathDelimiter; } if (!FileSystem.DirectoryExists(FileSystem.DebugFolder)) { FileSystem.CreateDirectory(FileSystem.DebugFolder); } if (!FileSystem.DirectoryExists(FileSystem.LogsFolder)) { FileSystem.CreateDirectory(FileSystem.LogsFolder); } // These are just general errors from the application so, if we have one, then write it out to the error file. if (writeError) { FileSystem.AppendToFile(FileSystem.DebugFolder + FileSystem.ErrorFile, appVersion + DateTime.Now.ToString(MacroParser.DateFormat + " " + MacroParser.TimeFormat) + "] ERROR: " + message); } // Log any exception errors we encounter. if (ex != null) { string exceptionError = appVersion + DateTime.Now.ToString(MacroParser.DateFormat + " " + MacroParser.TimeFormat) + "] " + message + " - Exception Message: " + ex.Message + "\nInner Exception: " + (ex.InnerException != null ? ex.InnerException.Message : string.Empty) + "\nSource: " + ex.Source + "\nStack Trace: " + ex.StackTrace; FileSystem.AppendToFile(FileSystem.DebugFolder + FileSystem.ErrorFile, exceptionError); FileSystem.AppendToFile(FileSystem.LogsFolder + FileSystem.LogFile + extension, exceptionError); // If we encounter an exception error it's probably better to just error out on exit // but we'll let the user decide if that's what they really want to do. if (Settings.Application == null || Convert.ToBoolean(Settings.Application.GetByKey("ExitOnError", DefaultSettings.ExitOnError).Value)) { Environment.Exit(1); } } else { // Write to the main log file. FileSystem.AppendToFile(FileSystem.LogsFolder + FileSystem.LogFile + extension, appVersion + DateTime.Now.ToString(MacroParser.DateFormat + " " + MacroParser.TimeFormat) + "] " + message); // Create a date-stamped directory if it does not already exist. if (!FileSystem.DirectoryExists(FileSystem.LogsFolder + DateTime.Now.ToString(MacroParser.DateFormat))) { FileSystem.CreateDirectory(FileSystem.LogsFolder + DateTime.Now.ToString(MacroParser.DateFormat)); } // Write to a log file within a directory representing the day when the message was logged. FileSystem.AppendToFile(FileSystem.LogsFolder + DateTime.Now.ToString(MacroParser.DateFormat) + FileSystem.PathDelimiter + FileSystem.LogFile + "_" + DateTime.Now.ToString(MacroParser.DateFormat) + ".txt", appVersion + DateTime.Now.ToString(MacroParser.DateFormat + " " + MacroParser.TimeFormat) + "] " + message); } } finally { _mutexWriteFile.ReleaseMutex(); } }