After installing Drupal you will notice it requires a script to be run periodically using something called Cron. This is a Unix process unavailable on a Windows machine. Although Drupal provides an option to run this script manually I thought it would be useful to simulate a Cron process on Uniform Server. The technique can be adapted to other scripts that require a Cron process to be run.
The script Drupal requires running via a cron-job is cron.php, which can be found in either the server web-root or the folder you installed Drupal in.
When logged in as administrator you can run the cron job manually using a link provided. Alternatively run the script from a browser by typing the following:
http://localhost/cron.php or if install in a separate folder named “drupal” http://localhost/drupal/cron.php
On a local server all that is required is to run cron.php from a batch file using PHP in CLI mode (check out this page for CLI mode)
Batch file - intro
Create a batch file named run_cron.bat add the following two lines and save it in folder “Uniform Server”:
udrive\usr\local\php\php.exe -n udrive\www\cron.php pause
PHP is run with switch –n this prevents PHP loading a configuration file (php.ini). Second parameter is the path and file name of the file to be run.
Note 1: “pause” is included allowing you to view any error messages.
Note 2: I install Drupal in the web-root folder “www” if you install in a seperate folder (drupal) remember to change the path to udrive\www\drupal\cron.php
- Start Uniform Server
- Run the above batch file
You will see a list of warnings and a fatal error message similar to this:
J:\drupal_server\Uniform Server>udrive\usr\local\php\php.exe -n udrive\www\cron.php Warning: include_once(./includes/bootstrap.inc): failed to open stream: No such file or directory in J:\drupal_server\Un iform Server\udrive\www\cron.php on line 9 Warning: include_once(): Failed opening './includes/bootstrap.inc' for inclusion (include_path='.;C:\php5\pear') in J:\d rupal_server\Uniform Server\udrive\www\cron.php on line 9 Fatal error: Call to undefined function drupal_bootstrap() in J:\drupal_server\Uniform Server\udrive\www\cron.php on lin e 10 J:\drupal_server\Uniform Server>pause Press any key to continue . . .
I have included the above to highlight paths are local and not server relative as expected by Drupal. The solution is to run cron.php on your live server as explained below.
Additional script and new batch file
Create a new PHP script named run_cron.php containing the following code and save it to folder containing cron.php.
<? $dummy = file("http://localhost/cron.php"); ?>
This script executes the file function reading the content of cron.php into a dummy array (the variable $dummy is never used). What’s important is the path to the file, its what would be typed into a browser meaning that page is run on the server with correct paths to other files it calls.
Change the batch file to call this new script as follows:
udrive\usr\local\php\php.exe -n udrive\www\run_cron.php pause
Run the new batch file this time there will be no errors.
Log into Drupal as admin; click the Status report link. To the right of “Cron maintenance tasks” note the “Last run” time.
Run batch file again, refresh page the time will update confirming scripts work.
Note: Just below “Cron maintenance tasks” you will find the link to manually run the cron task.
OK! Seems like we have created a long-winded method to duplicate the same function. That’s not strictly true the two files batch and script provide full control independent of a web browser.
There are two methods of periodically running run_cron.bat the first is to set-up Windows to schedule a task. I will not be covering this check out the following link for details http://support.microsoft.com/kb/308569
The second method is to modify run_cron.bat so it periodically runs the line of code that executes run_con.php; this has the advantage of portability. Remainder of this write-up covers this in detail.
Batch file with delay loop
Modify run_cron.bat as follows:
:next ping 184.108.40.206 -n 1 -w 60000 > nul udrive\usr\local\php\php.exe -n udrive\www\run_cron.php goto :next
The ping command introduces a delay of 60 seconds (60000ms). After this delay cron-job is run and loops back to “next” repeating the whole process.
Run the batch file and you will instantly observe a problem! The command window remains open.
Interestingly when Apache is run as a program it suffers from this same problem. Solution is to run Apache in a hidden process using uniserve.exe. Applying this to our cron problem results in a working solution although it requires a second batch file as follows:
Create a new batch file in folder “Uniform Server” named run_cron_hidden.bat and add the following lines:
start udrive\home\admin\program\uniserv.exe run_cron.bat pause
Run this new batch file, when requested press any key this closes the command window however run_cron command window remains running and hidden.
The above is a solution but far from ideal once started cron cannot be stopped until the PC is restarted (normally what is required). The reliance of ping as a delay is another issue. If the IP address is active the delay fails, solution is to use unidelay.exe for details refer to this page.
Final batch files and scripts are shown below:
<? $dummy = file("http://localhost/cron.php"); ?>
start udrive\home\admin\program\uniserv.exe run_cron.bat
:next unidelay.exe 60 udrive\usr\local\php\php.exe -n udrive\www\run_cron.php goto :next exit
Note: unidelay.exe 60 runs the cron-job every 60 seconds increase this as required.
The above-proposed solution is generic and can be adapted to other application requiring periodic running of an application.
As part of the LCC series I cover a small utility that specifically targets Drupal with a portable cron program. You can recompile this to meet your own requirements or use it as is.