Сабж, собственно... Хотя предложенный способ может пригодится и на локальной машине.
Какая задача меня подвигла на написание этого кода:
Было необходимо, чтобы скрипт запускался на сервере через строго определенные промежутки времени.
Было необходимо, чтобы при изменении настроек скрипта (например, интервала между задачами) он это сам подхватывал.
Не хотелось при промежутке между заданиями в 1 час иметь 24 задания.
Не было доступа к шедулеру Windows (только из командной строки).
Итак, что необходимо, чтобы на хостинге заработал нижеприведенный код:
Возможность ставить скрипт в планировщик заданий (спрашивал, многие разрешают).
Возможность модификации установленного задания (пока не знаю, как с этим обстоит дело).
Наличие в той-же папке, что и скрипт, пустого файла с именем prevTask.ini
Версия WScript не ниже 5.6
Вроде все.
Принцип работы скрипта — решедулинг самого себя.
Кому это пригодится? Лично мне по работе над проектом надо... Ну и, думаю, еще кому...
Кстати, я сделал целочисленный часовой интервал между запусками. Но это легко дописывается/меняется. И еще — прошу не рассматривать данный метод как единственный и универсальный, а лишь как одно из средств решения поставленной задачи.
Итак (все пояснения — в комментариях к коду):
// shedule.js source code
//---------------------------------------------------------------------------
function DoWork() {
// сюда поместить весь код работы (работа с базой, проверка почты, пр.)
}
//---------------------------------------------------------------------------
function ReSheduleMe() {
var lastHour = 0; // последний час работы
var taskNumber = 0; // номер зашедуленной задачи
var interval = 1; // интервал в часах между запусками задачи (1-24)
// рабочая директория
var workDir = WScript.ScriptFullName.substring(0,WScript.ScriptFullName.lastIndexOf("\\")+1);
// имя файла настроек. Лежит в той-же папке, что и скрипт. Структура файла:
/*
первая строка - номер ранее зашедуленной задачи (0 - нету)
вторая строка - последний час вызова (0 - в полночь)
третья строка - интервал в часах между вызовами (сюда поставьте интервал между запусками)
*/
var prevTaskFileName = workDir + "prevTask.ini";
var prevTasks = new ActiveXObject("Scripting.FileSystemObject");
var prevTasksFile = prevTasks.OpenTextFile(prevTaskFileName,1);
// читаем настройки
try {
taskNumber = parseInt(prevTasksFile.ReadLine());
lastHour = parseInt(prevTasksFile.ReadLine());
interval = parseInt(prevTasksFile.ReadLine());
} catch(e) {}
prevTasksFile.Close();
// проверяем их на валидность
if(isNaN(lastHour) || lastHour < 0 ) lastHour = 0;
if(isNaN(taskNumber) || taskNumber < 0 ) taskNumber = 0;
if(isNaN(interval) || interval < 1 || interval > 24 ) interval = 1;
var WshShell = new ActiveXObject("WScript.Shell");
if(taskNumber > 0) { // если была - удаляем предыдущую задачу
WshShell.Run("AT " + taskNumber + " /delete /yes",0,true);
}
// увеличиваем интервал
lastHour += interval;
if(lastHour >= 24) lastHour %= 24;
// добавляем задачу в шедулер
var oExec = WshShell.Exec('cmd /c "AT ' + (lastHour<10?'0':'') + lastHour +
':00 /interactive /every:su,m,t,w,th,f,s ' +
WScript.ScriptFullName + '"');
// читаем номер добавленной задачи
var input = "";
while (!oExec.StdOut.AtEndOfStream) {
input = oExec.StdOut.ReadAll();
}
input = input.substring(input.lastIndexOf(" ") +1, input.length);
taskNumber = parseInt(input);
if(isNaN(taskNumber)) taskNumber = 0;
// записываем настройки
prevTasksFile = prevTasks.OpenTextFile(prevTaskFileName,2);
prevTasksFile.WriteLine(taskNumber);
prevTasksFile.WriteLine(lastHour);
prevTasksFile.WriteLine(interval);
prevTasksFile.CLose();
}
//---------------------------------------------------------------------------
ReSheduleMe();
DoWork();
//---------------------------------------------------------------------------