diff --git a/ClickForensics.Quartz.Manager/ClickForensics.Quartz.Manager.csproj b/ClickForensics.Quartz.Manager/ClickForensics.Quartz.Manager.csproj index cc36f3e..34d50a3 100644 --- a/ClickForensics.Quartz.Manager/ClickForensics.Quartz.Manager.csproj +++ b/ClickForensics.Quartz.Manager/ClickForensics.Quartz.Manager.csproj @@ -1,199 +1,210 @@ - - - - Debug - AnyCPU - 9.0.30729 - 2.0 - {D23DACFA-11A1-480E-A6C4-1F37B564523D} - WinExe - Properties - ClickForensics.Quartz.Manager - ClickForensics.Quartz.Manager - v4.0 - 512 - - - 3.5 - - - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\lib\Common.Logging.dll - - - ..\lib\Quartz.dll - - - - - 3.5 - - - 3.5 - - - 3.5 - - - - - - - - - - Form - - - AddJobForm.cs - - - Form - - - AddListenerForm.cs - - - Form - - - ErrorDialog.cs - - - - UserControl - - - NativeJobDetailDisplay.cs - - - - Form - - - MainForm.cs - - - - - AddJobForm.cs - - - AddListenerForm.cs - - - CronTriggerDisplay.cs - - - ErrorDialog.cs - - - MainForm.cs - - - NativeJobDetailDisplay.cs - - - ResXFileCodeGenerator - Resources.Designer.cs - Designer - - - ServerConnectForm.cs - - - True - Resources.resx - True - - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - True - Settings.settings - True - - - - - Form - - - ServerConnectForm.cs - - - UserControl - - - CronTriggerDisplay.cs - - - - - - PreserveNewest - - - - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 3.5 SP1 - true - - - False - Windows Installer 3.1 - true - - - + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {D23DACFA-11A1-480E-A6C4-1F37B564523D} + WinExe + Properties + ClickForensics.Quartz.Manager + ClickForensics.Quartz.Manager + v4.0 + 512 + + + 3.5 + + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\lib\Common.Logging.dll + + + ..\lib\Quartz.dll + + + + + 3.5 + + + 3.5 + + + 3.5 + + + + + + + + + + Form + + + AddJobForm.cs + + + Form + + + AddListenerForm.cs + + + + UserControl + + + SimpleTriggerDisplay.cs + + + Form + + + ErrorDialog.cs + + + + UserControl + + + NativeJobDetailDisplay.cs + + + + Form + + + MainForm.cs + + + + + AddJobForm.cs + + + AddListenerForm.cs + + + SimpleTriggerDisplay.cs + + + CronTriggerDisplay.cs + + + ErrorDialog.cs + + + MainForm.cs + + + NativeJobDetailDisplay.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + ServerConnectForm.cs + + + True + Resources.resx + True + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + Form + + + ServerConnectForm.cs + + + UserControl + + + CronTriggerDisplay.cs + + + + + + PreserveNewest + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + --> \ No newline at end of file diff --git a/ClickForensics.Quartz.Manager/ConnectionInfo.cs b/ClickForensics.Quartz.Manager/ConnectionInfo.cs new file mode 100644 index 0000000..b71b5d5 --- /dev/null +++ b/ClickForensics.Quartz.Manager/ConnectionInfo.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace ClickForensics.Quartz.Manager +{ + public class ConnectionInfo + { + public string ServerName { get; set; } + public int Port { get; set; } + public string SchedulerName { get; set; } + } +} diff --git a/ClickForensics.Quartz.Manager/MainForm.cs b/ClickForensics.Quartz.Manager/MainForm.cs index 42682c9..56bf29f 100644 --- a/ClickForensics.Quartz.Manager/MainForm.cs +++ b/ClickForensics.Quartz.Manager/MainForm.cs @@ -1,380 +1,416 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Linq; -using System.Text; -using System.Windows.Forms; -using Quartz; -using Quartz.Collection; -using System.Net.Sockets; -//using ClickForensics.Quartz.Jobs; -using System.IO; - -namespace ClickForensics.Quartz.Manager -{ - public partial class MainForm : Form - { - public MainForm() - { - InitializeComponent(); - jobGroupsTreeView.AfterSelect += new TreeViewEventHandler(jobGroupsTreeView_AfterSelect); - ctxScheduler.Opening += new CancelEventHandler(ctxScheduler_Opening); - jobGroupsTreeView.MouseDown += new MouseEventHandler(jobGroupsTreeView_MouseDown); - - } - - void ctxScheduler_Opening(object sender, CancelEventArgs e) - { - - } - - void jobGroupsTreeView_AfterSelect(object sender, TreeViewEventArgs e) - { - jobDetailsToggle(false); - if (e.Node is TriggerNode || e.Node is JobNode) - { - btnDeleteJob.Enabled = true; - } - else - { - btnDeleteJob.Enabled = false; - } - - if (e.Node is JobNode) - { - btnRunJobNow.Enabled = true; - pnlDetails.Controls.Add(new NativeJobDetailDisplay(((JobNode)e.Node).Detail)); - jobDetailsToggle(true); - } - else - { - btnRunJobNow.Enabled = false; - - } - if (e.Node is TriggerNode) - { - btnPause.Enabled = true; - setPauseButtonText(); - if (((TriggerNode)e.Node).Trigger is CronTrigger) - { - pnlDetails.Controls.Add(new CronTriggerDisplay((CronTrigger)((TriggerNode)e.Node).Trigger)); - jobDetailsToggle(true); - } - btnEdit.Enabled = true; - } - else - { - btnEdit.Enabled = false; - btnPause.Enabled = false; - } - } - - private void setPauseButtonText() - { - TriggerNode node = (TriggerNode)jobGroupsTreeView.SelectedNode; - string name = node.Trigger.Name; - string group = node.Trigger.Group; - if (Scheduler.GetScheduler().GetTriggerState(name, group) == TriggerState.Paused) - { - btnPause.Text = "Resume"; - } - else - { - btnPause.Text = "Pause"; - } - } - - private void connectToolStripMenuItem_Click(object sender, EventArgs e) - { - using (ServerConnectForm form = new ServerConnectForm()) - { - form.ShowDialog(); - try - { - Scheduler = new QuartzScheduler(form.Server, form.Port, form.Scheduler); - serverConnectStatusLabel.Text = string.Format("Connected to {0}", Scheduler.Address); - connectToolStripMenuItem.Enabled = false; - jobsToolStripMenuItem.Enabled = true; - loadJobGroups(); - updateRunningJobs(); - } - catch (SocketException ex) - { - ErrorDialog dialog = new ErrorDialog(); - dialog.Message = string.Format("Unable to connect to scheduler {0} on {1}:{2}", form.Scheduler, form.Server, form.Port); - dialog.Description = ex.Message; - dialog.ShowDialog(); - } - form.Close(); - } - //loadGlobalTriggers(); - } - - //private void loadGlobalTriggers() - //{ - // foreach (IJobListener jobListener in Scheduler.GetScheduler().GetJobDetail(null,null)..GlobalJobListeners) - // { - // globalTriggersListView.Items.Add(jobListener.Name); - // } - //} - - private void loadJobGroups() - { - - try - { - this.Cursor = Cursors.WaitCursor; - - jobDetailsToggle(false); - jobGroupsTreeView.Nodes.Clear(); - SchedulerNode schedulerNode = new SchedulerNode(Scheduler); - schedulerNode.ContextMenuStrip = ctxScheduler; - jobGroupsTreeView.Nodes.Add(schedulerNode); - TreeNode jobGroupsNode = schedulerNode.Nodes.Add("Job Groups"); - string[] jobGroups = Scheduler.GetScheduler().JobGroupNames; - foreach (string jobGroup in jobGroups) - { - TreeNode jobGroupNode = jobGroupsNode.Nodes.Add(jobGroup); - TreeNode jobsNode = jobGroupNode.Nodes.Add("Jobs"); - addJobNodes(jobsNode); - } - - jobGroupsTreeView.Nodes[0].Expand(); - jobGroupsNode.Expand(); - - StripStatusLabel_Job_Groups.Text = DateTime.Now.ToString("yyyy.MM.dd HH:mm.ss"); - - } - finally - { - this.Cursor = Cursors.Default; - } - - - } - - private void jobDetailsToggle(bool isVisible) - { - if (isVisible == false) - { - pnlDetails.Controls.Clear(); - } - } - - void jobGroupsTreeView_MouseDown(object sender, MouseEventArgs e) - { - if (e.Button == MouseButtons.Right) - { - TreeNode node = jobGroupsTreeView.GetNodeAt(e.X, e.Y); - if (node != null) - { - jobGroupsTreeView.SelectedNode = node; - ctxScheduler.Show(jobGroupsTreeView, e.Location); - } - } - } - //private void loadJobs() - //{ - // foreach (TreeNode node in jobGroupsTreeView.Nodes) - // { - // addJobNodes(node); - // } - //} - - private void addJobNodes(TreeNode node) - { - string group = node.Parent.Text; - string[] jobs = Scheduler.GetScheduler().GetJobNames(group); - foreach (string jobName in jobs) - { - try - { - JobDetail detail = Scheduler.GetScheduler().GetJobDetail(jobName, group); - JobNode jobNode = new JobNode(detail); - node.Nodes.Add(jobNode); - addTriggerNodes(jobNode); - addListenerNodes(jobNode); - } - catch (Exception ex) - { - //TODO: Do something useful with this exception. Most likely cause is the client does not have a copy of a given dll and can't load the type. - } - } - } - - private void addListenerNodes(JobNode node) - { - string jobName = node.Text; - string jobGroupName = node.Parent.Text; - string[] listenerNames = node.Detail.JobListenerNames; - foreach (string listener in listenerNames) - { - node.Text = string.Format("JL {0}", listenerNames); - } - //ISet set = Scheduler.GetScheduler().JobListenerNames; - } - - private void addTriggerNodes(TreeNode treeNode) - { - Trigger[] triggers = Scheduler.GetScheduler().GetTriggersOfJob(treeNode.Text, treeNode.Parent.Parent.Text); - TreeNode triggersNode = treeNode.Nodes.Add("Triggers"); - foreach (Trigger trigger in triggers) - { - TriggerNode node = new TriggerNode(trigger); - triggersNode.Nodes.Add(node); - } - - } - private void updateRunningJobs() - { - try - { - this.Cursor = Cursors.WaitCursor; - - timer_Refresh_Running_Jobs.Stop(); - - listView_RunningJobs.Items.Clear(); - - DataTable table = Scheduler.GetRunningJobs(); - foreach (DataRow row in table.Rows) - { - //JobName JobDuration - ListViewItem item = new ListViewItem(new string[] { Convert.ToString(row["JobName"]), Convert.ToString(row["Runtime"]) }); - listView_RunningJobs.Items.Add(item); - } - StripStatusLabel_Jobs_Refresh_date.Text = DateTime.Now.ToString("yyyy.MM.dd HH:mm.ss"); - - - //reset the timer ( documentation not clear if .stop = restart @ 0 in timing, but changing the interval sure should do that. ) - int timer_was = timer_Refresh_Running_Jobs.Interval; - timer_Refresh_Running_Jobs.Interval = timer_was + 1; - timer_Refresh_Running_Jobs.Interval = timer_was; - - timer_Refresh_Running_Jobs.Start(); - } - finally - { - this.Cursor = Cursors.Default; - } - } - public QuartzScheduler Scheduler { get; set; } - - private void addGlobalListenerToolStripMenuItem_Click(object sender, EventArgs e) - { - AddListenerForm form = new AddListenerForm(); - form.ListenerInterface = typeof(IJobListener); - form.ShowDialog(); - JobDataMap map = new JobDataMap(); - map.Add("type", form.ListenerType); - //Scheduler.ScheduleOneTimeJob(typeof(AddJobListenerJob), map, 0); - loadJobGroups(); - } - - private void addJobListenerToolStripMenuItem_Click(object sender, EventArgs e) - { - TreeNode selectedNode = jobGroupsTreeView.SelectedNode; - if (selectedNode != null && selectedNode is JobNode) - { - AddListenerForm form = new AddListenerForm(); - form.ListenerInterface = typeof(IJobListener); - form.ShowDialog(); - //JobHistoryListener listener = new JobHistoryListener(); - //listener.Name = null; - //((JobNode)selectedNode).Detail.AddJobListener(); - } - } - - private void addJobToolStripMenuItem_Click(object sender, EventArgs e) - { - AddJobForm form = new AddJobForm(); - form.ShowDialog(); - if (form.JobDetail != null && form.Trigger != null) - { - Scheduler.GetScheduler().ScheduleJob(form.JobDetail, form.Trigger); - loadJobGroups(); - } - } - - private void btnRefreshRunningJobs_Click(object sender, EventArgs e) - { - updateRunningJobs(); - } - - private void btnRefreshJobGroups_Click(object sender, EventArgs e) - { - loadJobGroups(); - } - - private void btnRunJobNow_Click(object sender, EventArgs e) - { - JobNode node = (JobNode)jobGroupsTreeView.SelectedNode; - string job = node.Detail.Name; - string group = node.Detail.Group; - Scheduler.GetScheduler().TriggerJobWithVolatileTrigger(job, group); - } - - private void btnDeleteJob_Click(object sender, EventArgs e) - { - TreeNode selectedNode = jobGroupsTreeView.SelectedNode; - if (selectedNode is JobNode) - { - JobNode node = (JobNode)jobGroupsTreeView.SelectedNode; - string job = node.Detail.Name; - string group = node.Detail.Group; - Scheduler.GetScheduler().DeleteJob(job, group); - jobGroupsTreeView.SelectedNode.Remove(); - - } - if (selectedNode is TriggerNode) - { - Scheduler.GetScheduler().UnscheduleJob(((TriggerNode)selectedNode).Trigger.Name, ((TriggerNode)selectedNode).Trigger.Group); - } - - //loadJobGroups(); - } - - private void btnPause_Click(object sender, EventArgs e) - { - TriggerNode node = (TriggerNode)jobGroupsTreeView.SelectedNode; - string name = node.Trigger.Name; - string group = node.Trigger.Group; - if (Scheduler.GetScheduler().GetTriggerState(name, group) == TriggerState.Paused) - { - Scheduler.GetScheduler().ResumeTrigger(name, group); - } - else - { - Scheduler.GetScheduler().PauseTrigger(name, group); - } - setPauseButtonText(); - } - - private void btnEdit_Click(object sender, EventArgs e) - { - TriggerNode node = (TriggerNode)jobGroupsTreeView.SelectedNode; - AddJobForm form = new AddJobForm(node); - form.ShowDialog(); - if (form.JobDetail != null && form.Trigger != null) - { - Scheduler.GetScheduler().RescheduleJob(node.Trigger.Name, node.Trigger.Group, form.Trigger); - loadJobGroups(); - } - } - - private void backupToolStripMenuItem_Click(object sender, EventArgs e) - { - QuartzScheduler scheduler = ((SchedulerNode)((TreeView)((ContextMenuStrip)((ToolStripMenuItem)sender).Owner).SourceControl).SelectedNode).Scheduler; - FileDialog dialog = new SaveFileDialog(); - dialog.ShowDialog(); - FileInfo file = new FileInfo(dialog.FileName); - scheduler.BackupToFile(file); - } - - private void timer_Refresh_Running_Jobs_Tick(object sender, EventArgs e) - { - updateRunningJobs(); - } - } -} +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using Quartz; +using Quartz.Collection; +using System.Net.Sockets; +//using ClickForensics.Quartz.Jobs; +using System.IO; + +namespace ClickForensics.Quartz.Manager +{ + public partial class MainForm : Form + { + public MainForm() + { + InitializeComponent(); + jobGroupsTreeView.AfterSelect += new TreeViewEventHandler(jobGroupsTreeView_AfterSelect); + ctxScheduler.Opening += new CancelEventHandler(ctxScheduler_Opening); + jobGroupsTreeView.MouseDown += new MouseEventHandler(jobGroupsTreeView_MouseDown); + + } + + void ctxScheduler_Opening(object sender, CancelEventArgs e) + { + + } + + void jobGroupsTreeView_AfterSelect(object sender, TreeViewEventArgs e) + { + jobDetailsToggle(false); + if (e.Node is TriggerNode || e.Node is JobNode) + { + btnDeleteJob.Enabled = true; + } + else + { + btnDeleteJob.Enabled = false; + } + + if (e.Node is JobNode) + { + btnRunJobNow.Enabled = true; + pnlDetails.Controls.Add(new NativeJobDetailDisplay(((JobNode)e.Node).Detail)); + jobDetailsToggle(true); + } + else + { + btnRunJobNow.Enabled = false; + + } + if (e.Node is TriggerNode) + { + btnPause.Enabled = true; + setPauseButtonText(); + if (((TriggerNode)e.Node).Trigger is CronTrigger) + { + pnlDetails.Controls.Add(new CronTriggerDisplay((CronTrigger)((TriggerNode)e.Node).Trigger)); + jobDetailsToggle(true); + } + if (((TriggerNode)e.Node).Trigger is SimpleTrigger) + { + pnlDetails.Controls.Add(new SimpleTriggerDisplay((SimpleTrigger)((TriggerNode)e.Node).Trigger)); + jobDetailsToggle(true); + } + btnEdit.Enabled = true; + } + else + { + btnEdit.Enabled = false; + btnPause.Enabled = false; + } + } + + private void setPauseButtonText() + { + TriggerNode node = (TriggerNode)jobGroupsTreeView.SelectedNode; + string name = node.Trigger.Name; + string group = node.Trigger.Group; + if (Scheduler.GetScheduler().GetTriggerState(name, group) == TriggerState.Paused) + { + btnPause.Text = "Resume"; + } + else + { + btnPause.Text = "Pause"; + } + } + + private void connectToolStripMenuItem_Click(object sender, EventArgs e) + { + using (ServerConnectForm form = new ServerConnectForm()) + { + form.ShowDialog(); + if (form.Cancelled) + { + return; + } + try + { + Scheduler = new QuartzScheduler(form.Server, form.Port, form.Scheduler); + serverConnectStatusLabel.Text = string.Format("Connected to {0}", Scheduler.Address); + connectToolStripMenuItem.Enabled = false; + jobsToolStripMenuItem.Enabled = true; + loadJobGroups(); + updateRunningJobs(); + } + catch (SocketException ex) + { + ErrorDialog dialog = new ErrorDialog(); + dialog.Message = string.Format("Unable to connect to scheduler {0} on {1}:{2}", form.Scheduler, form.Server, form.Port); + dialog.Description = ex.Message; + dialog.ShowDialog(); + } + form.Close(); + } + //loadGlobalTriggers(); + } + + //private void loadGlobalTriggers() + //{ + // foreach (IJobListener jobListener in Scheduler.GetScheduler().GetJobDetail(null,null)..GlobalJobListeners) + // { + // globalTriggersListView.Items.Add(jobListener.Name); + // } + //} + + private void loadJobGroups() + { + + try + { + this.Cursor = Cursors.WaitCursor; + + jobDetailsToggle(false); + jobGroupsTreeView.Nodes.Clear(); + SchedulerNode schedulerNode = new SchedulerNode(Scheduler); + schedulerNode.ContextMenuStrip = ctxScheduler; + jobGroupsTreeView.Nodes.Add(schedulerNode); + TreeNode jobGroupsNode = schedulerNode.Nodes.Add("Job Groups"); + string[] jobGroups = Scheduler.GetScheduler().JobGroupNames; + foreach (string jobGroup in jobGroups) + { + TreeNode jobGroupNode = jobGroupsNode.Nodes.Add(jobGroup); + TreeNode jobsNode = jobGroupNode.Nodes.Add("Jobs"); + addJobNodes(jobsNode); + } + + jobGroupsTreeView.Nodes[0].Expand(); + jobGroupsNode.Expand(); + + StripStatusLabel_Job_Groups.Text = DateTime.Now.ToString("yyyy.MM.dd HH:mm.ss"); + loadOrphanJobs(schedulerNode); + loadStuckTriggers(schedulerNode); + } + finally + { + this.Cursor = Cursors.Default; + } + + + } + + private void loadStuckTriggers(SchedulerNode schedulerNode) + { + TreeNode jobGroupsNode = schedulerNode.Nodes.Add("Stuck Triggers"); + } + + private void loadOrphanJobs(SchedulerNode schedulerNode) + { + TreeNode jobGroupsNode = schedulerNode.Nodes.Add("Orphan Jobs"); + } + + private void jobDetailsToggle(bool isVisible) + { + if (isVisible == false) + { + pnlDetails.Controls.Clear(); + } + } + + void jobGroupsTreeView_MouseDown(object sender, MouseEventArgs e) + { + if (e.Button == MouseButtons.Right) + { + TreeNode node = jobGroupsTreeView.GetNodeAt(e.X, e.Y); + if (node != null) + { + jobGroupsTreeView.SelectedNode = node; + ctxScheduler.Show(jobGroupsTreeView, e.Location); + } + } + } + //private void loadJobs() + //{ + // foreach (TreeNode node in jobGroupsTreeView.Nodes) + // { + // addJobNodes(node); + // } + //} + + private void addJobNodes(TreeNode node) + { + string group = node.Parent.Text; + string[] jobs = Scheduler.GetScheduler().GetJobNames(group); + foreach (string jobName in jobs) + { + try + { + JobDetail detail = Scheduler.GetScheduler().GetJobDetail(jobName, group); + JobNode jobNode = new JobNode(detail); + node.Nodes.Add(jobNode); + addTriggerNodes(jobNode); + addListenerNodes(jobNode); + } + catch (Exception ex) + { + node.Nodes.Add(string.Format("Unknown Job Type ({0})", jobName)); + //TODO: Do something useful with this exception. Most likely cause is the client does not have a copy of a given dll and can't load the type. + } + } + } + + private void addListenerNodes(JobNode node) + { + string jobName = node.Text; + string jobGroupName = node.Parent.Text; + string[] listenerNames = node.Detail.JobListenerNames; + foreach (string listener in listenerNames) + { + node.Text = string.Format("JL {0}", listenerNames); + } + //ISet set = Scheduler.GetScheduler().JobListenerNames; + } + + private void addTriggerNodes(TreeNode treeNode) + { + Trigger[] triggers = Scheduler.GetScheduler().GetTriggersOfJob(treeNode.Text, treeNode.Parent.Parent.Text); + TreeNode triggersNode = treeNode.Nodes.Add("Triggers"); + foreach (Trigger trigger in triggers) + { + TriggerNode node = new TriggerNode(trigger); + triggersNode.Nodes.Add(node); + addCalendarNode(node); + } + + } + + private void addCalendarNode(TriggerNode node) + { + if (node.Trigger.CalendarName != null) + { + //TODO: Convert this to a CalendarNode and implement CalendarDisplay controls + node.Nodes.Add(node.Trigger.CalendarName); + } + else + { + node.Nodes.Add("No calendar found"); + } + } + + private void updateRunningJobs() + { + try + { + this.Cursor = Cursors.WaitCursor; + + timer_Refresh_Running_Jobs.Stop(); + + listView_RunningJobs.Items.Clear(); + + DataTable table = Scheduler.GetRunningJobs(); + foreach (DataRow row in table.Rows) + { + //JobName JobDuration + ListViewItem item = new ListViewItem(new string[] { Convert.ToString(row["JobName"]), Convert.ToString(row["Runtime"]) }); + listView_RunningJobs.Items.Add(item); + } + StripStatusLabel_Jobs_Refresh_date.Text = DateTime.Now.ToString("yyyy.MM.dd HH:mm.ss"); + + + //reset the timer ( documentation not clear if .stop = restart @ 0 in timing, but changing the interval sure should do that. ) + int timer_was = timer_Refresh_Running_Jobs.Interval; + timer_Refresh_Running_Jobs.Interval = timer_was + 1; + timer_Refresh_Running_Jobs.Interval = timer_was; + + timer_Refresh_Running_Jobs.Start(); + } + finally + { + this.Cursor = Cursors.Default; + } + } + public QuartzScheduler Scheduler { get; set; } + + private void addGlobalListenerToolStripMenuItem_Click(object sender, EventArgs e) + { + AddListenerForm form = new AddListenerForm(); + form.ListenerInterface = typeof(IJobListener); + form.ShowDialog(); + JobDataMap map = new JobDataMap(); + map.Add("type", form.ListenerType); + //Scheduler.ScheduleOneTimeJob(typeof(AddJobListenerJob), map, 0); + loadJobGroups(); + } + + private void addJobListenerToolStripMenuItem_Click(object sender, EventArgs e) + { + TreeNode selectedNode = jobGroupsTreeView.SelectedNode; + if (selectedNode != null && selectedNode is JobNode) + { + AddListenerForm form = new AddListenerForm(); + form.ListenerInterface = typeof(IJobListener); + form.ShowDialog(); + //JobHistoryListener listener = new JobHistoryListener(); + //listener.Name = null; + //((JobNode)selectedNode).Detail.AddJobListener(); + } + } + + private void addJobToolStripMenuItem_Click(object sender, EventArgs e) + { + AddJobForm form = new AddJobForm(); + form.ShowDialog(); + if (form.JobDetail != null && form.Trigger != null) + { + Scheduler.GetScheduler().ScheduleJob(form.JobDetail, form.Trigger); + loadJobGroups(); + } + } + + private void btnRefreshRunningJobs_Click(object sender, EventArgs e) + { + updateRunningJobs(); + } + + private void btnRefreshJobGroups_Click(object sender, EventArgs e) + { + loadJobGroups(); + } + + private void btnRunJobNow_Click(object sender, EventArgs e) + { + JobNode node = (JobNode)jobGroupsTreeView.SelectedNode; + string job = node.Detail.Name; + string group = node.Detail.Group; + Scheduler.GetScheduler().TriggerJobWithVolatileTrigger(job, group); + } + + private void btnDeleteJob_Click(object sender, EventArgs e) + { + TreeNode selectedNode = jobGroupsTreeView.SelectedNode; + if (selectedNode is JobNode) + { + JobNode node = (JobNode)jobGroupsTreeView.SelectedNode; + string job = node.Detail.Name; + string group = node.Detail.Group; + Scheduler.GetScheduler().DeleteJob(job, group); + jobGroupsTreeView.SelectedNode.Remove(); + + } + if (selectedNode is TriggerNode) + { + Scheduler.GetScheduler().UnscheduleJob(((TriggerNode)selectedNode).Trigger.Name, ((TriggerNode)selectedNode).Trigger.Group); + } + + //loadJobGroups(); + } + + private void btnPause_Click(object sender, EventArgs e) + { + TriggerNode node = (TriggerNode)jobGroupsTreeView.SelectedNode; + string name = node.Trigger.Name; + string group = node.Trigger.Group; + if (Scheduler.GetScheduler().GetTriggerState(name, group) == TriggerState.Paused) + { + Scheduler.GetScheduler().ResumeTrigger(name, group); + } + else + { + Scheduler.GetScheduler().PauseTrigger(name, group); + } + setPauseButtonText(); + } + + private void btnEdit_Click(object sender, EventArgs e) + { + TriggerNode node = (TriggerNode)jobGroupsTreeView.SelectedNode; + AddJobForm form = new AddJobForm(node); + form.ShowDialog(); + if (form.JobDetail != null && form.Trigger != null) + { + Scheduler.GetScheduler().RescheduleJob(node.Trigger.Name, node.Trigger.Group, form.Trigger); + loadJobGroups(); + } + } + + private void backupToolStripMenuItem_Click(object sender, EventArgs e) + { + QuartzScheduler scheduler = ((SchedulerNode)((TreeView)((ContextMenuStrip)((ToolStripMenuItem)sender).Owner).SourceControl).SelectedNode).Scheduler; + FileDialog dialog = new SaveFileDialog(); + dialog.ShowDialog(); + FileInfo file = new FileInfo(dialog.FileName); + scheduler.BackupToFile(file); + } + + private void timer_Refresh_Running_Jobs_Tick(object sender, EventArgs e) + { + updateRunningJobs(); + } + } +} diff --git a/ClickForensics.Quartz.Manager/QuartzScheduler.cs b/ClickForensics.Quartz.Manager/QuartzScheduler.cs index 561e9ca..1bdcda7 100644 --- a/ClickForensics.Quartz.Manager/QuartzScheduler.cs +++ b/ClickForensics.Quartz.Manager/QuartzScheduler.cs @@ -1,311 +1,311 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Web; -using System.Collections.Specialized; -using Quartz.Impl; -using Quartz; -using System.Data; -using System.Configuration; -using System.Collections; -using System.Windows.Forms; -using System.IO; -using System.Xml.Linq; - -namespace ClickForensics.Quartz.Manager -{ - public class QuartzScheduler - { - public QuartzScheduler(string server, int port, string scheduler) - { - Address = string.Format("tcp://{0}:{1}/{2}", server, port, scheduler); - _schedulerFactory = new StdSchedulerFactory(getProperties(Address)); - - try - { - _scheduler = _schedulerFactory.GetScheduler(); - } - catch (SchedulerException se) - { - MessageBox.Show("Unable to connect to the specified server", "Connection Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); - } - } - public string Address { get; private set; } - private NameValueCollection getProperties(string address) - { - NameValueCollection properties = new NameValueCollection(); - properties["quartz.scheduler.instanceName"] = "RemoteClient"; - properties["quartz.scheduler.proxy"] = "true"; - properties["quartz.threadPool.threadCount"] = "0"; - properties["quartz.scheduler.proxy.address"] = address; - return properties; - } - public IScheduler GetScheduler() - { - return _scheduler; - } - public DataTable GetJobs() - { - DataTable table = new DataTable(); - table.Columns.Add("GroupName"); - table.Columns.Add("JobName"); - table.Columns.Add("JobDescription"); - table.Columns.Add("TriggerName"); - table.Columns.Add("TriggerGroupName"); - table.Columns.Add("TriggerType"); - table.Columns.Add("TriggerState"); - table.Columns.Add("NextFireTime"); - table.Columns.Add("PreviousFireTime"); - string[] jobGroups = GetScheduler().JobGroupNames; - foreach (string group in jobGroups) - { - string[] jobNames = GetScheduler().GetJobNames(group); - foreach (string job in jobNames) - { - JobDetail detail = GetScheduler().GetJobDetail(job, group); - Trigger[] triggers = GetScheduler().GetTriggersOfJob(job, group); - foreach (Trigger trigger in triggers) - { - DataRow row = table.NewRow(); - row["GroupName"] = group; - row["JobName"] = job; - row["JobDescription"] = detail.Description; - row["TriggerName"] = trigger.Name; - row["TriggerGroupName"] = trigger.Group; - row["TriggerType"] = trigger.GetType().Name; - row["TriggerState"] = GetScheduler().GetTriggerState(trigger.Name, trigger.Group); - DateTime? nextFireTime = trigger.GetNextFireTimeUtc(); - if (nextFireTime != null) - { - row["NextFireTime"] = TimeZone.CurrentTimeZone.ToLocalTime((DateTime)nextFireTime); - } - - DateTime? previousFireTime = trigger.GetPreviousFireTimeUtc(); - if (previousFireTime != null) - { - row["PreviousFireTime"] = TimeZone.CurrentTimeZone.ToLocalTime((DateTime)previousFireTime); - } - - table.Rows.Add(row); - } - } - } - return table; - } - - public void ScheduleOneTimeJob(Type jobType, JobDataMap dataMap, int clientID) - { - string name = string.Format("{0}-{1}", jobType.Name, clientID); - string group = clientID.ToString(); - JobDetail jobDetail = new JobDetail(name, group, jobType); - jobDetail.Description = "One time job"; - jobDetail.Durable = false; - jobDetail.Group = group; - jobDetail.JobDataMap = dataMap; - jobDetail.JobType = jobType; - jobDetail.Name = name; - jobDetail.Volatile = true; - SimpleTrigger trigger = new SimpleTrigger(); - trigger.Name = name; - trigger.Group = group; - trigger.StartTimeUtc = DateTime.UtcNow; - trigger.RepeatCount = 0; - trigger.RepeatInterval = TimeSpan.Zero; - GetScheduler().ScheduleJob(jobDetail, trigger); - } - - private ISchedulerFactory _schedulerFactory; - - private IScheduler _scheduler; - - public DataTable GetRunningJobs() - { - DataTable table = new DataTable(); - table.Columns.Add("JobName", typeof(string)); - table.Columns.Add("RunTime", typeof(int)); - try - { - IList jobs = GetScheduler().GetCurrentlyExecutingJobs(); - foreach (JobExecutionContext context in jobs) - { - DataRow row = table.NewRow(); - row["JobName"] = context.JobDetail.Name; - row["RunTime"] = (DateTime.Now.ToUniversalTime() - (DateTime)context.FireTimeUtc).TotalMinutes; - table.Rows.Add(row); - } - } - catch (Exception ex) - { - //TODO: Let the user know we couldn't load the running jobs. - } - - return table; - } - - public void BackupToFile(System.IO.FileInfo file) - { - IScheduler scheduler = GetScheduler(); - string[] jobGroupNames = scheduler.JobGroupNames; - List jobDetails = new List(); - foreach (var jobGroup in jobGroupNames) - { - string[] jobNames = scheduler.GetJobNames(jobGroup); - foreach (var jobName in jobNames) - { - jobDetails.Add(scheduler.GetJobDetail(jobName, jobGroup)); - } - } - writeToFile(file, jobDetails); - - } - - private void writeToFile(System.IO.FileInfo file, List jobDetails) - { - using (StreamWriter writer = file.CreateText()) - { - XNamespace ns = "http://quartznet.sourceforge.net/JobSchedulingData"; - XDocument doc = new XDocument(new XDeclaration("1.0", "UTF-8", "yes") - , new XElement(ns + "quartz" - , new XAttribute(XNamespace.Xmlns + "xsi", "http://www.w3.org/2001/XMLSchema-instance") - , new XAttribute("version", "1.0") - , new XAttribute("overwrite-existing-jobs", "true") - ) - ); - foreach (JobDetail detail in jobDetails) - { - doc.Root.Add( - new XElement(ns + "job" - , new XElement(ns + "job-detail" - , new XElement(ns + "name", detail.Name) - , new XElement(ns + "group", detail.Group) - , new XElement(ns + "description", detail.Description) - , new XElement(ns + "job-type", detail.JobType.FullName + "," + detail.JobType.Assembly.FullName) - , new XElement(ns + "volatile", detail.Volatile) - , new XElement(ns + "durable", detail.Durable) - , new XElement(ns + "recover", detail.RequestsRecovery) - , getJobDataMap(ns, detail.JobDataMap) - ) - , getTriggers(ns, detail) - ) - ); - } - writer.Write(doc); - writer.Flush(); - writer.Close(); - } - } - - private XElement getJobDataMap(XNamespace ns, JobDataMap jobDataMap) - { - XElement map = new XElement(ns + "job-data-map"); - foreach (var key in jobDataMap.GetKeys()) - { - map.Add(new XElement(ns + "entry" - , new XElement(ns + "key", key) - , new XElement(ns + "value", jobDataMap[key]) - ) - ); - } - - return map; - } - - private XElement[] getTriggers(XNamespace ns, JobDetail detail) - { - Trigger[] triggers = _scheduler.GetTriggersOfJob(detail.Name, detail.Group); - XElement[] elements = new XElement[triggers.Length]; - for (int i = 0; i < triggers.Length; i++) - { - elements[i] = new XElement(ns + "trigger"); - if (triggers[i] is SimpleTrigger) - { - elements[i].Add(getSimpleTrigger(ns, (SimpleTrigger)triggers[i])); - } - else if (triggers[i] is CronTrigger) - { - elements[i].Add(getCronTrigger(ns, (CronTrigger)triggers[i])); - } - } - return elements; - } - - private XElement getCronTrigger(XNamespace ns, CronTrigger trigger) - { - XElement cronTrigger = new XElement(ns + "cron"); - addCommonTriggerData(ns, cronTrigger, trigger); - cronTrigger.Add( - new XElement(ns + "cron-expression", trigger.CronExpressionString) - ); - return cronTrigger; - } - - private void addCommonTriggerData(XNamespace ns, XElement rootTriggerElement, Trigger trigger) - { - rootTriggerElement.Add( - new XElement(ns + "name", trigger.Name) - , new XElement(ns + "group", trigger.Group) - , new XElement(ns + "description", trigger.Description) - , new XElement(ns + "misfire-instruction", getMisfireInstructionText(trigger)) - , new XElement(ns + "volatile", trigger.Volatile) - , new XElement(ns + "job-name", trigger.JobName) - , new XElement(ns + "job-group", trigger.JobGroup) - ); - } - - private string getMisfireInstructionText(Trigger trigger) - { - if (trigger is CronTrigger) - { - return getCronTriggerMisfireInstructionText(trigger.MisfireInstruction); - } - return getSimpleTriggerMisfireInstructionText(trigger.MisfireInstruction); - } - - private string getSimpleTriggerMisfireInstructionText(int misfireInstruction) - { - switch (misfireInstruction) - { - case 0: - return "SmartPolicy"; - case 1: - return "FireNow"; - case 2: - return "RescheduleNowWithExistingRepeatCount"; - case 3: - return "RescheduleNowWithRemainingRepeatCount"; - case 4: - return "RescheduleNextWithRemainingCount"; - case 5: - return "RescheduleNextWithExistingCount"; - default: - throw new ArgumentOutOfRangeException(string.Format("{0} is not a supported misfire instruction for SimpleTrigger See Quartz.MisfireInstruction for more details.", misfireInstruction)); - } - } - - private string getCronTriggerMisfireInstructionText(int misfireInstruction) - { - switch (misfireInstruction) - { - case 0: - return "SmartPolicy"; - case 1: - return "FireOnceNow"; - case 2: - return "DoNothing"; - default: - throw new ArgumentOutOfRangeException(string.Format("{0} is not a supported misfire instruction for CronTrigger See Quartz.MisfireInstruction for more details.", misfireInstruction)); - } - } - - private XElement getSimpleTrigger(XNamespace ns, SimpleTrigger trigger) - { - XElement simpleTrigger = new XElement(ns + "simple"); - addCommonTriggerData(ns, simpleTrigger, trigger); - simpleTrigger.Add( - new XElement(ns + "repeat-count", trigger.RepeatCount) - , new XElement(ns + "repeat-interval", trigger.RepeatInterval.Milliseconds) - ); - return simpleTrigger; - } - } -} +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Collections.Specialized; +using Quartz.Impl; +using Quartz; +using System.Data; +using System.Configuration; +using System.Collections; +using System.Windows.Forms; +using System.IO; +using System.Xml.Linq; + +namespace ClickForensics.Quartz.Manager +{ + public class QuartzScheduler + { + public QuartzScheduler(string server, int port, string scheduler) + { + Address = string.Format("tcp://{0}:{1}/{2}", server, port, scheduler); + _schedulerFactory = new StdSchedulerFactory(getProperties(Address)); + + try + { + _scheduler = _schedulerFactory.GetScheduler(); + } + catch (SchedulerException) + { + MessageBox.Show("Unable to connect to the specified server", "Connection Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); + } + } + public string Address { get; private set; } + private NameValueCollection getProperties(string address) + { + NameValueCollection properties = new NameValueCollection(); + properties["quartz.scheduler.instanceName"] = "RemoteClient"; + properties["quartz.scheduler.proxy"] = "true"; + properties["quartz.threadPool.threadCount"] = "0"; + properties["quartz.scheduler.proxy.address"] = address; + return properties; + } + public IScheduler GetScheduler() + { + return _scheduler; + } + public DataTable GetJobs() + { + DataTable table = new DataTable(); + table.Columns.Add("GroupName"); + table.Columns.Add("JobName"); + table.Columns.Add("JobDescription"); + table.Columns.Add("TriggerName"); + table.Columns.Add("TriggerGroupName"); + table.Columns.Add("TriggerType"); + table.Columns.Add("TriggerState"); + table.Columns.Add("NextFireTime"); + table.Columns.Add("PreviousFireTime"); + string[] jobGroups = GetScheduler().JobGroupNames; + foreach (string group in jobGroups) + { + string[] jobNames = GetScheduler().GetJobNames(group); + foreach (string job in jobNames) + { + JobDetail detail = GetScheduler().GetJobDetail(job, group); + Trigger[] triggers = GetScheduler().GetTriggersOfJob(job, group); + foreach (Trigger trigger in triggers) + { + DataRow row = table.NewRow(); + row["GroupName"] = group; + row["JobName"] = job; + row["JobDescription"] = detail.Description; + row["TriggerName"] = trigger.Name; + row["TriggerGroupName"] = trigger.Group; + row["TriggerType"] = trigger.GetType().Name; + row["TriggerState"] = GetScheduler().GetTriggerState(trigger.Name, trigger.Group); + DateTime? nextFireTime = trigger.GetNextFireTimeUtc(); + if (nextFireTime != null) + { + row["NextFireTime"] = TimeZone.CurrentTimeZone.ToLocalTime((DateTime)nextFireTime); + } + + DateTime? previousFireTime = trigger.GetPreviousFireTimeUtc(); + if (previousFireTime != null) + { + row["PreviousFireTime"] = TimeZone.CurrentTimeZone.ToLocalTime((DateTime)previousFireTime); + } + + table.Rows.Add(row); + } + } + } + return table; + } + + public void ScheduleOneTimeJob(Type jobType, JobDataMap dataMap, int clientID) + { + string name = string.Format("{0}-{1}", jobType.Name, clientID); + string group = clientID.ToString(); + JobDetail jobDetail = new JobDetail(name, group, jobType); + jobDetail.Description = "One time job"; + jobDetail.Durable = false; + jobDetail.Group = group; + jobDetail.JobDataMap = dataMap; + jobDetail.JobType = jobType; + jobDetail.Name = name; + jobDetail.Volatile = true; + SimpleTrigger trigger = new SimpleTrigger(); + trigger.Name = name; + trigger.Group = group; + trigger.StartTimeUtc = DateTime.UtcNow; + trigger.RepeatCount = 0; + trigger.RepeatInterval = TimeSpan.Zero; + GetScheduler().ScheduleJob(jobDetail, trigger); + } + + private ISchedulerFactory _schedulerFactory; + + private IScheduler _scheduler; + + public DataTable GetRunningJobs() + { + DataTable table = new DataTable(); + table.Columns.Add("JobName", typeof(string)); + table.Columns.Add("RunTime", typeof(int)); + try + { + IList jobs = GetScheduler().GetCurrentlyExecutingJobs(); + foreach (JobExecutionContext context in jobs) + { + DataRow row = table.NewRow(); + row["JobName"] = context.JobDetail.Name; + row["RunTime"] = (DateTime.Now.ToUniversalTime() - (DateTime)context.FireTimeUtc).TotalMinutes; + table.Rows.Add(row); + } + } + catch (Exception ex) + { + //TODO: Let the user know we couldn't load the running jobs. + } + + return table; + } + + public void BackupToFile(System.IO.FileInfo file) + { + IScheduler scheduler = GetScheduler(); + string[] jobGroupNames = scheduler.JobGroupNames; + List jobDetails = new List(); + foreach (var jobGroup in jobGroupNames) + { + string[] jobNames = scheduler.GetJobNames(jobGroup); + foreach (var jobName in jobNames) + { + jobDetails.Add(scheduler.GetJobDetail(jobName, jobGroup)); + } + } + writeToFile(file, jobDetails); + + } + + private void writeToFile(System.IO.FileInfo file, List jobDetails) + { + using (StreamWriter writer = file.CreateText()) + { + XNamespace ns = "http://quartznet.sourceforge.net/JobSchedulingData"; + XDocument doc = new XDocument(new XDeclaration("1.0", "UTF-8", "yes") + , new XElement(ns + "quartz" + , new XAttribute(XNamespace.Xmlns + "xsi", "http://www.w3.org/2001/XMLSchema-instance") + , new XAttribute("version", "1.0") + , new XAttribute("overwrite-existing-jobs", "true") + ) + ); + foreach (JobDetail detail in jobDetails) + { + doc.Root.Add( + new XElement(ns + "job" + , new XElement(ns + "job-detail" + , new XElement(ns + "name", detail.Name) + , new XElement(ns + "group", detail.Group) + , new XElement(ns + "description", detail.Description) + , new XElement(ns + "job-type", detail.JobType.FullName + "," + detail.JobType.Assembly.FullName) + , new XElement(ns + "volatile", detail.Volatile) + , new XElement(ns + "durable", detail.Durable) + , new XElement(ns + "recover", detail.RequestsRecovery) + , getJobDataMap(ns, detail.JobDataMap) + ) + , getTriggers(ns, detail) + ) + ); + } + writer.Write(doc); + writer.Flush(); + writer.Close(); + } + } + + private XElement getJobDataMap(XNamespace ns, JobDataMap jobDataMap) + { + XElement map = new XElement(ns + "job-data-map"); + foreach (var key in jobDataMap.GetKeys()) + { + map.Add(new XElement(ns + "entry" + , new XElement(ns + "key", key) + , new XElement(ns + "value", jobDataMap[key]) + ) + ); + } + + return map; + } + + private XElement[] getTriggers(XNamespace ns, JobDetail detail) + { + Trigger[] triggers = _scheduler.GetTriggersOfJob(detail.Name, detail.Group); + XElement[] elements = new XElement[triggers.Length]; + for (int i = 0; i < triggers.Length; i++) + { + elements[i] = new XElement(ns + "trigger"); + if (triggers[i] is SimpleTrigger) + { + elements[i].Add(getSimpleTrigger(ns, (SimpleTrigger)triggers[i])); + } + else if (triggers[i] is CronTrigger) + { + elements[i].Add(getCronTrigger(ns, (CronTrigger)triggers[i])); + } + } + return elements; + } + + private XElement getCronTrigger(XNamespace ns, CronTrigger trigger) + { + XElement cronTrigger = new XElement(ns + "cron"); + addCommonTriggerData(ns, cronTrigger, trigger); + cronTrigger.Add( + new XElement(ns + "cron-expression", trigger.CronExpressionString) + ); + return cronTrigger; + } + + private void addCommonTriggerData(XNamespace ns, XElement rootTriggerElement, Trigger trigger) + { + rootTriggerElement.Add( + new XElement(ns + "name", trigger.Name) + , new XElement(ns + "group", trigger.Group) + , new XElement(ns + "description", trigger.Description) + , new XElement(ns + "misfire-instruction", getMisfireInstructionText(trigger)) + , new XElement(ns + "volatile", trigger.Volatile) + , new XElement(ns + "job-name", trigger.JobName) + , new XElement(ns + "job-group", trigger.JobGroup) + ); + } + + private string getMisfireInstructionText(Trigger trigger) + { + if (trigger is CronTrigger) + { + return getCronTriggerMisfireInstructionText(trigger.MisfireInstruction); + } + return getSimpleTriggerMisfireInstructionText(trigger.MisfireInstruction); + } + + private string getSimpleTriggerMisfireInstructionText(int misfireInstruction) + { + switch (misfireInstruction) + { + case 0: + return "SmartPolicy"; + case 1: + return "FireNow"; + case 2: + return "RescheduleNowWithExistingRepeatCount"; + case 3: + return "RescheduleNowWithRemainingRepeatCount"; + case 4: + return "RescheduleNextWithRemainingCount"; + case 5: + return "RescheduleNextWithExistingCount"; + default: + throw new ArgumentOutOfRangeException(string.Format("{0} is not a supported misfire instruction for SimpleTrigger See Quartz.MisfireInstruction for more details.", misfireInstruction)); + } + } + + private string getCronTriggerMisfireInstructionText(int misfireInstruction) + { + switch (misfireInstruction) + { + case 0: + return "SmartPolicy"; + case 1: + return "FireOnceNow"; + case 2: + return "DoNothing"; + default: + throw new ArgumentOutOfRangeException(string.Format("{0} is not a supported misfire instruction for CronTrigger See Quartz.MisfireInstruction for more details.", misfireInstruction)); + } + } + + private XElement getSimpleTrigger(XNamespace ns, SimpleTrigger trigger) + { + XElement simpleTrigger = new XElement(ns + "simple"); + addCommonTriggerData(ns, simpleTrigger, trigger); + simpleTrigger.Add( + new XElement(ns + "repeat-count", trigger.RepeatCount) + , new XElement(ns + "repeat-interval", trigger.RepeatInterval.Milliseconds) + ); + return simpleTrigger; + } + } +} diff --git a/ClickForensics.Quartz.Manager/RegistryStore.cs b/ClickForensics.Quartz.Manager/RegistryStore.cs new file mode 100644 index 0000000..08e33b5 --- /dev/null +++ b/ClickForensics.Quartz.Manager/RegistryStore.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.Win32; + +namespace ClickForensics.Quartz.Manager +{ + public class RegistryStore + { + + public static List GetLastConnections() + { + List lastConnections = new List(); + + RegistryKey key = Registry.CurrentUser.CreateSubKey("QuartzNetManager").CreateSubKey("MRUList"); + if (key != null) + { + for (int i = 0; i < 5; i++) + { + ConnectionInfo info = (ConnectionInfo)key.GetValue(string.Format("connection{0}", i), null); + if (info != null) + { + lastConnections.Add(info); + } + } + } + key.Close(); + return lastConnections; + } + public static void AddConnection(ConnectionInfo info) + { + + } + private static object lockObject = new object(); + } +} diff --git a/ClickForensics.Quartz.Manager/ServerConnectForm.Designer.cs b/ClickForensics.Quartz.Manager/ServerConnectForm.Designer.cs index 49ae7d4..e642345 100644 --- a/ClickForensics.Quartz.Manager/ServerConnectForm.Designer.cs +++ b/ClickForensics.Quartz.Manager/ServerConnectForm.Designer.cs @@ -1,143 +1,145 @@ -namespace ClickForensics.Quartz.Manager -{ - partial class ServerConnectForm - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.btnConnect = new System.Windows.Forms.Button(); - this.btnCancel = new System.Windows.Forms.Button(); - this.label1 = new System.Windows.Forms.Label(); - this.txtServer = new System.Windows.Forms.TextBox(); - this.txtPort = new System.Windows.Forms.TextBox(); - this.label2 = new System.Windows.Forms.Label(); - this.txtScheduler = new System.Windows.Forms.TextBox(); - this.label3 = new System.Windows.Forms.Label(); - this.SuspendLayout(); - // - // btnConnect - // - this.btnConnect.Location = new System.Drawing.Point(32, 87); - this.btnConnect.Name = "btnConnect"; - this.btnConnect.Size = new System.Drawing.Size(75, 23); - this.btnConnect.TabIndex = 3; - this.btnConnect.Text = "Connect"; - this.btnConnect.UseVisualStyleBackColor = true; - this.btnConnect.Click += new System.EventHandler(this.btnConnect_Click); - // - // btnCancel - // - this.btnCancel.Location = new System.Drawing.Point(115, 87); - this.btnCancel.Name = "btnCancel"; - this.btnCancel.Size = new System.Drawing.Size(75, 23); - this.btnCancel.TabIndex = 4; - this.btnCancel.Text = "Cancel"; - this.btnCancel.UseVisualStyleBackColor = true; - this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click); - // - // label1 - // - this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(29, 12); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(41, 13); - this.label1.TabIndex = 2; - this.label1.Text = "Server:"; - // - // txtServer - // - this.txtServer.Location = new System.Drawing.Point(90, 9); - this.txtServer.Name = "txtServer"; - this.txtServer.Size = new System.Drawing.Size(100, 20); - this.txtServer.TabIndex = 0; - // - // txtPort - // - this.txtPort.Location = new System.Drawing.Point(90, 35); - this.txtPort.Name = "txtPort"; - this.txtPort.Size = new System.Drawing.Size(100, 20); - this.txtPort.TabIndex = 1; - this.txtPort.Text = "555"; - // - // label2 - // - this.label2.AutoSize = true; - this.label2.Location = new System.Drawing.Point(29, 38); - this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(29, 13); - this.label2.TabIndex = 8; - this.label2.Text = "Port:"; - // - // txtScheduler - // - this.txtScheduler.Location = new System.Drawing.Point(90, 61); - this.txtScheduler.Name = "txtScheduler"; - this.txtScheduler.Size = new System.Drawing.Size(100, 20); - this.txtScheduler.TabIndex = 2; - this.txtScheduler.Text = "QuartzScheduler"; - // - // label3 - // - this.label3.AutoSize = true; - this.label3.Location = new System.Drawing.Point(29, 64); - this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(55, 13); - this.label3.TabIndex = 10; - this.label3.Text = "Scheduler"; - // - // ServerConnectForm - // - this.AcceptButton = this.btnConnect; - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(227, 141); - this.Controls.Add(this.txtScheduler); - this.Controls.Add(this.label3); - this.Controls.Add(this.txtPort); - this.Controls.Add(this.label2); - this.Controls.Add(this.txtServer); - this.Controls.Add(this.label1); - this.Controls.Add(this.btnCancel); - this.Controls.Add(this.btnConnect); - this.Name = "ServerConnectForm"; - this.Text = "ServerConnectForm"; - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.Button btnConnect; - private System.Windows.Forms.Button btnCancel; - private System.Windows.Forms.Label label1; - private System.Windows.Forms.TextBox txtServer; - private System.Windows.Forms.TextBox txtPort; - private System.Windows.Forms.Label label2; - private System.Windows.Forms.TextBox txtScheduler; - private System.Windows.Forms.Label label3; - } +namespace ClickForensics.Quartz.Manager +{ + partial class ServerConnectForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btnConnect = new System.Windows.Forms.Button(); + this.btnCancel = new System.Windows.Forms.Button(); + this.label1 = new System.Windows.Forms.Label(); + this.txtPort = new System.Windows.Forms.TextBox(); + this.label2 = new System.Windows.Forms.Label(); + this.txtScheduler = new System.Windows.Forms.TextBox(); + this.label3 = new System.Windows.Forms.Label(); + this.cboServer = new System.Windows.Forms.ComboBox(); + this.SuspendLayout(); + // + // btnConnect + // + this.btnConnect.Location = new System.Drawing.Point(32, 87); + this.btnConnect.Name = "btnConnect"; + this.btnConnect.Size = new System.Drawing.Size(75, 23); + this.btnConnect.TabIndex = 3; + this.btnConnect.Text = "Connect"; + this.btnConnect.UseVisualStyleBackColor = true; + this.btnConnect.Click += new System.EventHandler(this.btnConnect_Click); + // + // btnCancel + // + this.btnCancel.Location = new System.Drawing.Point(115, 87); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size(75, 23); + this.btnCancel.TabIndex = 4; + this.btnCancel.Text = "Cancel"; + this.btnCancel.UseVisualStyleBackColor = true; + this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(29, 12); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(41, 13); + this.label1.TabIndex = 2; + this.label1.Text = "Server:"; + // + // txtPort + // + this.txtPort.Location = new System.Drawing.Point(90, 35); + this.txtPort.Name = "txtPort"; + this.txtPort.Size = new System.Drawing.Size(100, 20); + this.txtPort.TabIndex = 1; + this.txtPort.Text = "555"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(29, 38); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(29, 13); + this.label2.TabIndex = 8; + this.label2.Text = "Port:"; + // + // txtScheduler + // + this.txtScheduler.Location = new System.Drawing.Point(90, 61); + this.txtScheduler.Name = "txtScheduler"; + this.txtScheduler.Size = new System.Drawing.Size(100, 20); + this.txtScheduler.TabIndex = 2; + this.txtScheduler.Text = "QuartzScheduler"; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(29, 64); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(55, 13); + this.label3.TabIndex = 10; + this.label3.Text = "Scheduler"; + // + // cboServer + // + this.cboServer.FormattingEnabled = true; + this.cboServer.Location = new System.Drawing.Point(90, 8); + this.cboServer.Name = "cboServer"; + this.cboServer.Size = new System.Drawing.Size(100, 21); + this.cboServer.TabIndex = 1; + this.cboServer.SelectedIndexChanged += new System.EventHandler(this.cboServer_SelectedIndexChanged); + // + // ServerConnectForm + // + this.AcceptButton = this.btnConnect; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(227, 141); + this.Controls.Add(this.cboServer); + this.Controls.Add(this.txtScheduler); + this.Controls.Add(this.label3); + this.Controls.Add(this.txtPort); + this.Controls.Add(this.label2); + this.Controls.Add(this.label1); + this.Controls.Add(this.btnCancel); + this.Controls.Add(this.btnConnect); + this.Name = "ServerConnectForm"; + this.Text = "ServerConnectForm"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button btnConnect; + private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox txtPort; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.TextBox txtScheduler; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.ComboBox cboServer; + } } \ No newline at end of file diff --git a/ClickForensics.Quartz.Manager/ServerConnectForm.cs b/ClickForensics.Quartz.Manager/ServerConnectForm.cs index 0610da6..3b544b5 100644 --- a/ClickForensics.Quartz.Manager/ServerConnectForm.cs +++ b/ClickForensics.Quartz.Manager/ServerConnectForm.cs @@ -1,37 +1,43 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Linq; -using System.Text; -using System.Windows.Forms; - -namespace ClickForensics.Quartz.Manager -{ - public partial class ServerConnectForm : Form - { - public ServerConnectForm() - { - InitializeComponent(); - } - - private void btnCancel_Click(object sender, EventArgs e) - { - this.Close(); - } - - private void btnConnect_Click(object sender, EventArgs e) - { - Server = txtServer.Text; - Port = int.Parse(txtPort.Text); - Scheduler = txtScheduler.Text; - this.Close(); - } - public string Server { get; set; } - public int Port { get; set; } - public string Scheduler { get; set; } - - - } -} +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace ClickForensics.Quartz.Manager +{ + public partial class ServerConnectForm : Form + { + public ServerConnectForm() + { + InitializeComponent(); + cboServer.DataSource = RegistryStore.GetLastConnections(); + } + + private void btnCancel_Click(object sender, EventArgs e) + { + Cancelled = true; + this.Close(); + } + + private void btnConnect_Click(object sender, EventArgs e) + { + Server = cboServer.Text; + Port = int.Parse(txtPort.Text); + Scheduler = txtScheduler.Text; + RegistryStore.AddConnection(new ConnectionInfo { ServerName = Server, Port = Port, SchedulerName = Scheduler }); + this.Close(); + } + public string Server { get; set; } + public int Port { get; set; } + public string Scheduler { get; set; } + public bool Cancelled { get; set; } + private void cboServer_SelectedIndexChanged(object sender, EventArgs e) + { + + } + } +} diff --git a/ClickForensics.Quartz.Manager/ServerConnectForm.resx b/ClickForensics.Quartz.Manager/ServerConnectForm.resx index d58980a..c7e0d4b 100644 --- a/ClickForensics.Quartz.Manager/ServerConnectForm.resx +++ b/ClickForensics.Quartz.Manager/ServerConnectForm.resx @@ -1,120 +1,120 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + \ No newline at end of file diff --git a/ClickForensics.Quartz.Manager/SimpleTriggerDisplay.Designer.cs b/ClickForensics.Quartz.Manager/SimpleTriggerDisplay.Designer.cs new file mode 100644 index 0000000..9a6a23a --- /dev/null +++ b/ClickForensics.Quartz.Manager/SimpleTriggerDisplay.Designer.cs @@ -0,0 +1,215 @@ +namespace ClickForensics.Quartz.Manager +{ + partial class SimpleTriggerDisplay + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.lblName = new System.Windows.Forms.Label(); + this.label3 = new System.Windows.Forms.Label(); + this.lblGroup = new System.Windows.Forms.Label(); + this.label5 = new System.Windows.Forms.Label(); + this.lblDescription = new System.Windows.Forms.Label(); + this.label7 = new System.Windows.Forms.Label(); + this.lblPreviousFireTime = new System.Windows.Forms.Label(); + this.label9 = new System.Windows.Forms.Label(); + this.lblNextFireTime = new System.Windows.Forms.Label(); + this.label11 = new System.Windows.Forms.Label(); + this.lblRepeatCount = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.lblRepeatInterval = new System.Windows.Forms.Label(); + this.label6 = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // lblName + // + this.lblName.AutoSize = true; + this.lblName.Location = new System.Drawing.Point(116, 15); + this.lblName.Name = "lblName"; + this.lblName.Size = new System.Drawing.Size(35, 13); + this.lblName.TabIndex = 3; + this.lblName.Text = "label2"; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(14, 15); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(38, 13); + this.label3.TabIndex = 2; + this.label3.Text = "Name:"; + // + // lblGroup + // + this.lblGroup.AutoSize = true; + this.lblGroup.Location = new System.Drawing.Point(116, 36); + this.lblGroup.Name = "lblGroup"; + this.lblGroup.Size = new System.Drawing.Size(35, 13); + this.lblGroup.TabIndex = 5; + this.lblGroup.Text = "label4"; + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Location = new System.Drawing.Point(14, 36); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(39, 13); + this.label5.TabIndex = 4; + this.label5.Text = "Group:"; + // + // lblDescription + // + this.lblDescription.AutoSize = true; + this.lblDescription.Location = new System.Drawing.Point(116, 57); + this.lblDescription.Name = "lblDescription"; + this.lblDescription.Size = new System.Drawing.Size(35, 13); + this.lblDescription.TabIndex = 7; + this.lblDescription.Text = "label6"; + // + // label7 + // + this.label7.AutoSize = true; + this.label7.Location = new System.Drawing.Point(14, 57); + this.label7.Name = "label7"; + this.label7.Size = new System.Drawing.Size(63, 13); + this.label7.TabIndex = 6; + this.label7.Text = "Description:"; + // + // lblPreviousFireTime + // + this.lblPreviousFireTime.AutoSize = true; + this.lblPreviousFireTime.Location = new System.Drawing.Point(116, 99); + this.lblPreviousFireTime.Name = "lblPreviousFireTime"; + this.lblPreviousFireTime.Size = new System.Drawing.Size(35, 13); + this.lblPreviousFireTime.TabIndex = 9; + this.lblPreviousFireTime.Text = "label8"; + // + // label9 + // + this.label9.AutoSize = true; + this.label9.Location = new System.Drawing.Point(14, 99); + this.label9.Name = "label9"; + this.label9.Size = new System.Drawing.Size(97, 13); + this.label9.TabIndex = 8; + this.label9.Text = "Previous Fire Time:"; + // + // lblNextFireTime + // + this.lblNextFireTime.AutoSize = true; + this.lblNextFireTime.Location = new System.Drawing.Point(116, 78); + this.lblNextFireTime.Name = "lblNextFireTime"; + this.lblNextFireTime.Size = new System.Drawing.Size(41, 13); + this.lblNextFireTime.TabIndex = 11; + this.lblNextFireTime.Text = "label10"; + // + // label11 + // + this.label11.AutoSize = true; + this.label11.Location = new System.Drawing.Point(14, 78); + this.label11.Name = "label11"; + this.label11.Size = new System.Drawing.Size(78, 13); + this.label11.TabIndex = 10; + this.label11.Text = "Next Fire Time:"; + // + // lblRepeatCount + // + this.lblRepeatCount.AutoSize = true; + this.lblRepeatCount.Location = new System.Drawing.Point(116, 121); + this.lblRepeatCount.Name = "lblRepeatCount"; + this.lblRepeatCount.Size = new System.Drawing.Size(35, 13); + this.lblRepeatCount.TabIndex = 13; + this.lblRepeatCount.Text = "label8"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(14, 121); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(76, 13); + this.label2.TabIndex = 12; + this.label2.Text = "Repeat Count:"; + // + // lblRepeatInterval + // + this.lblRepeatInterval.AutoSize = true; + this.lblRepeatInterval.Location = new System.Drawing.Point(116, 144); + this.lblRepeatInterval.Name = "lblRepeatInterval"; + this.lblRepeatInterval.Size = new System.Drawing.Size(35, 13); + this.lblRepeatInterval.TabIndex = 15; + this.lblRepeatInterval.Text = "label8"; + // + // label6 + // + this.label6.AutoSize = true; + this.label6.Location = new System.Drawing.Point(14, 144); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(83, 13); + this.label6.TabIndex = 14; + this.label6.Text = "Repeat Interval:"; + // + // SimpleTriggerDisplay + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.lblRepeatInterval); + this.Controls.Add(this.label6); + this.Controls.Add(this.lblRepeatCount); + this.Controls.Add(this.label2); + this.Controls.Add(this.lblNextFireTime); + this.Controls.Add(this.label11); + this.Controls.Add(this.lblPreviousFireTime); + this.Controls.Add(this.label9); + this.Controls.Add(this.lblDescription); + this.Controls.Add(this.label7); + this.Controls.Add(this.lblGroup); + this.Controls.Add(this.label5); + this.Controls.Add(this.lblName); + this.Controls.Add(this.label3); + this.Name = "SimpleTriggerDisplay"; + this.Size = new System.Drawing.Size(324, 168); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label lblName; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Label lblGroup; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.Label lblDescription; + private System.Windows.Forms.Label label7; + private System.Windows.Forms.Label lblPreviousFireTime; + private System.Windows.Forms.Label label9; + private System.Windows.Forms.Label lblNextFireTime; + private System.Windows.Forms.Label label11; + private System.Windows.Forms.Label lblRepeatCount; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label lblRepeatInterval; + private System.Windows.Forms.Label label6; + } +} diff --git a/ClickForensics.Quartz.Manager/SimpleTriggerDisplay.cs b/ClickForensics.Quartz.Manager/SimpleTriggerDisplay.cs new file mode 100644 index 0000000..468854f --- /dev/null +++ b/ClickForensics.Quartz.Manager/SimpleTriggerDisplay.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using Quartz; + +namespace ClickForensics.Quartz.Manager +{ + public partial class SimpleTriggerDisplay : UserControl + { + public SimpleTriggerDisplay() + { + InitializeComponent(); + this.Load += new EventHandler(SimpleTriggerDisplay_Load); + } + + void SimpleTriggerDisplay_Load(object sender, EventArgs e) + { + lblDescription.Text = _trigger.Description; + lblGroup.Text = _trigger.Group; + lblName.Text = _trigger.Name; + if (_trigger.GetNextFireTimeUtc().HasValue) + { + lblNextFireTime.Text = _trigger.GetNextFireTimeUtc().Value.ToLocalTime().ToString(); + } + else + { + lblNextFireTime.Text = "Unknown"; + } + + if (_trigger.GetPreviousFireTimeUtc().HasValue) + { + lblPreviousFireTime.Text = _trigger.GetPreviousFireTimeUtc().Value.ToLocalTime().ToString(); + } + else + { + lblPreviousFireTime.Text = "Unknown"; + } + lblRepeatCount.Text = _trigger.RepeatCount.ToString(); + lblRepeatInterval.Text = _trigger.RepeatInterval.ToString(); + } + public SimpleTriggerDisplay(SimpleTrigger trigger) + : this() + { + _trigger = trigger; + + } + + private SimpleTrigger _trigger; + } +} diff --git a/ClickForensics.Quartz.Manager/SimpleTriggerDisplay.resx b/ClickForensics.Quartz.Manager/SimpleTriggerDisplay.resx new file mode 100644 index 0000000..c7e0d4b --- /dev/null +++ b/ClickForensics.Quartz.Manager/SimpleTriggerDisplay.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file