asp.net scheduled tasks i

17
ASP.NET Page 1 Table of Contents Building a .NET Console Application for Scheduled Tasks By John Peterson ......................................................................... 2 smtp from vb.net console application .................................................................................................................................. 12 Hide/Show Console window in .NET 2.0 and higher (black window) ......................................................... 12 Hide Console Window in Console Application In C#.Net ...................................................................................................... 14 Consuming a webservice in a console app ........................................................................................................................... 14 Auto email sending and reminder ........................................................................................................................................ 16 Concept of an Online Reminder Service ............................................................................................................................... 17

Upload: rajesh-ravindran

Post on 18-Apr-2015

47 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: ASP.net Scheduled Tasks I

ASP.NET Page 1

Table of Contents Building a .NET Console Application for Scheduled Tasks By John Peterson ......................................................................... 2

smtp from vb.net console application .................................................................................................................................. 12

Hide/Show Console window in .NET 2.0 and higher (black window) ......................................................... 12

Hide Console Window in Console Application In C#.Net ...................................................................................................... 14

Consuming a webservice in a console app ........................................................................................................................... 14

Auto email sending and reminder ........................................................................................................................................ 16

Concept of an Online Reminder Service ............................................................................................................................... 17

Page 2: ASP.net Scheduled Tasks I

ASP.NET Page 2

Building a .NET Console Application for Scheduled

Tasks By John Peterson

Introduction

As is usually the case for me, the idea for this article came from a project on which I was recently working. Without going into all the

gory the details, the basic requirement was that something needed to happen on a daily basis. This obviously wasn't the first time I'd

run into this type of requirement, but as I started digging up my normal solution, I realized that while it was tried and true, it was also

horribly outdated. It was written as a .vbs file designed to run via WSH. This meant that while it was easy to make changes to the

script because it was written in plain text and not compiled, making sure those changes worked correctly and debugging new versions

of the script ranged from slightly annoying to downright frustrating.

Note: For those of you who would like to learn more about the old system I had been using to schedule script execution, I wrote up the

concepts involved in an old article over on ASP 101: Getting Scripts to Run on a Schedule. The actual processing involved had

evolved over the years and obviously varied based on the project, but the basic process of scheduling a .vbs file that is outlined in

method three of that article had pretty much remained the same.

Thinking there had to be a better way, I set out to build a command-line .NET application that I could then schedule via Windows

Scheduled Tasks. Not only would this allow me to utilize the power of the .NET Framework, but it would also allow me to more

easily test and debug the application. In this article, I'll walk you through the process of building a simple .NET command-line

application that is designed to be scheduled to execute. For the sake of illustration, the sample application will send an HTTP request

to a web server and send the returned HTML as the body of an email message.

Tools Needed

If you don't already have a version of Visual Studio that can build a command line application, you'll need to download and install the

Express Edition product of your choice:

Visual Basic 2008 Express Edition

Visual C# 2008 Express Edition

Visual C++ 2008 Express Edition

You'll only need one and I recommend and will be using Visual Basic 2008 Express Edition for the remainder of this article. The code

will obviously be different if you choose a different language, but the concepts are pretty much the same.

For those of you already using Visual Web Developer 2008 Express Edition, don't worry... it's perfectly acceptable to have multiple

Express Edition products installed.

Building the Command-Line Application

The sample application I'm going to build will send an HTTP request to a web server. It will then take the HTML returned from the

server and use it as the body of an email message. The code is pretty simple and can be changed to do whatever your situation

requires. The steps involved are pretty much the same regardless of what the code involved actually does.

Once you've got Visual Basic 2008 Express Edition installed and working, launch it and select File -> New Project. This will

bring up the "New Project" dialog box.

Page 3: ASP.net Scheduled Tasks I

ASP.NET Page 3

You want to select "Console Application" and give your application a meaningful name. I'm calling the sample application

"Http2Email". Once you click "OK", your workspace should look something like this:

Since I like my objects to have meaningful names, the first thing I'll do is rename "Module1.vb" to "Http2Email.vb" in the "Solution

Explorer" pane. This will update the name in all the appropriate places in the project. After which, I'll save the project to disk by doing

a File -> Save All...

Page 4: ASP.net Scheduled Tasks I

ASP.NET Page 4

Next I'm going to change a few settings. If you double-click on the "My Project" item in "Solution Explorer", you'll get a

configuration screen that looks like this:

Since a number of my Web servers are still running .NET 2.0, the first setting I'll change is the target framework version. On the

"Compile" tab, click the "Advanced Compile Options..." button. The bottom option in the resulting dialog box is "Target framework".

Change it to ".NET Framework 2.0".

On the "References" tab, we can remove a bunch of the references and imported namespaces. Remove all but the "System" reference

(unless you're building a different application and need other references) and all the "Imported Namespaces" except for:

Microsoft.VisualBasic, System, System.Collections, and System.Collections.Generic.

Page 5: ASP.net Scheduled Tasks I

ASP.NET Page 5

Next I'm going to define some application settings. By defining these as settings instead of hard-coding them, we can change the

application's parameters and hence its behavior without needing to recompile it. On the "Settings" tab, I define eight application-

scoped settings:

Setting Description

Url URL from which we pull the HTML to use as the body of the email

EmailFrom From email address(es)

EmailTo To email address(es)

EmailCC CC email address(es)

EmailBCC BCC email address(es)

EmailSubject Subject line for the email message

EmailHtml Boolean indicating if the email should be formatted as HTML or not

SmtpServer Name of the SMTP server to use to send the email message

Page 6: ASP.net Scheduled Tasks I

ASP.NET Page 6

They're pretty straight-forward. I've included the values I used to test with in the image above, but you'll obviously want to use your

own settings for the URL, email addresses, and SMTP server.

The only setting that is a little interesting is the "EmailSubject". If you look at the value, you'll notice that I've included the phrase

"<date>" as a place holder. The application's code replaces that with the current date. I only did this as an illustration of how you can

use the setting functionality and yet still provide for dynamically changing values.

Now that we've got the application all configured, it's time to add the code. It's probably easiest it you just cut and paste the code from

the box below:

Imports System.IO

Imports System.Net

Module Http2Email

Sub Main()

Dim myWebRequest As WebRequest

Dim myStreamReader As StreamReader

Dim strSubject, strBody As String

Dim myMailMessage As Mail.MailMessage

Dim mySmtpClient As Mail.SmtpClient

' Retrieve HTML via HTTP request to use as body of email

myWebRequest = WebRequest.Create(My.Settings.Url)

myStreamReader = New StreamReader(myWebRequest.GetResponse().GetResponseStream())

strBody = myStreamReader.ReadToEnd

myStreamReader.Close()

' Get subject from settings and replace placeholder with current date

strSubject = My.Settings.EmailSubject

strSubject = strSubject.Replace("<date>", FormatDateTime(Now(),

DateFormat.ShortDate))

' Create email message

myMailMessage = New Mail.MailMessage(My.Settings.EmailFrom, My.Settings.EmailTo,

strSubject, strBody)

If My.Settings.EmailCC <> "" Then myMailMessage.CC.Add(My.Settings.EmailCC)

Page 7: ASP.net Scheduled Tasks I

ASP.NET Page 7

If My.Settings.EmailBCC <> "" Then myMailMessage.Bcc.Add(My.Settings.EmailBCC)

myMailMessage.IsBodyHtml = My.Settings.EmailHtml

' Send email

mySmtpClient = New Mail.SmtpClient()

mySmtpClient.Host = My.Settings.SmtpServer

mySmtpClient.Send(myMailMessage)

End Sub

End Module

The code is pretty simple so I won't spend too much time going over it. The only thing that might seem a little odd to those of you who

aren't used to it is all the references to My.Settings. That's the namespace used to access the settings we defined previously.

At this point you can go ahead and build and run the application from within the development environment to make sure everything is

working. You can do this by either click Debug -> Start Debugging or pressing the "F5" key.

If you get an error it'll probably be related to either a bad URL or an unreachable or locked down SMTP server. To resolve the later,

you might need to set credentials on the SMTP client object.

If you don't get an error, you'll most likely just see a black console window open for a second and then go away. That's exactly what

we want to happen. Since the application is designed to run when no one is logged on, it doesn't really provide any visual feedback.

Simply wait a few minutes for the email to make its way through the network and to your Inbox.

Once you've got your application working to your satisfaction, from the Build menu select Build -> Build Http2Email. Then

you'll find the executable and config files in the "bin\Release" sub-folder of your project's folder.

These are the files you'll need to copy to whatever computer on which you want to schedule the application to run.

Remember those settings we defined earlier. If you open up the "Http2Email.exe.config" file with Notepad and scroll to the bottom of

the file, you'll see all those settings and values stored in XML format. If you need to modify one for testing or if you need to change a

setting later, simply edit the text file and the next time the application runs it will read in the new value. No need to fire off Visual

Studio or recompile anything. Pretty slick, huh?

Before we move on to the scheduling part of the article, I want to re-iterate that although our application simply does an HTTP request

and sends an email, you're free to do whatever you want to in your console application. You've got full access to the .NET Framework

and are pretty much limited only by the lack of a graphical UI.

Scheduling the Application to Run

Now that our command-line application is working the way we want it to, the next step is to get it scheduled to run at the right time.

As I mentioned previously, the first step is to copy the executable and configuration files to the target computer. Where you store them

is up to you, but It's probably best if you give them their own folder. I put them in a "schedule" folder under my server's "Inetpub"

folder since they're related to my web application, but I want to keep them outside of the "wwwroot" folder.

Page 8: ASP.net Scheduled Tasks I

ASP.NET Page 8

If you're logged into the server interactively, once you've copied the file, you can simply double-click on the executable to see if it

runs without generating an error. If it does, all that remains is to set up a scheduled task.

To set a program to run as a scheduled task, you need to go to the "Scheduled Tasks" Control Panel applet. You can usually get there

via Start -> Control Panel -> Scheduled Tasks.

Once there you should see an item that says "Add Scheduled Task" along with any other tasks with may already be scheduled. If you

double-click "Add Scheduled Task", it will launch the "Scheduled Task Wizard".

Click the "Browse" button to find and select the application's executable file ("Http2Email.exe").

Page 9: ASP.net Scheduled Tasks I

ASP.NET Page 9

Select the type of schedule and set the details telling the computer when it should run the application.

Page 10: ASP.net Scheduled Tasks I

ASP.NET Page 10

It'll then ask you for a username and password for the account as which it should run the application.

Click the "Finish" button and the new task should appear in the "Scheduled Tasks" window. From here you can monitor the task and

even see the return result from the last time the application ran (0x0 indicates the application exited without generating an error...

anything else usually means there was an error).

Page 11: ASP.net Scheduled Tasks I

ASP.NET Page 11

Conclusion

I hope this article has shown you just how easy it is to build a command-line .NET application and schedule it to run via Windows

Scheduled Tasks. If you're used to building web-based applications, it may feel a little weird at first, but after you've done it a couple

times you'll get the hang of things and realize how much flexibility it actually gives you to do things on your schedule.

Page 12: ASP.net Scheduled Tasks I

ASP.NET Page 12

smtp from vb.net console application

Dim Message As MailMessage = New MailMessage()

Dim Smtp As New SmtpClient()

Dim SmtpUser As New System.Net.NetworkCredential("[email protected]", "password")

Message.From = New MailAddress("[email protected]")

Message.To.Add(New MailAddress("[email protected]"))

Message.IsBodyHtml = False

Message.Subject = "Another test"

Message.Body = "This is a test"

Message.Priority = MailPriority.Normal

Smtp.EnableSsl = False

Smtp.Credentials = SmtpUser

Smtp.Host = "smtp.mydomain.com"

Smtp.DeliveryMethod = SmtpDeliveryMethod.Network

Smtp.Port = 587

Smtp.Send(Message)

Hide/Show Console window in .NET 2.0 and higher (black window)

When working with .Net Console application, one issue may occurred is how to hide the console screen ( the black window ). In my case, my console application call to show an

Window Form and the console need to be hide for convenient handling. And when needed, we also unhide the console.

See runnable example below :

using System; using System.Collections.Generic; using System.Windows.Forms; namespace MyNamespace { class Program { [DllImport("user32.dll")] public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll")] static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); [STAThread] static void Main(string[] args) {

Page 13: ASP.net Scheduled Tasks I

ASP.NET Page 13

// My example context is when app run with no parameters // application launch an UI to waiting command from it. if (arrArgs.Count == 0) { // Display manage UI and hide console HideConsole(); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new mainForm()); } else { // Handle parameters ... } } static void HideConsole() { IntPtr hWnd = FindWindow(null, Console.Title); if(hWnd != IntPtr.Zero) { ShowWindow(hWnd, 0); // 0 = SW_HIDE } } static void ShowConsole() { IntPtr hWnd = FindWindow(null, Console.Title); if (hWnd != IntPtr.Zero) { ShowWindow(hWnd, 1); //1 = SW_SHOWNORMA } } } }

Page 14: ASP.net Scheduled Tasks I

ASP.NET Page 14

Hide Console Window in Console Application

In C#.Net

1) Create the Console application in C# dotnet 2) Now in the static void Main(string[] args) function put the below line //give the title of running application Console.Title = “TestHideApplication”; //put your console window caption here IntPtr hWnd = FindWindow(null, ” TestHideApplication “); if (hWnd != IntPtr.Zero) { //Hide the window ShowWindow(hWnd, 0); // 0 = SW_HIDE } 3) in the global declation put the below code //add namespace using System.Runtime.InteropServices; [DllImport("user32.dll")] public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll")] static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

Consuming a webservice in a console app

Here's a little console program that calls a webservice method which returns a dataset, loops through a datatable, and

does something for each row. I'm going to use it to update an Oracle database on a website:

Imports System.Environment Imports hexcolorns Module Module1 Sub Main() dim UseProxy as Boolean = false dim args() as string = GetCommandLineArgs() if args.GetUpperBound(0) > 0 then UseProxy = true End If Dim myWebSvc As Hexcolor = New Hexcolor() if UseProxy then mywebsvc.ProxyName = "192.168.10.3" mywebsvc.ProxyPort = 8080 end if Dim ds As dataset ds = myWebSvc.ColorList

Page 15: ASP.net Scheduled Tasks I

ASP.NET Page 15

dim dr as DataRow for each dr in ds.Tables("product").Rows console.WriteLine(dr("product_code").tostring.trim & "," & dr("cm_hex").tostring) Next end sub End Module

Page 16: ASP.net Scheduled Tasks I

ASP.NET Page 16

Auto email sending and reminder

Write a Windows Service that will query your database for birthdays on the current date. Within the service

implement a Timer that fires your method at Start and every hour or two. If the last run date is not today then

do the work.

You can put a timer at a windows/consoule server which call a function to check the schedule at database and

send reminders like this:

System.Threading;

.....

static void Main(string[] args)

{

TimerCallback timerdelegate = new TimerCallback(BirthdayFunction); //BirthdayFunction is the name of the fucntion which send

email (after checking schedules at database)

Timer stateTimer = new Timer(timerdelegate, null, 0, " Time (Every How Much Time To Invoke The Function)");

}

........................

static void BirthdayFunction(object state)

{

// check the database for the persons birthdays and then send to friends' a reminder email

}

You also can use this within a web site's Global.asax Application_Start Event by creating a timer there, in that

timer you would call the Birthday reminder function. Autamated timed emails, should they be sent using a page. A timer should be a working thread in applications main loop or entry point that is global.asax Application_Start Event;

If you do not have a dedicated server you surely will have a problem installing the service, even if you can

create one.

If you use a shared hosting, make a aspx page which does all the reminder and email sending work and you can

invoke it from a service like www.webcron.org on scheduled intervals!

You make up a aspx page with all the emailing logic in it and you register your page url on webcron so that the

page is executed at the interval you specify there. As your page is executed, so would the emailing logic and

you send out the emails then.

You may put a check somewhere that no one can maliciously invoke this page multiple times or you do not

send out emails more than once etc.

Page 17: ASP.net Scheduled Tasks I

ASP.NET Page 17

Concept of an Online Reminder Service

the key thing you need is a scheduler of some kind - usually you would use one of:

Windows Service on the server

SQL Job

CRON or AT job schedualed on the server

Any one of those could be set up to call a page on your site that would kick off this process.

As you are in a shared environment, you're not likely to have access to any of those, and so would need to have some

other process in place.

What you could do is have remote (to the server) schedualer calling a page on your website that performs the lookup and

sends the emails - this could either be something running on your dev/office environment (with all the attendant dangers

of power/network failures, etc), or you could look at getting a "site monitoring" service that will ping a page on your server

at regular intervals to check to see if it's up and running.

The page it hits would then:

1. Check a flag to see if today's alerts had been sent.

2. Update the flag to say the send is in progress.

3. Search for today's alerts.

4. Send today's alerts.

5. Update the flag to say that the alerts have been sent.

We basically have a SQL Job that calls a page like this on our webserver to send out daily alerts, and it usually works

quite well.

There's no reason why the page couldn't be called by a remote server to start this process.

Various options are available for this sort of thing:

Hosted Cron

PingDom

Are just a couple, I'm sure that there are plenty more.