| @@ -1,199 +1,210 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | |||
| <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |||
| <PropertyGroup> | |||
| <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> | |||
| <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> | |||
| <ProductVersion>9.0.30729</ProductVersion> | |||
| <SchemaVersion>2.0</SchemaVersion> | |||
| <ProjectGuid>{D23DACFA-11A1-480E-A6C4-1F37B564523D}</ProjectGuid> | |||
| <OutputType>WinExe</OutputType> | |||
| <AppDesignerFolder>Properties</AppDesignerFolder> | |||
| <RootNamespace>ClickForensics.Quartz.Manager</RootNamespace> | |||
| <AssemblyName>ClickForensics.Quartz.Manager</AssemblyName> | |||
| <TargetFrameworkVersion>v4.0</TargetFrameworkVersion> | |||
| <FileAlignment>512</FileAlignment> | |||
| <FileUpgradeFlags> | |||
| </FileUpgradeFlags> | |||
| <OldToolsVersion>3.5</OldToolsVersion> | |||
| <UpgradeBackupLocation /> | |||
| <TargetFrameworkProfile /> | |||
| <PublishUrl>publish\</PublishUrl> | |||
| <Install>true</Install> | |||
| <InstallFrom>Disk</InstallFrom> | |||
| <UpdateEnabled>false</UpdateEnabled> | |||
| <UpdateMode>Foreground</UpdateMode> | |||
| <UpdateInterval>7</UpdateInterval> | |||
| <UpdateIntervalUnits>Days</UpdateIntervalUnits> | |||
| <UpdatePeriodically>false</UpdatePeriodically> | |||
| <UpdateRequired>false</UpdateRequired> | |||
| <MapFileExtensions>true</MapFileExtensions> | |||
| <ApplicationRevision>0</ApplicationRevision> | |||
| <ApplicationVersion>1.0.0.%2a</ApplicationVersion> | |||
| <IsWebBootstrapper>false</IsWebBootstrapper> | |||
| <UseApplicationTrust>false</UseApplicationTrust> | |||
| <BootstrapperEnabled>true</BootstrapperEnabled> | |||
| </PropertyGroup> | |||
| <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> | |||
| <DebugSymbols>true</DebugSymbols> | |||
| <DebugType>full</DebugType> | |||
| <Optimize>false</Optimize> | |||
| <OutputPath>bin\Debug\</OutputPath> | |||
| <DefineConstants>DEBUG;TRACE</DefineConstants> | |||
| <ErrorReport>prompt</ErrorReport> | |||
| <WarningLevel>4</WarningLevel> | |||
| </PropertyGroup> | |||
| <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> | |||
| <DebugType>pdbonly</DebugType> | |||
| <Optimize>true</Optimize> | |||
| <OutputPath>bin\Release\</OutputPath> | |||
| <DefineConstants>TRACE</DefineConstants> | |||
| <ErrorReport>prompt</ErrorReport> | |||
| <WarningLevel>4</WarningLevel> | |||
| </PropertyGroup> | |||
| <ItemGroup> | |||
| <Reference Include="Common.Logging"> | |||
| <HintPath>..\lib\Common.Logging.dll</HintPath> | |||
| </Reference> | |||
| <Reference Include="Quartz"> | |||
| <HintPath>..\lib\Quartz.dll</HintPath> | |||
| </Reference> | |||
| <Reference Include="System" /> | |||
| <Reference Include="System.configuration" /> | |||
| <Reference Include="System.Core"> | |||
| <RequiredTargetFramework>3.5</RequiredTargetFramework> | |||
| </Reference> | |||
| <Reference Include="System.Xml.Linq"> | |||
| <RequiredTargetFramework>3.5</RequiredTargetFramework> | |||
| </Reference> | |||
| <Reference Include="System.Data.DataSetExtensions"> | |||
| <RequiredTargetFramework>3.5</RequiredTargetFramework> | |||
| </Reference> | |||
| <Reference Include="System.Data" /> | |||
| <Reference Include="System.Deployment" /> | |||
| <Reference Include="System.Drawing" /> | |||
| <Reference Include="System.Windows.Forms" /> | |||
| <Reference Include="System.Xml" /> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <Compile Include="AddJobForm.cs"> | |||
| <SubType>Form</SubType> | |||
| </Compile> | |||
| <Compile Include="AddJobForm.Designer.cs"> | |||
| <DependentUpon>AddJobForm.cs</DependentUpon> | |||
| </Compile> | |||
| <Compile Include="AddListenerForm.cs"> | |||
| <SubType>Form</SubType> | |||
| </Compile> | |||
| <Compile Include="AddListenerForm.Designer.cs"> | |||
| <DependentUpon>AddListenerForm.cs</DependentUpon> | |||
| </Compile> | |||
| <Compile Include="ErrorDialog.cs"> | |||
| <SubType>Form</SubType> | |||
| </Compile> | |||
| <Compile Include="ErrorDialog.Designer.cs"> | |||
| <DependentUpon>ErrorDialog.cs</DependentUpon> | |||
| </Compile> | |||
| <Compile Include="JobType.cs" /> | |||
| <Compile Include="NativeJobDetailDisplay.cs"> | |||
| <SubType>UserControl</SubType> | |||
| </Compile> | |||
| <Compile Include="NativeJobDetailDisplay.Designer.cs"> | |||
| <DependentUpon>NativeJobDetailDisplay.cs</DependentUpon> | |||
| </Compile> | |||
| <Compile Include="JobNode.cs" /> | |||
| <Compile Include="MainForm.cs"> | |||
| <SubType>Form</SubType> | |||
| </Compile> | |||
| <Compile Include="MainForm.Designer.cs"> | |||
| <DependentUpon>MainForm.cs</DependentUpon> | |||
| </Compile> | |||
| <Compile Include="Program.cs" /> | |||
| <Compile Include="Properties\AssemblyInfo.cs" /> | |||
| <EmbeddedResource Include="AddJobForm.resx"> | |||
| <DependentUpon>AddJobForm.cs</DependentUpon> | |||
| </EmbeddedResource> | |||
| <EmbeddedResource Include="AddListenerForm.resx"> | |||
| <DependentUpon>AddListenerForm.cs</DependentUpon> | |||
| </EmbeddedResource> | |||
| <EmbeddedResource Include="CronTriggerDisplay.resx"> | |||
| <DependentUpon>CronTriggerDisplay.cs</DependentUpon> | |||
| </EmbeddedResource> | |||
| <EmbeddedResource Include="ErrorDialog.resx"> | |||
| <DependentUpon>ErrorDialog.cs</DependentUpon> | |||
| </EmbeddedResource> | |||
| <EmbeddedResource Include="MainForm.resx"> | |||
| <DependentUpon>MainForm.cs</DependentUpon> | |||
| </EmbeddedResource> | |||
| <EmbeddedResource Include="NativeJobDetailDisplay.resx"> | |||
| <DependentUpon>NativeJobDetailDisplay.cs</DependentUpon> | |||
| </EmbeddedResource> | |||
| <EmbeddedResource Include="Properties\Resources.resx"> | |||
| <Generator>ResXFileCodeGenerator</Generator> | |||
| <LastGenOutput>Resources.Designer.cs</LastGenOutput> | |||
| <SubType>Designer</SubType> | |||
| </EmbeddedResource> | |||
| <EmbeddedResource Include="ServerConnectForm.resx"> | |||
| <DependentUpon>ServerConnectForm.cs</DependentUpon> | |||
| </EmbeddedResource> | |||
| <Compile Include="Properties\Resources.Designer.cs"> | |||
| <AutoGen>True</AutoGen> | |||
| <DependentUpon>Resources.resx</DependentUpon> | |||
| <DesignTime>True</DesignTime> | |||
| </Compile> | |||
| <None Include="app.config" /> | |||
| <None Include="Properties\Settings.settings"> | |||
| <Generator>SettingsSingleFileGenerator</Generator> | |||
| <LastGenOutput>Settings.Designer.cs</LastGenOutput> | |||
| </None> | |||
| <Compile Include="Properties\Settings.Designer.cs"> | |||
| <AutoGen>True</AutoGen> | |||
| <DependentUpon>Settings.settings</DependentUpon> | |||
| <DesignTimeSharedInput>True</DesignTimeSharedInput> | |||
| </Compile> | |||
| <Compile Include="QuartzScheduler.cs" /> | |||
| <Compile Include="SchedulerNode.cs" /> | |||
| <Compile Include="ServerConnectForm.cs"> | |||
| <SubType>Form</SubType> | |||
| </Compile> | |||
| <Compile Include="ServerConnectForm.Designer.cs"> | |||
| <DependentUpon>ServerConnectForm.cs</DependentUpon> | |||
| </Compile> | |||
| <Compile Include="CronTriggerDisplay.cs"> | |||
| <SubType>UserControl</SubType> | |||
| </Compile> | |||
| <Compile Include="CronTriggerDisplay.Designer.cs"> | |||
| <DependentUpon>CronTriggerDisplay.cs</DependentUpon> | |||
| </Compile> | |||
| <Compile Include="TriggerNode.cs" /> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <Content Include="JobAssemblies.txt"> | |||
| <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | |||
| </Content> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <BootstrapperPackage Include="Microsoft.Net.Client.3.5"> | |||
| <Visible>False</Visible> | |||
| <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName> | |||
| <Install>false</Install> | |||
| </BootstrapperPackage> | |||
| <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1"> | |||
| <Visible>False</Visible> | |||
| <ProductName>.NET Framework 3.5 SP1</ProductName> | |||
| <Install>true</Install> | |||
| </BootstrapperPackage> | |||
| <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1"> | |||
| <Visible>False</Visible> | |||
| <ProductName>Windows Installer 3.1</ProductName> | |||
| <Install>true</Install> | |||
| </BootstrapperPackage> | |||
| </ItemGroup> | |||
| <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> | |||
| <?xml version="1.0" encoding="utf-8"?> | |||
| <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |||
| <PropertyGroup> | |||
| <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> | |||
| <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> | |||
| <ProductVersion>9.0.30729</ProductVersion> | |||
| <SchemaVersion>2.0</SchemaVersion> | |||
| <ProjectGuid>{D23DACFA-11A1-480E-A6C4-1F37B564523D}</ProjectGuid> | |||
| <OutputType>WinExe</OutputType> | |||
| <AppDesignerFolder>Properties</AppDesignerFolder> | |||
| <RootNamespace>ClickForensics.Quartz.Manager</RootNamespace> | |||
| <AssemblyName>ClickForensics.Quartz.Manager</AssemblyName> | |||
| <TargetFrameworkVersion>v4.0</TargetFrameworkVersion> | |||
| <FileAlignment>512</FileAlignment> | |||
| <FileUpgradeFlags> | |||
| </FileUpgradeFlags> | |||
| <OldToolsVersion>3.5</OldToolsVersion> | |||
| <UpgradeBackupLocation /> | |||
| <TargetFrameworkProfile /> | |||
| <PublishUrl>publish\</PublishUrl> | |||
| <Install>true</Install> | |||
| <InstallFrom>Disk</InstallFrom> | |||
| <UpdateEnabled>false</UpdateEnabled> | |||
| <UpdateMode>Foreground</UpdateMode> | |||
| <UpdateInterval>7</UpdateInterval> | |||
| <UpdateIntervalUnits>Days</UpdateIntervalUnits> | |||
| <UpdatePeriodically>false</UpdatePeriodically> | |||
| <UpdateRequired>false</UpdateRequired> | |||
| <MapFileExtensions>true</MapFileExtensions> | |||
| <ApplicationRevision>0</ApplicationRevision> | |||
| <ApplicationVersion>1.0.0.%2a</ApplicationVersion> | |||
| <IsWebBootstrapper>false</IsWebBootstrapper> | |||
| <UseApplicationTrust>false</UseApplicationTrust> | |||
| <BootstrapperEnabled>true</BootstrapperEnabled> | |||
| </PropertyGroup> | |||
| <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> | |||
| <DebugSymbols>true</DebugSymbols> | |||
| <DebugType>full</DebugType> | |||
| <Optimize>false</Optimize> | |||
| <OutputPath>bin\Debug\</OutputPath> | |||
| <DefineConstants>DEBUG;TRACE</DefineConstants> | |||
| <ErrorReport>prompt</ErrorReport> | |||
| <WarningLevel>4</WarningLevel> | |||
| </PropertyGroup> | |||
| <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> | |||
| <DebugType>pdbonly</DebugType> | |||
| <Optimize>true</Optimize> | |||
| <OutputPath>bin\Release\</OutputPath> | |||
| <DefineConstants>TRACE</DefineConstants> | |||
| <ErrorReport>prompt</ErrorReport> | |||
| <WarningLevel>4</WarningLevel> | |||
| </PropertyGroup> | |||
| <ItemGroup> | |||
| <Reference Include="Common.Logging"> | |||
| <HintPath>..\lib\Common.Logging.dll</HintPath> | |||
| </Reference> | |||
| <Reference Include="Quartz"> | |||
| <HintPath>..\lib\Quartz.dll</HintPath> | |||
| </Reference> | |||
| <Reference Include="System" /> | |||
| <Reference Include="System.configuration" /> | |||
| <Reference Include="System.Core"> | |||
| <RequiredTargetFramework>3.5</RequiredTargetFramework> | |||
| </Reference> | |||
| <Reference Include="System.Xml.Linq"> | |||
| <RequiredTargetFramework>3.5</RequiredTargetFramework> | |||
| </Reference> | |||
| <Reference Include="System.Data.DataSetExtensions"> | |||
| <RequiredTargetFramework>3.5</RequiredTargetFramework> | |||
| </Reference> | |||
| <Reference Include="System.Data" /> | |||
| <Reference Include="System.Deployment" /> | |||
| <Reference Include="System.Drawing" /> | |||
| <Reference Include="System.Windows.Forms" /> | |||
| <Reference Include="System.Xml" /> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <Compile Include="AddJobForm.cs"> | |||
| <SubType>Form</SubType> | |||
| </Compile> | |||
| <Compile Include="AddJobForm.Designer.cs"> | |||
| <DependentUpon>AddJobForm.cs</DependentUpon> | |||
| </Compile> | |||
| <Compile Include="AddListenerForm.cs"> | |||
| <SubType>Form</SubType> | |||
| </Compile> | |||
| <Compile Include="AddListenerForm.Designer.cs"> | |||
| <DependentUpon>AddListenerForm.cs</DependentUpon> | |||
| </Compile> | |||
| <Compile Include="ConnectionInfo.cs" /> | |||
| <Compile Include="SimpleTriggerDisplay.cs"> | |||
| <SubType>UserControl</SubType> | |||
| </Compile> | |||
| <Compile Include="SimpleTriggerDisplay.Designer.cs"> | |||
| <DependentUpon>SimpleTriggerDisplay.cs</DependentUpon> | |||
| </Compile> | |||
| <Compile Include="ErrorDialog.cs"> | |||
| <SubType>Form</SubType> | |||
| </Compile> | |||
| <Compile Include="ErrorDialog.Designer.cs"> | |||
| <DependentUpon>ErrorDialog.cs</DependentUpon> | |||
| </Compile> | |||
| <Compile Include="JobType.cs" /> | |||
| <Compile Include="NativeJobDetailDisplay.cs"> | |||
| <SubType>UserControl</SubType> | |||
| </Compile> | |||
| <Compile Include="NativeJobDetailDisplay.Designer.cs"> | |||
| <DependentUpon>NativeJobDetailDisplay.cs</DependentUpon> | |||
| </Compile> | |||
| <Compile Include="JobNode.cs" /> | |||
| <Compile Include="MainForm.cs"> | |||
| <SubType>Form</SubType> | |||
| </Compile> | |||
| <Compile Include="MainForm.Designer.cs"> | |||
| <DependentUpon>MainForm.cs</DependentUpon> | |||
| </Compile> | |||
| <Compile Include="Program.cs" /> | |||
| <Compile Include="Properties\AssemblyInfo.cs" /> | |||
| <EmbeddedResource Include="AddJobForm.resx"> | |||
| <DependentUpon>AddJobForm.cs</DependentUpon> | |||
| </EmbeddedResource> | |||
| <EmbeddedResource Include="AddListenerForm.resx"> | |||
| <DependentUpon>AddListenerForm.cs</DependentUpon> | |||
| </EmbeddedResource> | |||
| <EmbeddedResource Include="SimpleTriggerDisplay.resx"> | |||
| <DependentUpon>SimpleTriggerDisplay.cs</DependentUpon> | |||
| </EmbeddedResource> | |||
| <EmbeddedResource Include="CronTriggerDisplay.resx"> | |||
| <DependentUpon>CronTriggerDisplay.cs</DependentUpon> | |||
| </EmbeddedResource> | |||
| <EmbeddedResource Include="ErrorDialog.resx"> | |||
| <DependentUpon>ErrorDialog.cs</DependentUpon> | |||
| </EmbeddedResource> | |||
| <EmbeddedResource Include="MainForm.resx"> | |||
| <DependentUpon>MainForm.cs</DependentUpon> | |||
| </EmbeddedResource> | |||
| <EmbeddedResource Include="NativeJobDetailDisplay.resx"> | |||
| <DependentUpon>NativeJobDetailDisplay.cs</DependentUpon> | |||
| </EmbeddedResource> | |||
| <EmbeddedResource Include="Properties\Resources.resx"> | |||
| <Generator>ResXFileCodeGenerator</Generator> | |||
| <LastGenOutput>Resources.Designer.cs</LastGenOutput> | |||
| <SubType>Designer</SubType> | |||
| </EmbeddedResource> | |||
| <EmbeddedResource Include="ServerConnectForm.resx"> | |||
| <DependentUpon>ServerConnectForm.cs</DependentUpon> | |||
| </EmbeddedResource> | |||
| <Compile Include="Properties\Resources.Designer.cs"> | |||
| <AutoGen>True</AutoGen> | |||
| <DependentUpon>Resources.resx</DependentUpon> | |||
| <DesignTime>True</DesignTime> | |||
| </Compile> | |||
| <None Include="app.config" /> | |||
| <None Include="Properties\Settings.settings"> | |||
| <Generator>SettingsSingleFileGenerator</Generator> | |||
| <LastGenOutput>Settings.Designer.cs</LastGenOutput> | |||
| </None> | |||
| <Compile Include="Properties\Settings.Designer.cs"> | |||
| <AutoGen>True</AutoGen> | |||
| <DependentUpon>Settings.settings</DependentUpon> | |||
| <DesignTimeSharedInput>True</DesignTimeSharedInput> | |||
| </Compile> | |||
| <Compile Include="QuartzScheduler.cs" /> | |||
| <Compile Include="RegistryMRU.cs" /> | |||
| <Compile Include="SchedulerNode.cs" /> | |||
| <Compile Include="ServerConnectForm.cs"> | |||
| <SubType>Form</SubType> | |||
| </Compile> | |||
| <Compile Include="ServerConnectForm.Designer.cs"> | |||
| <DependentUpon>ServerConnectForm.cs</DependentUpon> | |||
| </Compile> | |||
| <Compile Include="CronTriggerDisplay.cs"> | |||
| <SubType>UserControl</SubType> | |||
| </Compile> | |||
| <Compile Include="CronTriggerDisplay.Designer.cs"> | |||
| <DependentUpon>CronTriggerDisplay.cs</DependentUpon> | |||
| </Compile> | |||
| <Compile Include="TriggerNode.cs" /> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <Content Include="JobAssemblies.txt"> | |||
| <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | |||
| </Content> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <BootstrapperPackage Include="Microsoft.Net.Client.3.5"> | |||
| <Visible>False</Visible> | |||
| <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName> | |||
| <Install>false</Install> | |||
| </BootstrapperPackage> | |||
| <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1"> | |||
| <Visible>False</Visible> | |||
| <ProductName>.NET Framework 3.5 SP1</ProductName> | |||
| <Install>true</Install> | |||
| </BootstrapperPackage> | |||
| <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1"> | |||
| <Visible>False</Visible> | |||
| <ProductName>Windows Installer 3.1</ProductName> | |||
| <Install>true</Install> | |||
| </BootstrapperPackage> | |||
| </ItemGroup> | |||
| <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> | |||
| <!-- To modify your build process, add your task inside one of the targets below and uncomment it. | |||
| Other similar extension points exist, see Microsoft.Common.targets. | |||
| <Target Name="BeforeBuild"> | |||
| </Target> | |||
| <Target Name="AfterBuild"> | |||
| </Target> | |||
| --> | |||
| --> | |||
| </Project> | |||
| @@ -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; } | |||
| } | |||
| } | |||
| @@ -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(); | |||
| } | |||
| } | |||
| } | |||
| @@ -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<JobDetail> jobDetails = new List<JobDetail>(); | |||
| 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<JobDetail> 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<JobDetail> jobDetails = new List<JobDetail>(); | |||
| 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<JobDetail> 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; | |||
| } | |||
| } | |||
| } | |||
| @@ -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<ConnectionInfo> GetLastConnections() | |||
| { | |||
| List<ConnectionInfo> lastConnections = new List<ConnectionInfo>(); | |||
| 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(); | |||
| } | |||
| } | |||
| @@ -1,143 +1,145 @@ | |||
| namespace ClickForensics.Quartz.Manager | |||
| { | |||
| partial class ServerConnectForm | |||
| { | |||
| /// <summary> | |||
| /// Required designer variable. | |||
| /// </summary> | |||
| private System.ComponentModel.IContainer components = null; | |||
| /// <summary> | |||
| /// Clean up any resources being used. | |||
| /// </summary> | |||
| /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> | |||
| protected override void Dispose(bool disposing) | |||
| { | |||
| if (disposing && (components != null)) | |||
| { | |||
| components.Dispose(); | |||
| } | |||
| base.Dispose(disposing); | |||
| } | |||
| #region Windows Form Designer generated code | |||
| /// <summary> | |||
| /// Required method for Designer support - do not modify | |||
| /// the contents of this method with the code editor. | |||
| /// </summary> | |||
| 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 | |||
| { | |||
| /// <summary> | |||
| /// Required designer variable. | |||
| /// </summary> | |||
| private System.ComponentModel.IContainer components = null; | |||
| /// <summary> | |||
| /// Clean up any resources being used. | |||
| /// </summary> | |||
| /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> | |||
| protected override void Dispose(bool disposing) | |||
| { | |||
| if (disposing && (components != null)) | |||
| { | |||
| components.Dispose(); | |||
| } | |||
| base.Dispose(disposing); | |||
| } | |||
| #region Windows Form Designer generated code | |||
| /// <summary> | |||
| /// Required method for Designer support - do not modify | |||
| /// the contents of this method with the code editor. | |||
| /// </summary> | |||
| 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; | |||
| } | |||
| } | |||
| @@ -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) | |||
| { | |||
| } | |||
| } | |||
| } | |||
| @@ -1,120 +1,120 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | |||
| <root> | |||
| <!-- | |||
| Microsoft ResX Schema | |||
| Version 2.0 | |||
| The primary goals of this format is to allow a simple XML format | |||
| that is mostly human readable. The generation and parsing of the | |||
| various data types are done through the TypeConverter classes | |||
| associated with the data types. | |||
| Example: | |||
| ... ado.net/XML headers & schema ... | |||
| <resheader name="resmimetype">text/microsoft-resx</resheader> | |||
| <resheader name="version">2.0</resheader> | |||
| <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> | |||
| <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> | |||
| <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> | |||
| <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> | |||
| <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> | |||
| <value>[base64 mime encoded serialized .NET Framework object]</value> | |||
| </data> | |||
| <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> | |||
| <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> | |||
| <comment>This is a comment</comment> | |||
| </data> | |||
| There are any number of "resheader" rows that contain simple | |||
| name/value pairs. | |||
| Each data row contains a name, and value. The row also contains a | |||
| type or mimetype. Type corresponds to a .NET class that support | |||
| text/value conversion through the TypeConverter architecture. | |||
| Classes that don't support this are serialized and stored with the | |||
| mimetype set. | |||
| The mimetype is used for serialized objects, and tells the | |||
| ResXResourceReader how to depersist the object. This is currently not | |||
| extensible. For a given mimetype the value must be set accordingly: | |||
| Note - application/x-microsoft.net.object.binary.base64 is the format | |||
| that the ResXResourceWriter will generate, however the reader can | |||
| read any of the formats listed below. | |||
| mimetype: application/x-microsoft.net.object.binary.base64 | |||
| value : The object must be serialized with | |||
| : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter | |||
| : and then encoded with base64 encoding. | |||
| mimetype: application/x-microsoft.net.object.soap.base64 | |||
| value : The object must be serialized with | |||
| : System.Runtime.Serialization.Formatters.Soap.SoapFormatter | |||
| : and then encoded with base64 encoding. | |||
| mimetype: application/x-microsoft.net.object.bytearray.base64 | |||
| value : The object must be serialized into a byte array | |||
| : using a System.ComponentModel.TypeConverter | |||
| : and then encoded with base64 encoding. | |||
| --> | |||
| <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> | |||
| <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> | |||
| <xsd:element name="root" msdata:IsDataSet="true"> | |||
| <xsd:complexType> | |||
| <xsd:choice maxOccurs="unbounded"> | |||
| <xsd:element name="metadata"> | |||
| <xsd:complexType> | |||
| <xsd:sequence> | |||
| <xsd:element name="value" type="xsd:string" minOccurs="0" /> | |||
| </xsd:sequence> | |||
| <xsd:attribute name="name" use="required" type="xsd:string" /> | |||
| <xsd:attribute name="type" type="xsd:string" /> | |||
| <xsd:attribute name="mimetype" type="xsd:string" /> | |||
| <xsd:attribute ref="xml:space" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| <xsd:element name="assembly"> | |||
| <xsd:complexType> | |||
| <xsd:attribute name="alias" type="xsd:string" /> | |||
| <xsd:attribute name="name" type="xsd:string" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| <xsd:element name="data"> | |||
| <xsd:complexType> | |||
| <xsd:sequence> | |||
| <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> | |||
| <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> | |||
| </xsd:sequence> | |||
| <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> | |||
| <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> | |||
| <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> | |||
| <xsd:attribute ref="xml:space" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| <xsd:element name="resheader"> | |||
| <xsd:complexType> | |||
| <xsd:sequence> | |||
| <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> | |||
| </xsd:sequence> | |||
| <xsd:attribute name="name" type="xsd:string" use="required" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| </xsd:choice> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| </xsd:schema> | |||
| <resheader name="resmimetype"> | |||
| <value>text/microsoft-resx</value> | |||
| </resheader> | |||
| <resheader name="version"> | |||
| <value>2.0</value> | |||
| </resheader> | |||
| <resheader name="reader"> | |||
| <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||
| </resheader> | |||
| <resheader name="writer"> | |||
| <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||
| </resheader> | |||
| <?xml version="1.0" encoding="utf-8"?> | |||
| <root> | |||
| <!-- | |||
| Microsoft ResX Schema | |||
| Version 2.0 | |||
| The primary goals of this format is to allow a simple XML format | |||
| that is mostly human readable. The generation and parsing of the | |||
| various data types are done through the TypeConverter classes | |||
| associated with the data types. | |||
| Example: | |||
| ... ado.net/XML headers & schema ... | |||
| <resheader name="resmimetype">text/microsoft-resx</resheader> | |||
| <resheader name="version">2.0</resheader> | |||
| <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> | |||
| <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> | |||
| <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> | |||
| <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> | |||
| <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> | |||
| <value>[base64 mime encoded serialized .NET Framework object]</value> | |||
| </data> | |||
| <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> | |||
| <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> | |||
| <comment>This is a comment</comment> | |||
| </data> | |||
| There are any number of "resheader" rows that contain simple | |||
| name/value pairs. | |||
| Each data row contains a name, and value. The row also contains a | |||
| type or mimetype. Type corresponds to a .NET class that support | |||
| text/value conversion through the TypeConverter architecture. | |||
| Classes that don't support this are serialized and stored with the | |||
| mimetype set. | |||
| The mimetype is used for serialized objects, and tells the | |||
| ResXResourceReader how to depersist the object. This is currently not | |||
| extensible. For a given mimetype the value must be set accordingly: | |||
| Note - application/x-microsoft.net.object.binary.base64 is the format | |||
| that the ResXResourceWriter will generate, however the reader can | |||
| read any of the formats listed below. | |||
| mimetype: application/x-microsoft.net.object.binary.base64 | |||
| value : The object must be serialized with | |||
| : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter | |||
| : and then encoded with base64 encoding. | |||
| mimetype: application/x-microsoft.net.object.soap.base64 | |||
| value : The object must be serialized with | |||
| : System.Runtime.Serialization.Formatters.Soap.SoapFormatter | |||
| : and then encoded with base64 encoding. | |||
| mimetype: application/x-microsoft.net.object.bytearray.base64 | |||
| value : The object must be serialized into a byte array | |||
| : using a System.ComponentModel.TypeConverter | |||
| : and then encoded with base64 encoding. | |||
| --> | |||
| <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> | |||
| <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> | |||
| <xsd:element name="root" msdata:IsDataSet="true"> | |||
| <xsd:complexType> | |||
| <xsd:choice maxOccurs="unbounded"> | |||
| <xsd:element name="metadata"> | |||
| <xsd:complexType> | |||
| <xsd:sequence> | |||
| <xsd:element name="value" type="xsd:string" minOccurs="0" /> | |||
| </xsd:sequence> | |||
| <xsd:attribute name="name" use="required" type="xsd:string" /> | |||
| <xsd:attribute name="type" type="xsd:string" /> | |||
| <xsd:attribute name="mimetype" type="xsd:string" /> | |||
| <xsd:attribute ref="xml:space" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| <xsd:element name="assembly"> | |||
| <xsd:complexType> | |||
| <xsd:attribute name="alias" type="xsd:string" /> | |||
| <xsd:attribute name="name" type="xsd:string" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| <xsd:element name="data"> | |||
| <xsd:complexType> | |||
| <xsd:sequence> | |||
| <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> | |||
| <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> | |||
| </xsd:sequence> | |||
| <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> | |||
| <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> | |||
| <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> | |||
| <xsd:attribute ref="xml:space" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| <xsd:element name="resheader"> | |||
| <xsd:complexType> | |||
| <xsd:sequence> | |||
| <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> | |||
| </xsd:sequence> | |||
| <xsd:attribute name="name" type="xsd:string" use="required" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| </xsd:choice> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| </xsd:schema> | |||
| <resheader name="resmimetype"> | |||
| <value>text/microsoft-resx</value> | |||
| </resheader> | |||
| <resheader name="version"> | |||
| <value>2.0</value> | |||
| </resheader> | |||
| <resheader name="reader"> | |||
| <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||
| </resheader> | |||
| <resheader name="writer"> | |||
| <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||
| </resheader> | |||
| </root> | |||
| @@ -0,0 +1,215 @@ | |||
| namespace ClickForensics.Quartz.Manager | |||
| { | |||
| partial class SimpleTriggerDisplay | |||
| { | |||
| /// <summary> | |||
| /// Required designer variable. | |||
| /// </summary> | |||
| private System.ComponentModel.IContainer components = null; | |||
| /// <summary> | |||
| /// Clean up any resources being used. | |||
| /// </summary> | |||
| /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> | |||
| protected override void Dispose(bool disposing) | |||
| { | |||
| if (disposing && (components != null)) | |||
| { | |||
| components.Dispose(); | |||
| } | |||
| base.Dispose(disposing); | |||
| } | |||
| #region Component Designer generated code | |||
| /// <summary> | |||
| /// Required method for Designer support - do not modify | |||
| /// the contents of this method with the code editor. | |||
| /// </summary> | |||
| 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; | |||
| } | |||
| } | |||
| @@ -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; | |||
| } | |||
| } | |||
| @@ -0,0 +1,120 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | |||
| <root> | |||
| <!-- | |||
| Microsoft ResX Schema | |||
| Version 2.0 | |||
| The primary goals of this format is to allow a simple XML format | |||
| that is mostly human readable. The generation and parsing of the | |||
| various data types are done through the TypeConverter classes | |||
| associated with the data types. | |||
| Example: | |||
| ... ado.net/XML headers & schema ... | |||
| <resheader name="resmimetype">text/microsoft-resx</resheader> | |||
| <resheader name="version">2.0</resheader> | |||
| <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> | |||
| <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> | |||
| <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> | |||
| <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> | |||
| <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> | |||
| <value>[base64 mime encoded serialized .NET Framework object]</value> | |||
| </data> | |||
| <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> | |||
| <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> | |||
| <comment>This is a comment</comment> | |||
| </data> | |||
| There are any number of "resheader" rows that contain simple | |||
| name/value pairs. | |||
| Each data row contains a name, and value. The row also contains a | |||
| type or mimetype. Type corresponds to a .NET class that support | |||
| text/value conversion through the TypeConverter architecture. | |||
| Classes that don't support this are serialized and stored with the | |||
| mimetype set. | |||
| The mimetype is used for serialized objects, and tells the | |||
| ResXResourceReader how to depersist the object. This is currently not | |||
| extensible. For a given mimetype the value must be set accordingly: | |||
| Note - application/x-microsoft.net.object.binary.base64 is the format | |||
| that the ResXResourceWriter will generate, however the reader can | |||
| read any of the formats listed below. | |||
| mimetype: application/x-microsoft.net.object.binary.base64 | |||
| value : The object must be serialized with | |||
| : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter | |||
| : and then encoded with base64 encoding. | |||
| mimetype: application/x-microsoft.net.object.soap.base64 | |||
| value : The object must be serialized with | |||
| : System.Runtime.Serialization.Formatters.Soap.SoapFormatter | |||
| : and then encoded with base64 encoding. | |||
| mimetype: application/x-microsoft.net.object.bytearray.base64 | |||
| value : The object must be serialized into a byte array | |||
| : using a System.ComponentModel.TypeConverter | |||
| : and then encoded with base64 encoding. | |||
| --> | |||
| <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> | |||
| <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> | |||
| <xsd:element name="root" msdata:IsDataSet="true"> | |||
| <xsd:complexType> | |||
| <xsd:choice maxOccurs="unbounded"> | |||
| <xsd:element name="metadata"> | |||
| <xsd:complexType> | |||
| <xsd:sequence> | |||
| <xsd:element name="value" type="xsd:string" minOccurs="0" /> | |||
| </xsd:sequence> | |||
| <xsd:attribute name="name" use="required" type="xsd:string" /> | |||
| <xsd:attribute name="type" type="xsd:string" /> | |||
| <xsd:attribute name="mimetype" type="xsd:string" /> | |||
| <xsd:attribute ref="xml:space" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| <xsd:element name="assembly"> | |||
| <xsd:complexType> | |||
| <xsd:attribute name="alias" type="xsd:string" /> | |||
| <xsd:attribute name="name" type="xsd:string" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| <xsd:element name="data"> | |||
| <xsd:complexType> | |||
| <xsd:sequence> | |||
| <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> | |||
| <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> | |||
| </xsd:sequence> | |||
| <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> | |||
| <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> | |||
| <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> | |||
| <xsd:attribute ref="xml:space" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| <xsd:element name="resheader"> | |||
| <xsd:complexType> | |||
| <xsd:sequence> | |||
| <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> | |||
| </xsd:sequence> | |||
| <xsd:attribute name="name" type="xsd:string" use="required" /> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| </xsd:choice> | |||
| </xsd:complexType> | |||
| </xsd:element> | |||
| </xsd:schema> | |||
| <resheader name="resmimetype"> | |||
| <value>text/microsoft-resx</value> | |||
| </resheader> | |||
| <resheader name="version"> | |||
| <value>2.0</value> | |||
| </resheader> | |||
| <resheader name="reader"> | |||
| <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||
| </resheader> | |||
| <resheader name="writer"> | |||
| <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||
| </resheader> | |||
| </root> | |||