Friday, January 28, 2011

Installing Quartz.Net 2.0 as a Windows Service

NOTE: I'm now blogging at http://jayvilalta.com/blog and not updating this blog anymore. For information on the latest version of Quartz.Net, visit me there.

UPDATE: I've written a new post that has been updated with the release of Beta 1. Take a look at this newer post instead.
Quartz.Net 2.0 is currently under development. No official release (beta or otherwise) is available yet but if you really want to get started with it, you can download the source code from Github and build it yourself. In this post I am going to describe how to install the latest version of Quartz.Net 2.0 from source.

Getting the Source

If you are familiar with Git, Github and how it works, then just download the repository locally using whatever method you prefer. There are a lot of posts and even a free book on how to use Git, so I am not going to go over that stuff here.
If you’re not familiar with how to use Git or Github, then go ahead and download a zipped file of the source from here.
At this point I am going to assume that you have already downloaded the Quartz.Net source code and that it is in a folder somewhere on your drive. On my box I have downloaded the source to C:\git\quartznet, and the image below shows what that folder looks like. Your folder should look similar to the screenshot below.
image

Building The Source Code

Since this post is about installing Quartz.Net 2.0 as a windows service, let’s build the server project.
Instructions for Visual Studio 2008 and .Net 3.5
Double click on the Quartz.Server.2008.sln file if you have Visual Studio 2008 installed. This will open the file in VS 2008. Build the solution by pressing F6. This will build the binaries targeting the 3.5 framework. The build output for this project can be found under the build\3.5\Debug\Quartz.Server folder, as shown below.
image
Instructions for Visual Studio 2010 and .Net 4.0
If you have Visual Studio 2010 installed, double click on the Quartz.Server.2010.sln file to open it in VS 2010. Build the solution by pressing F6. This will build the binaries targeting the 4.0 framework. The build output for this project can be found under the build\4.0\Debug\Quartz.Server folder, as shown below.
image

Installing Quartz.Net 2.0 as a Windows Service

Now that you have built the source code, let’s install the service. Open a command prompt as administrator (if you are running a Vista or later OS) and cd to the directory that contains the Quartz.Server.exe file. This directory will be different based on whether you use VS 2008 or VS 2010, so double check that the file exists first in one of the paths that I mention above. At this point, all that is left is to install the service. Type the following into your command prompt:
Quartz.Server.exe install
If all goes well, then you should see the following in your command prompt window (replace 3.5 with 4.0 where appropriate):
image
By default, the service is installed with a startup type of automatic and under the Local System account. To uninstall, type the following into your command prompt:
Quartz.Server.exe uninstall
Now, go fire that puppy up and start experimenting!
As always, let me know in the comments if this stuff is useful and what topics you’re interested in reading about.

Tuesday, January 18, 2011

Quartz.Net Library is Available on NuGet

NOTE: I'm now blogging at http://jayvilalta.com/blog and not updating this blog anymore. For information on the latest version of Quartz.Net, visit me there.

The Quartz.Net library has been uploaded to NuGet. If you’re using Quartz.Net and NuGet, this should help you with setting up your environment and in keeping things current. The Common.Logging and the Common.Logging.Log4net and Log4net libraries are on NuGet as well. These are all required dependencies for running Quartz.Net with Log4net.

Saturday, January 15, 2011

Quartz.Net Development is Moving to Github

NOTE: I'm now blogging at http://jayvilalta.com/blog and not updating this blog anymore. For information on the latest version of Quartz.Net, visit me there.

In case you didn’t know it yet, development of Quart.Net is moving from Sourceforge to Github. If you want to follow development of the latest version of Quartz.Net. be sure and check out the project on Github. This should make it easier for everybody to contribute any changes to the project.

Tuesday, November 9, 2010

Quartz.Net GUI Tour - Part 2

NOTE: I'm now blogging at http://jayvilalta.com/blog and not updating this blog anymore. For information on the latest version of Quartz.Net, visit me there.

This is the second part of the Quartz.Net GUI Tour. The first part of the tour covered connecting to schedulers and adding jobs. In this post, I’ll go over the remaining features.

Running Jobs

To run a job immediately, select the job from the left tree. The job details will be displayed on the right, and the run button will be enabled, as in the attached screenshot:
image
Clicking on the button will cause the job to be scheduled to execute once, immediately.

Deleting Jobs

To delete a job, select it from the left tree. The delete button will then become enabled. Click the delete button on the right to delete the job and all of its associated triggers.
image

Pausing and Resuming Triggers

Quartz.Net manager allows you to pause and resume triggers as well. To enable the pause / resume button, you must first select a trigger from the tree on the left. Once a trigger is selected, the pause button will be enabled. Click on the pause button to pause a trigger. If the trigger you selected is already paused, the button will say Resume instead of Pause. Click on the resume button to reactivate the selected trigger.
image

Backup To File

The last feature we’ll discuss in the tour is the backup to file feature. This feature lets you backup all of your jobs and triggers to a text (xml) file. This file can be then be used by the xml plugin to load all the job information into, say, a new scheduler instance. To create a backup of your scheduler, right click on the entry for the scheduler in the tree. Select the backup option and enter a file name for your backup file.
This concludes the quick tour of the Quartz.Net manager features. I hope you have found it useful.

Monday, November 8, 2010

Quartz.Net GUI Tour

NOTE: I'm now blogging at http://jayvilalta.com/blog and not updating this blog anymore. For information on the latest version of Quartz.Net, visit me there.

In this post I will do a quick walkthrough of the Quartz.Net GUI that we open sourced last week.

Installation

We do not have an installer right now, so your options are:
  1. 1. Download the source code and hit F5.
  2. 2. After having downloaded the source code and done a successful build, run the executable.
  3. 3. Download the binaries, extract them into a folder and run the executable.

Connecting to a Scheduler

Click on Scheduler –> Connect. You should get the following connection dialog:
image
Type in your server name, and change any of the default connection information if necessary. Once connected, your screen should look something like this:
image

Adding Custom Jobs to the Manager

Before we can add a custom job, we must first tell the application which dlls contain the jobs that we want to add. Adding dlls to the list of scanned dlls is done by editing the JobAssemblies.txt file. Just include the name of your dll in the file, by adding it to the bottom of the list.

Adding a Job to the Scheduler

To add or schedule a job on the scheduler that you are connected to, click on the Jobs –> Add menu. You should get a dialog box like this:
image
Now, select a job type from the dropdown and fill out all the boxes with the necessary information. You do not need to add job data unless your job requires it. If your job requires job data to be set, use the right hand side of the dialog to add as many key value pairs of data as needed.
Once you have set up your data, click on add and your job will be scheduled. The dialog will close and the Scheduler objects pane will show the job that you scheduled.

What About the Run, Pause, Delete and Edit Buttons?

Part 2 of the tour is now available, with a quick description on how to use these buttons.

Monday, November 1, 2010

Open Source Graphical User Interface (GUI) for Quartz.Net

NOTE: I'm now blogging at http://jayvilalta.com/blog and not updating this blog anymore. For information on the latest version of Quartz.Net, visit me there.

Click Forensics, the company I work for, has graciously allowed me to open source the code to a GUI for Quartz.net. The latest code is currently available on github.  We have been using Quartz.net for over a year and we use this tool to manage our schedulers. The application is written in C#, using windows forms and is targeting .Net 4.0
The code should be considered alpha quality at this point, as some features are missing and some don’t work properly. The documentation is pretty much non-existent at this point, but as I have some spare time I will post updates here and on github. Please give it a try send us any feedback you might have.
I would suggest you download the source and build it yourself, but for your convenience, you can download the binaries from https://github.com/adometry/QuartzNetManager/downloads.

Creating a Quartz.Net JobListener

NOTE: I'm now blogging at http://jayvilalta.com/blog and not updating this blog anymore. For information on the latest version of Quartz.Net, visit me there.

This post will describe how to create a Quartz.Net job listener. As an example, we will write a job history listener that will log job start and end times to a database.

Creating the Job Listener

To create a job listener, we need to implement the IJobListener interface. Here is the interface:
public interface IJobListener
{
    string Name { get; }

    void JobExecutionVetoed(JobExecutionContext context);
    void JobToBeExecuted(JobExecutionContext context);
    void JobWasExecuted(JobExecutionContext context, JobExecutionException jobException);
}


For the task at hand, we will not implement JobExecutionVetoed, since we just want to be notified when a job starts and when it ends. Since we want to log start and end times for our jobs, we will focus on implementing the JobToBeExecuted and the JobWasExecuted methods.


Implementing the JobToBeExecuted Method



In this method, we will write a record to the database, indicating that the job has started processing. Your implementation of the method could look something like this:


Guid historyId = Guid.NewGuid();
context.JobDetail.JobDataMap.Add("historyID", historyId);
string sql = @"INSERT INTO [dbo].[QRTZ_JOB_HISTORY]([JobHistoryID],[JobName],[StartDate],[Server],[JobType]) VALUES(@JobHistoryID,@JobName,@StartDate,@Server,@JobType)";
using (SqlConnection connection = new SqlConnection(connectionStringGoesHere)
{
   connection.Open();
   using (SqlCommand command = new SqlCommand(sql, connection))
   {
       command.Parameters.AddWithValue("@JobHistoryID", historyId);
       command.Parameters.AddWithValue("@JobName", context.JobDetail.Name);
       command.Parameters.AddWithValue("@StartDate", DateTime.Now);
       command.Parameters.AddWithValue("@Server", Environment.MachineName);
       command.Parameters.AddWithValue("@JobType", context.JobDetail.JobType.ToString());
       command.ExecuteNonQuery();
   }
}


Basically we are inserting a row into a table with all the information we need in order to be able to determine the job’s run time. One thing you should note is that we are creating a GUID and sticking it into the context. This is so that we can record when the job finishes running.


Implementing the JobWasExecuted Method



This method gets called whenever the job finishes running. The only thing left to do now is to update the row we inserted when the job began running and set the end time. Here is what that method might look like:


string sql = "UPDATE [dbo].[QRTZ_JOB_HISTORY] SET [EndDate]=@EndDate WHERE [JobHistoryID]=@JobHistoryID";
using (SqlConnection connection = new SqlConnection(connectionStringGoesHere))
{
   connection.Open();
   using (SqlCommand command = new SqlCommand(sql, connection))
   {
       command.Parameters.AddWithValue("@JobHistoryID", (Guid)jobDetail.JobDataMap.Get("historyID"));
       command.Parameters.AddWithValue("@EndDate", DateTime.Now);
       command.ExecuteNonQuery();
   }
}



As you can see here, we are reaching into the context and extracting the GUID that we put there when the job started running. This will allow us to update the correct row and thus be able to calculate how long it took the job to finish running.


Wrapping Up



Now that you have written a job listener. You have a couple of choices:



  1. You can add the listener directly to your job, in which case only jobs that have the listener attached will log their execution in our database.


  2. Add the listener as a global listener. Global listeners get called whenever any job runs, and our history listener seems like a good candidate for becoming a global listener. My previous post describes how to schedule a global listener.


I hope this post was useful.