ASP,purpose,article,show,tasks,regular,interv
Quick Search for:  in language:    
ASP,purpose,article,show,tasks,regular,interv
   Code/Articles » |  Newest/Best » |  Community » |  Jobs » |  Other » |  Goto » | 
CategoriesSearch Newest CodeCoding ContestCode of the DayAsk A ProJobsUpload
ASP/ VbScript Stats

 Code: 132,008 lines
 Jobs: 198 postings

 
Sponsored by:

 

You are in:

 
Login


 

 


Latest Code Ticker for ASP/ VbScript.
if i remember, this is a M. Harris code sample
By ask on 8/24


MTS Registration Script
By Igor Krupitsky on 8/23


Click here to see a screenshot of this code!Creating Windows Users with ASP and ADSI
By James P. Walters on 8/23

(Screen Shot)

News Poster (Advanced)
By Martin Kilbryde on 8/22


Print a web document through MS Word
By ask on 8/22


Click here to see a screenshot of this code!ADSI Domain Group Explorer
By Gordon Asbach on 8/22

(Screen Shot)

_-~Who is looking at your site? v2.0!~-_
By John on 8/22


Using HTML Option to Display Current Month
By Patrick Ingle on 8/20


FdB: Free Database (Aka Fake Database)
By TV2k.net on 8/19


Click here to put this ticker on your site!


Add this ticker to your desktop!


Daily Code Email
To join the 'Code of the Day' Mailing List click here!





Affiliate Sites



 
 
   

Automating Tasks with WSH

Print
Email
 

Submitted on: 5/23/2000 4:50:55 PM
By: Mark Lidstone 
Level: Intermediate
User Rating: By 9 Users
Compatibility:ASP (Active Server Pages), VbScript (browser/client side)

Users have accessed this article 12276 times.
 
 
     The purpose of this article is to show how to run tasks at regular intervals without having to access an ASP script with your web browser manually.

 
 
Terms of Agreement:   
By using this article, you agree to the following terms...   
1) You may use this article in your own programs (and may compile it into a program and distribute it in compiled format for languages that allow it) freely and with no charge.   
2) You MAY NOT redistribute this article (for example to a web site) without written permission from the original author. Failure to do so is a violation of copyright laws.   
3) You may link to this article from another website, but ONLY if it is not wrapped in a frame. 
4) You will abide by any additional copyright restrictions which the author may have placed in the article or article's description.

Automating Tasks

A common question with ASP is "How do I run a certain page at regular intervals?". Normally people want to do this because they have a page that performs all their database maintenance or does something like send of reminder emails. Windows NT has a method of scheduling tasks to run at a specific time, but it only allows command-line tasks to be run. To use this all you have to do is use the "AT" command at the console and leave the "Scheduler" service running.

It is possible to start, for instance, Internet Explorer from the command line and tell it to request your page (e.g. "c:\program files\internet explorer\iexplore.exe http://localhost/mypage.asp"). Netscape also gives this ability, but using either will mean that every time the scheduled task runs you will be opening a new browser window and will need to get to the server and actually close the browser window. Running a browser also has a pretty high overhead in terms of disk access, memory space/bandwidth and processor time, and if you went on holiday for a month and the task was run every day you'd come back to a server with about 30 open browser windows. Not nice!

Another drawback is that scripts running through ASP.DLL can timeout. If you are doing a lot of work and you know that the task is going to take longer than your default timeout value, it can make things a little more complicated getting them to run. Although it's possible to make the timeout longer, that means that malformed scripts on other parts of your site can take up more processing time, and changing the timeout for individual pages only allows you to reduce the timeout delay, not lengthen it.

Luckily it is possible to run scripts from the command-line directly, without requesting ASP scripts through the web server thanks to the Windows Scripting Host (WSH). For a rather dry overview of what WSH is, you can see the article at http://www.microsoft.com/MANAGEMENT/ScrptHost.htm

The main advantages to using WSH instead of an ASP script are:

  1. Less memory/CPU intensive than opening a browser.
  2. Timeouts are optional and can be set on a "per script" basis.
  3. No windows to close after every execution.
  4. Simpler code production.

Writing WSH scripts is not difficult at all. Normally you can convert your ASP scripts to WSH scripts in a matter of seconds, and to show you what I mean, I'll convert an example ASP script to a WSH script. The source below is for a page that removes all entries in the "tblNewsItems" that are over a week out of date and displays a list of the articles that have been deleted.

    <html>
    <head><title>Database Maintenance Page</title>
    <body background="#FFFFFF">
    <h1>Database Maintenance</h1>
    <!-- #include virtual="/includes/adovbs.inc" --><%
    
' Define variables Dim objConn, objRS Dim dtmCutoffDate Dim strCutoffDate
' Make sure the date format cannot be confused (I'm paranoid about this because I'm British) dtmCutoffDate = DateAdd("d",-7,Date) strCutoffDate = Day(dtmCutoffDate) & " " & MonthName(Month(dtmCutoffDate)) & _ " " & Year(dtmCutoffDate)
' Create and setup connection object Set objConn = Server.CreateObject("ADODB.Connection") objConn.Open "MyDSN"
' Retrieve records that are to be deleted Set objRS = Server.CreateObject("ADODB.RecordSet") objRS.Open "SELECT * FROM tblNewsItems WHERE dtmExpireDate < #" & strCutoffDate & _ "#;", objConn, adOpenKeyset, adLockOptimistic, adCmdText
' If there are some articles returned, print their details then remove them from ' the database If NOT objRS.EOF Then Response.Write "The following articles were out of date and have " & _ been deleted :" & vbCrLf Response.Write "<table border=0 cellpadding=1 cellspacing=1>" & vbCrLf Response.Write vbTab & "<tr><th>Article Title</th><th>Author</th>" & _ <th>Start Date</th><th>End Date</th></tr>" & vbCrLf While NOT objRS.EOF Response.Write vbTab & "<tr><td>" & objRS("strTitle") & "</td>" & _ "<td>" & objRS("strAuthor") & "</td><td>" & _ objRS("dtmStartDate") & "</td><td>" & objRS("dtmExpireDate") & _ "</td></tr>" & vbCrLf objRS.MoveNext WEnd Response.Write "</table>" & vbCrLf objConn.Execute("DELETE FROM tblNewsItems WHERE dtmExpireDate < #" & _ strCutoffDate & "#;") Else
' If no out of date articles were found, explain and carry on Response.Write "No out of date articles were found" & vbCrLf End If
' Tidy up objects objRS.Close Set objRS = Nothing objConn.Close Set objConn = Nothing
%></body> </html>

The main difference is that you don't need to put anything inside script delimiters like "<% .... %>" or "<script runat=Server> .... </script>" because the entire file is treated as script. Also, there are no "Request" or "Response" objects because there will be no input or output from IIS. Changing our script to take account of this (and deleting everything outside the delimiters) gives us this :

    ' Define variables
    Dim objConn, objRS
    Dim dtmCutoffDate
    Dim strCutoffDate
    
' Make sure the date format cannot be confused (I'm paranoid about this because I'm British) dtmCutoffDate = DateAdd("d",-7,Date) strCutoffDate = Day(dtmCutoffDate) & " " & MonthName(Month(dtmCutoffDate)) & _ " " & Year(dtmCutoffDate)
' Create and setup connection object Set objConn = Server.CreateObject("ADODB.Connection") objConn.Open "MyDSN"
' Retrieve records that are to be deleted Set objRS = Server.CreateObject("ADODB.RecordSet") objRS.Open "SELECT * FROM tblNewsItems WHERE dtmExpireDate < #" & _ strCutoffDate & "#;", objConn, adOpenKeyset, adLockOptimistic, adCmdText
' If there are some articles returned, print their details then remove them from the database If NOT objRS.EOF Then While NOT objRS.EOF objRS.MoveNext WEnd objConn.Execute("DELETE FROM tblNewsItems WHERE dtmExpireDate < #" & strCutoffDate & "#;") Else
' If no out of date articles were found, explain and carry on End If
' Tidy up objects objRS.Close Set objRS = Nothing objConn.Close Set objConn = Nothing

We now have the problem that adovbs.inc is not included, so as a work-around you can open up the adovbs.inc file (or whatever include files you are working with) and copy the relevant lines into your code (luckily adovbs.inc only includes constant definitions and I only need two of them. When using include files that contain large amounts of code this can make the script difficult to navigate) :

    ' Define variables
    Dim objConn, objRS
    Dim dtmCutoffDate
    Dim strCutoffDate
    
' Define constants from ADOVBS.INC Const adOpenKeyset = 1 Const adLockOptimistic = 3 Const adCmdText = &H0001;
' Make sure the date format cannot be confused (I'm paranoid about this because I'm British) dtmCutoffDate = DateAdd("d",-7,Date) strCutoffDate = Day(dtmCutoffDate) & " " & MonthName(Month(dtmCutoffDate)) & " " & _ Year(dtmCutoffDate)
' Create and setup connection object Set objConn = Server.CreateObject("ADODB.Connection") objConn.Open "MyDSN"
' Retrieve records that are to be deleted Set objRS = Server.CreateObject("ADODB.RecordSet") objRS.Open "SELECT * FROM tblNewsItems WHERE dtmExpireDate < #" & strCutoffDate & _ "#;", objConn, adOpenKeyset, adLockOptimistic, adCmdText
' If there are some articles returned, print their details then remove them from the database If NOT objRS.EOF Then While NOT objRS.EOF objRS.MoveNext WEnd objConn.Execute("DELETE FROM tblNewsItems WHERE dtmExpireDate < #" & strCutoffDate & "#;") Else
' If no out of date articles were found, explain and carry on End If
' Tidy up objects objRS.Close Set objRS = Nothing objConn.Close Set objConn = Nothing

In this example we can now see that the object "objRS" is redundant, it's whole point being for display of the data. Taking out all references to that object gives :

    ' Define variables
    Dim objConn
    Dim dtmCutoffDate
    Dim strCutoffDate
    
' Make sure the date format cannot be confused (I'm paranoid about this because I'm British) dtmCutoffDate = DateAdd("d",-7,Date) strCutoffDate = Day(dtmCutoffDate) & " " & MonthName(Month(dtmCutoffDate)) & " " & _ Year(dtmCutoffDate)
' Create and setup connection object Set objConn = Server.CreateObject("ADODB.Connection") objConn.Open "MyDSN"
' Run the SQL query objConn.Execute("DELETE FROM tblNewsItems WHERE dtmExpireDate < #" & strCutoffDate & "#;")
' Tidy up objects objRS.Close Set objRS = Nothing objConn.Close Set objConn = Nothing

This can be tidied up even further like so :

    ' Define variables
    Dim objConn
    Dim dtmCutOffDate
    
' Make sure the date format cannot be confused (I'm paranoid about this because I'm British) dtmCutoffDate = DateAdd("d",-7,Date)
' Create and setup connection object Set objConn = Server.CreateObject("ADODB.Connection") objConn.Open "MyDSN"
' Run the SQL query objConn.Execute("DELETE FROM tblNewsItems WHERE dtmExpireDate < #" & Day(dtmCutoffDate) & _ " " & MonthName(Month(dtmCutoffDate)) & " " & Year(dtmCutoffDate) & "#;")
' Tidy up objects objConn.Close Set objConn = Nothing

The script has now been stripped down to the bare basics with nothing except the real bones functionality of the original. This is much cleaner to look at and will be more efficient.

Out of interest, it is also possible to remove references to the connection object instead of references to the recordset object like so :

    ' Define variables
    Dim objRS
    
' Define constants Const adOpenKeyset = 1 Const adLockOptimistic = 3 Const adCmdText = &H0001; Const adAffectAll = 3
' Create and setup recordset object objRS.Open "SELECT * FROM tblNewsItems WHERE dtmExpireDate < #" & strCutoffDate & _ "#;", "MyDSN", adOpenKeyset, adLockOptimistic, adCmdText
' Remove out of date articles from the database objRS.Delete adAffectAll objRS.Update
' Tidy up objects objRS.Close Set objRS = Nothing

but this method is slightly less efficient because it returns the matching records before deleting them from the database whereas using the connection object deletes the entries directly from the database without loading them into memory first.

Alternatively, you may find it easier to just rewrite your code from scratch. This way you shouldn't end up accidentally including some code that was meant for formatting output which isn't needed any more.

Now that you have a script like this you need to save it with the ".vbs" extension. If you now look at the script in an Explorer window it shouw have an icon like a small scroll of blue paper. Double-clicking it actually runs the script and performs the same funcion as the ASP page on your website, but without the need to access it with a browser.

If you go to the command-line and try typing in the name of the file, you will get the standard "I don't know what to do with this file" message that you get from the console, so what you need to do is tell it that you want to run the WSH and pass it the script.

There are two ways to call the WSH engine from the command-line, which are "CSCRIPT" which calls the command-line version of the WSH, and "WSCRIPT" which calls the windows version. As the command-line version seems to have a lower overhead I'll stick to that one. Let's assume that your script is saved as "dbmaintain.vbs" in the "c:\scripts\" directory. The console command to run that script would be "cscript c:\scripts\dbmaintain.vbs". You can pass this command directly to the AT scheduller, or you can place it in a batch file and pass the batch file to AT. Voila! You now have a working maintenance script.

Here's a quick tip. If you have a server that has several tasks that need to be run at regular intervals you might find it easier to create a set of batch files representing different time-plans or repetition frequencies. e.g. you could have a batch file called "hour.bat" which is run every hour, one called "day.bat" which is run every day etc... This means you don't have to re-type the long AT commands every time you want to add or change a task, and it makes looking up what tasks are run at what frequency much easier.

Of course, database maintenance is not the only thing that this can be useful for. Several people have asked if it is possible to do something like email a client x number of days before an advertisement they have placed expires. This again is simple and just needs the SQL statement to be changed to something like:

strSQL = "SELECT strPlacerName, strPlacerEmail, dtmExpireDate FROM " & _
    	"tblAdverts WHERE dtmExpireDate >= #" & DateAdd("d",-5,Date) & "#;"

Which would return a recordset populated with all the adverts that are due to expire in the next 5 days. Emailing all of these people then would be a simple matter using CDONTS or some other mailer component. You could then improve the system to query the database for anyone whose advert expires in 5 days and give them a reminder, then look for ads that expire in 2 days and give them a more urgent message etc....

 
Report Bad Submission
Use this form to notify us if this entry should be deleted (i.e contains no code, is a virus, etc.).
Reason:
 
Your Vote!

What do you think of this article(in the Intermediate category)?
(The article with your highest vote will win this month's coding contest!)
Excellent  Good  Average  Below Average  Poor See Voting Log
 
Other User Comments
1/18/2001 10:49:05 AM:Nik Martin
I have battled with this myself, and the one area that you cannot use this method when your maintenence involves IIS type stuff. For instance, I regularly need to check a web page from my server and parse out some text. The only way I can do this is a page with a <META Refresh value = xxx> tag, and a javascript that creates the window as a small popup with no toolbars. then I minimize it and it refreshes every 600 seconds performing the IIS actions I need it to.
Keep the Planet clean! If this comment was disrespectful, please report it:
Reason:

 
11/2/2001 9:05:28 AM:AcidReign
A minor oversite: WSH does not Recognize the Server Object, as with the Response and Request Objects... so Server.CreateObject() would simply be CreateObject() ;-)
Keep the Planet clean! If this comment was disrespectful, please report it:
Reason:

 
11/2/2001 7:35:02 PM:Mark Lidstone
1) You can use this. There is an object supplied by IE that lets you grab the contents of a page without loading the GUI as well. Also, you can install Sockets from dimac.net to do the same thing. 2) I know. When I first posted this (not to this site if I remember rightly...i don't remember actually ever posting it to this site......) I noticed it soon and asked them to change it. They never did and I still get loads of emails about it today. GetObject() is more efficient anyway (providing your code is written right).
Keep the Planet clean! If this comment was disrespectful, please report it:
Reason:

 
2/18/2002 6:26:11 PM:jklukan
I realize that my comment is about 3.5 months after the last one, but I felt it important to note that the XMLHTTP object will retrieve a web page. It would not be difficult to use WSH to program the XMLHTTP object to retrieve a page at a given time/date. That page could be an ASP script that would execute actions of its own, or it could be a page that returns information to the WSH script for processing. That is what the XMLHTTP object was originally created for anyway (retrieving data from a remote location).
Keep the Planet clean! If this comment was disrespectful, please report it:
Reason:

 
Add Your Feedback!
Note:Not only will your feedback be posted, but an email will be sent to the code's author in your name.

NOTICE: The author of this article has been kind enough to share it with you.  If you have a criticism, please state it politely or it will be deleted.

For feedback not related to this particular article, please click here.
 
Name:
Comment:

 

Categories | Articles and Tutorials | Advanced Search | Recommended Reading | Upload | Newest Code | Code of the Month | Code of the Day | All Time Hall of Fame | Coding Contest | Search for a job | Post a Job | Ask a Pro Discussion Forum | Live Chat | Feedback | Customize | ASP/ VbScript Home | Site Home | Other Sites | About the Site | Feedback | Link to the Site | Awards | Advertising | Privacy

Copyright© 1997 by Exhedra Solutions, Inc. All Rights Reserved.  By using this site you agree to its Terms and Conditions.  Planet Source Code (tm) and the phrase "Dream It. Code It" (tm) are trademarks of Exhedra Solutions, Inc.