-
Notifications
You must be signed in to change notification settings - Fork 72
/
Copy pathScheduler.ahk
305 lines (253 loc) · 11.6 KB
/
Scheduler.ahk
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
/*
Function: Create
Creates new scheduled task.
Parameters:
Name - Specifies a name for the task
Run - Specifies the program or command that the task runs.
Args - Arguments of the program that the task runs.
Type - MINUTE, HOURLY, DAILY, WEEKLY, MONTHLY, ONCE, ONSTART, ONLOGON, ONIDLE. By default, ONCE.
Mod - Modifier, number, Specifies how often the task runs within its schedule type (defaults to 1). See bellow.
Day - Specifies a day of the week or a day of a month. Valid only with a WEEKLY or MONTHLY schedule.
For WEEKLY type, valid values are MON-SUN and * (every day). MON is the default.
A value of MON-SUN is required when the FIRST, SECOND, THIRD, FOURTH, or LAST modifier is used.
A value of 1-31 is optional and is valid only with no modifier or a modifier of the 1-12 type.
Month - Specifies a month of the year. Valid values are JAN - DEC and * The parameter is valid only with a MONTHLY schedule.
It is required when the LASTDAY modifier is used. Otherwise, it is optional and the default value is * (every month).
IdleTime - A whole number from 1 to 999. Specifies how many minutes the computer is idle before the task starts. This parameter is valid only with an ONIDLE schedule, and then it is required.
Time - Specifies the time of day that the task starts in HH:MM:SS 24-hour format. The default value is the current local time when the command completes. \
Valid with MINUTE, HOURLY, DAILY, WEEKLY, MONTHLY, and ONCE schedules. It is required with a ONCE schedule.
EndTime - A value that specifies the end time to run the task. The time format is HH:mm (24-hour time). For example, 14:50 specifies 2:50PM. This is not applicable for the following schedule types: ONSTART, ONLOGON, ONIDLE, and ONEVENT.
Duration - A value that specifies the duration to run the task. The time format is HH:mm (24-hour time). For example, 14:50 specifies 2:50PM. This is not applicable with /ET and for the following schedule types: ONSTART, ONLOGON, ONIDLE, and ONEVENT. For /V1 tasks (Task Scheduler 1.0 tasks), if /RI is specified, then the duration default is one hour.
StartDate - Specifies the date that the task starts in MM/DD/YYYY format. The default value is the current date. Valid with all schedules, and is required for a ONCE schedule.
EndDate - Specifies the last date that the task is scheduled to run. This parameter is optional. It is not valid in a ONCE, ONSTART, ONLOGON, or ONIDLE schedule. By default, schedules have no ending date.
Computer - Specifies the name or IP address of a remote computer (with or without backslashes). The default is the local computer.
User - Runs the command with the permissions of the specified user account. By default, the command runs with the permissions of the user logged on to the computer running SchTasks.
Password - Specifies the password of the user account specified in the _User_ parameter (required with it)
Flags - See bellow.
Flags:
K - A value that terminates the task at the end time or duration time. This is not applicable for the following schedule types: ONSTART, ONLOGON, ONIDLE, and ONEVENT. Either EndTime or Duration must be specified.
Z - A value that marks the task to be deleted after its final run.
Modifiers:
MINUTE - (1 - 1439) The task runs every n minutes.
HOURLY - (1 - 23) The task runs every n hours.
DAILY - (1 - 365) The task runs every n days.
WEEKLY - (1 - 52) The task runs every n weeks.
MONTHLY - (1 - 12) The task runs every n months. LASTDAY - The task runs on the last day of the month. FIRST, SECOND, THIRD, FOURTH, LAST Use with the /d day parameter to run a task on a particular week and day. For example, on the third Wednesday of the month.
*/
Scheduler_Create( v, bForce=false ) {
static arguments="Type Mod Day Month IdleTime Time EndDate Computer User Password StartDate EndTime Duration Repeat"
static Type="/sc", Mod="/mo", Day="/d", Month="/m", IdleTime="/i", Time="/st", EndDate="/ed", Computer="/s", User="/u", Password="/p", StartDate="/sd", EndTime="/et", Duration="/du", Repeat="/ri"
Name := %v%_Name, Run := %v%_Run, Args := %v%_Args
;errors
if (Name = "")
return "ERROR: No value specified for 'Name' option."
if (Run = "")
return "ERROR: No value specified for 'Run' option."
;defaults
if ( %v%_Type = "" )
%v%_Type := "ONCE"
if (%v%_Computer = "")
%v%_Computer := "localhost"
;check for 2.0
if A_OSVersion not in WIN_VISTA
{
if (%v%_EndTime != "")
return A_ThisFunc "> Your OS doesn't support this feature: EndTime"
if (%v%_Duration != "")
return A_ThisFunc "> Your OS doesn't support this feature: Duration"
if (%v%_Flags != "")
return A_ThisFunc "> Your OS doesn't support this feature: Flags"
}
;generate cmd line
cmd = /create /tn "%Name%" /tr "\"%Run%\" %Args%"
loop, parse, arguments, %A_Space%
{
c := %A_LoopField%,
val := %v%_%A_LoopField%
StringReplace, val, val, `",, A
if val !=
cmd = %cmd% %c% %val%
}
;add flags
loop, parse, %v%_Flags
cmd .= " /" A_LoopField
;in vista it can be done with /F but this works too...
if Scheduler_Exists(Name)
{
if !bForce
{
Msgbox, 36, %A_ThisFunc%, Scheduled task '%Name%' already exists.`n`nDo you want to overwrite ?
IfMsgBox No
return "Operation canceled."
}
Scheduler_Delete( %v%_Name, true)
}
res := Scheduler_run("Schtasks " cmd)
StringReplace, res, res, `r`nType "SCHTASKS /CREATE /?" for usage.`r`n
return res
}
/* Function: ClearVar
Clears the global array.
*/
Scheduler_ClearVar(v){
static args="Computer,Name,NextRun,LastRun,User,Run,State,Time,Type,StartDate,EndDate,LastResult,Mod"
loop, parse, args, `,
%v%_%A_LoopField% := ""
}
/*
Function: Delete
Delete specified scheduled task
Parameters:
Name - Specifies the name of task to be deleted. Use "*" to delete all tasks.
bForce - Surpess confimration message, false by default.
*/
Scheduler_Delete( Name, bForce=false, User="", Password="", Computer="")
{
StringReplace, Name, Name, `", ,A
if (!bForce) {
Msgbox, 36, %A_ThisFunc%, Are you sure you want to delete task "%Name%" ?
IfMsgBox No, return
}
cmd = /delete /f /tn "%Name%" %A_Space%
cmd .= User != "" ? "/u" User : ""
cmd .= Password != "" ? "/p" Password : ""
cmd .= Computer != "" ? "/s" Computer : ""
res := Scheduler_run("Schtasks " cmd)
return res
}
/*
Function: Query
Query specified scheduled task or all tasks.
Parameters:
Name - Specifies the name of task. Use empty string to return all tasks.
var - If non empty, variable prefix for task parameters extraction.
*/
Scheduler_Query(Name="", var=""){
global
static args="Computer,Name,NextRun,LastRun,User,Run,State,Time,Type,StartDate,EndDate,LastResult,Mod"
static 1="Computer",2="Name",3="NextRun",6="LastRun",7="LastResult",8="User",9="Run",12="State",20="Time",21="StartDate",22="EndDate",23="Day",24="Month",25="Mod"
local cmd, res, p, out, out1
if A_OSVersion in WIN_VISTA
{
StringReplace, Name, Name, `", ,A
cmd := "Schtasks /query /fo CSV /v " (Name != "" ? "/tn """ Name """" : "")
res := Scheduler_run(cmd)
if InStr(res, "ERROR: The system cannot find the file specified")
res := ""
;remove header, /NH has a bug : Schtasks /query /fo CSV /v /NH /tn "ISPP Konzola StanjaPodracunaISPP" ---> reports that LIST ouptut is active ....
res := SubStr(res, InStr(res, "`n")+1)
} else {
cmd := "/query /fo CSV /v"
res := Scheduler_run("Schtasks " cmd)
}
if (var != ""){
Scheduler_ClearVar( var )
loop, parse, res, CSV
{
ifEqual, A_Index, 26, break
f := %A_Index%
ifEqual, f, ,continue
%var%_%f% := Scheduler_fixData(f, A_LoopField)
}
}
return res
}
/* Function: Exists
Check if task exists.
Parameter:
Name - Name of the task.
*/
Scheduler_Exists(Name) {
if A_OsVersion in WIN_VISTA
return Scheduler_Query(Name) != ""
else if InStr("`n" Scheduler_Run("schtasks /query /fo CSV /NH"), """" Name """")
return true
}
/* Function: Exists
Check if task exists.
Parameter:
Name - Name of the task.
*/
Scheduler_Enable( Name, Value ) {
if A_OsVersion not in WIN_VISTA
return A_ThisFunc "> Your OS doesn't support this feature"
Scheduler_Run("schtasks /change /TN """ Name """ /" Value ? "ENABLE" : "DISABLE")
}
/* Function: Open
Opens or activates the Task Scheduler.
Returns:
PID of Task Scheduler process.
*/
Scheduler_Open() {
static PID
if WinExist("ahk_pid " PID) {
WinActivate, ahk_pid %PID%
return
}
if A_OSVersion in WIN_VISTA
Run, %A_WinDir%\system32\mmc.exe %A_WinDir%\system32\taskschd.msc,,,PID
else Run, %A_WinDir%\explorer.exe ::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\::{21EC2020-3AEA-1069-A2DD-08002B30309D}\::{D6277990-4C6A-11CF-8D87-00AA0060F5BF},,,PID
return PID
}
;fix garbadge data reported by schtasks app.
Scheduler_fixData( Field, Value ) {
if (Field = "Mod")
if RegExMatch( Value, "S)(\d+)\D+(\d+)", m) ;1 Hour(s), 10 Minute(s)
return m1*60 + m2
return Value
}
;v1.2
Scheduler_run(Cmd, Dir = "", Skip=0, Input = "", Stream = "")
{
DllCall("CreatePipe", "UintP", hStdInRd , "UintP", hStdInWr , "Uint", 0, "Uint", 0)
DllCall("CreatePipe", "UintP", hStdOutRd, "UintP", hStdOutWr, "Uint", 0, "Uint", 0)
DllCall("SetHandleInformation", "Uint", hStdInRd , "Uint", 1, "Uint", 1)
DllCall("SetHandleInformation", "Uint", hStdOutWr, "Uint", 1, "Uint", 1)
VarSetCapacity(pi, 16, 0)
NumPut(VarSetCapacity(si, 68, 0), si) ; size of si
,NumPut(0x100, si, 44) ; STARTF_USESTDHANDLES
,NumPut(hStdInRd, si, 56) ; hStdInput
,NumPut(hStdOutWr, si, 60) ; hStdOutput
,NumPut(hStdOutWr, si, 64) ; hStdError
If !DllCall("CreateProcess", "Uint", 0, "Uint", &Cmd, "Uint", 0, "Uint", 0, "int", True, "Uint", 0x08000000, "Uint", 0, "Uint", Dir ? &Dir : 0, "Uint", &si, "Uint", &pi) ; bInheritHandles and CREATE_NO_WINDOW
return A_ThisFunc "> Can't create process:`n" Cmd
hProcess := NumGet(pi,0)
DllCall("CloseHandle", "Uint", NumGet(pi,4)), DllCall("CloseHandle", "Uint", hStdOutWr), DllCall("CloseHandle", "Uint", hStdInRd)
If Input !=
DllCall("WriteFile", "Uint", hStdInWr, "Uint", &Input, "Uint", StrLen(Input), "UintP", nSize, "Uint", 0)
DllCall("CloseHandle", "Uint", hStdInWr)
if (Stream+0)
bAlloc := DllCall("AllocConsole") ,hCon:=DllCall("CreateFile","str","CON","Uint",0x40000000,"Uint", bAlloc ? 0 : 3, "Uint",0, "Uint",3, "Uint",0, "Uint",0)
VarSetCapacity(sTemp, nTemp:=Stream ? 64-nTrim:=1 : 4095)
loop
If DllCall("ReadFile", "Uint", hStdOutRd, "Uint", &sTemp, "Uint", nTemp, "UintP", nSize:=0, "Uint", 0) && nSize
{
NumPut(0,sTemp,nSize,"Uchar"), VarSetCapacity(sTemp,-1), sOutput .= sTemp
if Stream
loop
if RegExMatch(sOutput, "S)[^\n]*\n", sTrim, nTrim)
Stream+0 ? DllCall("WriteFile", "Uint", hCon, "Uint", &sTrim, "Uint", StrLen(sTrim), "UintP", 0, "Uint", 0) : %Stream%(sTrim), nTrim += StrLen(sTrim)
else break
}
else break
DllCall("CloseHandle", "Uint", hStdOutRd)
Stream+0 ? (DllCall("Sleep", "Uint", 1000), hCon+1 ? DllCall("CloseHandle","Uint", hCon) : "", bAlloc ? DllCall("FreeConsole") : "" ) : ""
DllCall("GetExitCodeProcess", "uint", hProcess, "intP", ExitCode), DllCall("CloseHandle", "Uint", hProcess)
if (Skip != ""){
StringSplit, s, Skip, .,
StringReplace, sOutput, sOutput, `n, `n, A UseErrorLevel
s2 := ErrorLevel - (s2 ? s2 : 0) + 1, s1++
loop, parse, sOutput,`n,`r
if A_Index between %s1% and %s2%
s .= A_LoopField "`r`n"
StringTrimRight, sOutput, s, 2
}
ErrorLevel := ExitCode
return sOutput
}
/*
Group: About
o v0.94 by majkinetor.
o Schtasks at MSDN: http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/schtasks.mspx?mfr=true
o Licenced under GNU GPL <http://creativecommons.org/licenses/GPL/2.0/>
*/