win32-taskscheduler 2.0.1 → 2.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/win32-taskscheduler.rb +1 -1
- data/lib/win32/taskscheduler.rb +266 -292
- data/lib/win32/taskscheduler/constants.rb +6 -6
- data/lib/win32/taskscheduler/helper.rb +10 -10
- data/lib/win32/taskscheduler/sid.rb +12 -12
- data/lib/win32/taskscheduler/time_calc_helper.rb +71 -40
- data/lib/win32/taskscheduler/version.rb +1 -1
- metadata +5 -53
- data/CHANGELOG.md +0 -184
- data/Gemfile +0 -3
- data/README.md +0 -78
- data/RELEASE_NOTES.md +0 -14
- data/Rakefile +0 -38
- data/VERSION +0 -1
- data/appveyor.yml +0 -40
- data/examples/taskscheduler_example.rb +0 -54
- data/spec/functional/win32/taskscheduler/time_calc_helper_spec.rb +0 -392
- data/spec/functional/win32/taskscheduler_spec.rb +0 -883
- data/spec/spec_helper.rb +0 -224
- data/spec/unit/win32/taskscheduler/constants_spec.rb +0 -20
- data/spec/unit/win32/taskscheduler/time_calc_helper_spec.rb +0 -217
- data/spec/unit/win32/taskscheduler_spec.rb +0 -169
- data/test/test_taskscheduler.rb +0 -690
- data/win32-taskscheduler.gemspec +0 -34
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 00e707355e5575715bf3e9dbc5c393b961f25582297aeabf0c1c0d926bdc5b57
|
4
|
+
data.tar.gz: '04017484cc39076681c335c3be0698b14242bb7ef72041a1b67795d31dea44a0'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d0b8dd84740d507701fa5968bf495d576656428f03b27230f62aedcee15fde5977243d838c343f95eed78a23203b0b5390d0ba2636e79b43aacf114b9c946429
|
7
|
+
data.tar.gz: 265ae1a999a3edded0a35e4b43062373be85ab5f0f239fc9b8300ffdb5f2266d46f2b3bae485b50adacf670cedee6cd086fadb4d22f8a9d7d95ff68b3f8ecaab
|
data/lib/win32-taskscheduler.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
require_relative
|
1
|
+
require_relative "win32/taskscheduler"
|
data/lib/win32/taskscheduler.rb
CHANGED
@@ -1,16 +1,15 @@
|
|
1
|
-
require_relative
|
2
|
-
require_relative
|
3
|
-
require_relative
|
4
|
-
require_relative
|
5
|
-
require_relative
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
1
|
+
require_relative "taskscheduler/sid"
|
2
|
+
require_relative "taskscheduler/helper"
|
3
|
+
require_relative "taskscheduler/time_calc_helper"
|
4
|
+
require_relative "taskscheduler/constants"
|
5
|
+
require_relative "taskscheduler/version"
|
6
|
+
require "win32ole"
|
7
|
+
require "socket"
|
8
|
+
require "time"
|
9
|
+
require "structured_warnings"
|
10
10
|
|
11
11
|
# The Win32 module serves as a namespace only
|
12
12
|
module Win32
|
13
|
-
|
14
13
|
# The TaskScheduler class encapsulates a Windows scheduled task
|
15
14
|
class TaskScheduler
|
16
15
|
include Win32::TaskScheduler::Helper
|
@@ -117,13 +116,11 @@ module Win32
|
|
117
116
|
THIRTY_FIRST = TASK_THIRTY_FIRST
|
118
117
|
LAST = TASK_LAST
|
119
118
|
|
120
|
-
|
121
119
|
# :startdoc:
|
122
120
|
|
123
121
|
attr_accessor :password
|
124
122
|
attr_reader :host
|
125
123
|
|
126
|
-
|
127
124
|
def root_path(path = '\\')
|
128
125
|
path
|
129
126
|
end
|
@@ -144,14 +141,14 @@ module Win32
|
|
144
141
|
@task = nil
|
145
142
|
@password = nil
|
146
143
|
|
147
|
-
raise ArgumentError, "invalid folder" unless folder.include?(
|
144
|
+
raise ArgumentError, "invalid folder" unless folder.include?('\\')
|
148
145
|
|
149
146
|
unless [TrueClass, FalseClass].include?(force.class)
|
150
147
|
raise TypeError, "invalid force value"
|
151
148
|
end
|
152
149
|
|
153
150
|
begin
|
154
|
-
@service = WIN32OLE.new(
|
151
|
+
@service = WIN32OLE.new("Schedule.Service")
|
155
152
|
rescue WIN32OLERuntimeError => err
|
156
153
|
raise Error, err.inspect
|
157
154
|
end
|
@@ -173,9 +170,7 @@ module Win32
|
|
173
170
|
@root = @service.GetFolder(folder)
|
174
171
|
end
|
175
172
|
|
176
|
-
if task && trigger
|
177
|
-
new_work_item(task, trigger)
|
178
|
-
end
|
173
|
+
new_work_item(task, trigger) if task && trigger
|
179
174
|
end
|
180
175
|
|
181
176
|
# Returns an array of scheduled task names.
|
@@ -201,13 +196,13 @@ module Win32
|
|
201
196
|
path = nil
|
202
197
|
task_name = nil
|
203
198
|
|
204
|
-
if full_task_path.include?(
|
199
|
+
if full_task_path.include?('\\')
|
205
200
|
*path, task_name = full_task_path.split('\\')
|
206
201
|
else
|
207
202
|
task_name = full_task_path
|
208
203
|
end
|
209
204
|
|
210
|
-
folder = path.nil? ? root_path : path.join(
|
205
|
+
folder = path.nil? ? root_path : path.join('\\')
|
211
206
|
|
212
207
|
begin
|
213
208
|
root = @service.GetFolder(folder)
|
@@ -236,7 +231,7 @@ module Win32
|
|
236
231
|
registeredTask = @root.GetTask(task)
|
237
232
|
@task = registeredTask
|
238
233
|
rescue WIN32OLERuntimeError => err
|
239
|
-
raise Error, ole_error(
|
234
|
+
raise Error, ole_error("activate", err)
|
240
235
|
end
|
241
236
|
end
|
242
237
|
|
@@ -250,7 +245,7 @@ module Win32
|
|
250
245
|
registeredTask.Enabled = 1
|
251
246
|
@task = registeredTask
|
252
247
|
rescue WIN32OLERuntimeError => err
|
253
|
-
raise Error, ole_error(
|
248
|
+
raise Error, ole_error("activate", err)
|
254
249
|
end
|
255
250
|
end
|
256
251
|
|
@@ -262,7 +257,7 @@ module Win32
|
|
262
257
|
begin
|
263
258
|
@root.DeleteTask(task, 0)
|
264
259
|
rescue WIN32OLERuntimeError => err
|
265
|
-
raise Error, ole_error(
|
260
|
+
raise Error, ole_error("DeleteTask", err)
|
266
261
|
end
|
267
262
|
end
|
268
263
|
|
@@ -276,7 +271,7 @@ module Win32
|
|
276
271
|
# This method no longer has any effect. It is a no-op that remains for
|
277
272
|
# backwards compatibility. It will be removed in 0.4.0.
|
278
273
|
#
|
279
|
-
def save(
|
274
|
+
def save(_file = nil)
|
280
275
|
warn DeprecatedMethodWarning, "this method is no longer necessary"
|
281
276
|
check_for_active_task
|
282
277
|
# Do nothing, deprecated.
|
@@ -300,7 +295,7 @@ module Win32
|
|
300
295
|
begin
|
301
296
|
@service.Connect(host)
|
302
297
|
rescue WIN32OLERuntimeError => err
|
303
|
-
raise Error, ole_error(
|
298
|
+
raise Error, ole_error("Connect", err)
|
304
299
|
end
|
305
300
|
|
306
301
|
@host = host
|
@@ -317,7 +312,7 @@ module Win32
|
|
317
312
|
begin
|
318
313
|
@service.Connect(host, user, domain, password)
|
319
314
|
rescue WIN32OLERuntimeError => err
|
320
|
-
raise Error, ole_error(
|
315
|
+
raise Error, ole_error("Connect", err)
|
321
316
|
end
|
322
317
|
|
323
318
|
@host = host
|
@@ -331,7 +326,8 @@ module Win32
|
|
331
326
|
# Sets the +user+ and +password+ for the given task. If the user and
|
332
327
|
# password are set properly then true is returned.
|
333
328
|
# throws TypeError if password is not provided for other than system users
|
334
|
-
def set_account_information(user_id, password)
|
329
|
+
def set_account_information(user_id, password, interactive)
|
330
|
+
@interactive ||= interactive
|
335
331
|
check_credential_requirements(user_id, password)
|
336
332
|
check_for_active_task
|
337
333
|
@password = password
|
@@ -463,32 +459,32 @@ module Win32
|
|
463
459
|
def priority
|
464
460
|
check_for_active_task
|
465
461
|
|
466
|
-
case @task.Definition.Settings.Priority
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
462
|
+
priority = case @task.Definition.Settings.Priority
|
463
|
+
when 0
|
464
|
+
"critical"
|
465
|
+
when 1
|
466
|
+
"highest"
|
467
|
+
when 2
|
468
|
+
"above_normal_2"
|
469
|
+
when 3
|
470
|
+
"above_normal_3"
|
471
|
+
when 4
|
472
|
+
"normal_4"
|
473
|
+
when 5
|
474
|
+
"normal_5"
|
475
|
+
when 6
|
476
|
+
"normal_6"
|
477
|
+
when 7
|
478
|
+
"below_normal_7"
|
479
|
+
when 8
|
480
|
+
"below_normal_8"
|
481
|
+
when 9
|
482
|
+
"lowest"
|
483
|
+
when 10
|
484
|
+
"idle"
|
485
|
+
else
|
486
|
+
"unknown"
|
487
|
+
end
|
492
488
|
|
493
489
|
priority
|
494
490
|
end
|
@@ -517,99 +513,91 @@ module Win32
|
|
517
513
|
|
518
514
|
# If user ID is not given, consider it as a 'SYSTEM' user
|
519
515
|
userinfo[:user] = SERVICE_ACCOUNT_USERS.first if userinfo[:user].to_s.empty?
|
516
|
+
@password = userinfo[:password]
|
517
|
+
@interactive = userinfo[:interactive]
|
520
518
|
|
521
519
|
check_credential_requirements(userinfo[:user], userinfo[:password])
|
522
520
|
|
523
521
|
taskDefinition = @service.NewTask(0)
|
524
|
-
taskDefinition.RegistrationInfo.Description =
|
525
|
-
taskDefinition.RegistrationInfo.Author =
|
522
|
+
taskDefinition.RegistrationInfo.Description = ""
|
523
|
+
taskDefinition.RegistrationInfo.Author = ""
|
526
524
|
taskDefinition.Settings.StartWhenAvailable = false
|
527
|
-
taskDefinition.Settings.Enabled
|
525
|
+
taskDefinition.Settings.Enabled = true
|
528
526
|
taskDefinition.Settings.Hidden = false
|
529
527
|
|
530
|
-
|
531
|
-
|
532
528
|
unless trigger.empty?
|
533
|
-
raise ArgumentError,
|
529
|
+
raise ArgumentError, "Unknown trigger type" unless valid_trigger_option(trigger[:trigger_type])
|
534
530
|
validate_trigger(trigger)
|
535
531
|
|
536
|
-
startTime = "%04d-%02d-%02dT%02d:%02d:00"
|
537
|
-
trigger[:start_year], trigger[:start_month], trigger[:start_day],
|
538
|
-
trigger[:start_hour], trigger[:start_minute]
|
539
|
-
]
|
532
|
+
startTime = format("%04d-%02d-%02dT%02d:%02d:00", trigger[:start_year], trigger[:start_month], trigger[:start_day], trigger[:start_hour], trigger[:start_minute])
|
540
533
|
|
541
534
|
# Set defaults
|
542
535
|
trigger[:end_year] ||= 0
|
543
536
|
trigger[:end_month] ||= 0
|
544
537
|
trigger[:end_day] ||= 0
|
545
538
|
|
546
|
-
endTime = "%04d-%02d-%02dT00:00:00"
|
547
|
-
trigger[:end_year], trigger[:end_month], trigger[:end_day]
|
548
|
-
]
|
539
|
+
endTime = format("%04d-%02d-%02dT00:00:00", trigger[:end_year], trigger[:end_month], trigger[:end_day])
|
549
540
|
|
550
541
|
trig = taskDefinition.Triggers.Create(trigger[:trigger_type].to_i)
|
551
542
|
trig.Id = "RegistrationTriggerId#{taskDefinition.Triggers.Count}"
|
552
|
-
trig.StartBoundary = startTime if startTime !=
|
553
|
-
trig.EndBoundary = endTime if endTime !=
|
543
|
+
trig.StartBoundary = startTime if startTime != "0000-00-00T00:00:00"
|
544
|
+
trig.EndBoundary = endTime if endTime != "0000-00-00T00:00:00"
|
554
545
|
trig.Enabled = true
|
555
546
|
|
556
547
|
repetitionPattern = trig.Repetition
|
557
548
|
|
558
549
|
if trigger[:minutes_duration].to_i > 0
|
559
|
-
repetitionPattern.Duration = "PT#{trigger[:minutes_duration]||0}M"
|
550
|
+
repetitionPattern.Duration = "PT#{trigger[:minutes_duration] || 0}M"
|
560
551
|
end
|
561
552
|
|
562
553
|
if trigger[:minutes_interval].to_i > 0
|
563
|
-
repetitionPattern.Interval = "PT#{trigger[:minutes_interval]||0}M"
|
554
|
+
repetitionPattern.Interval = "PT#{trigger[:minutes_interval] || 0}M"
|
564
555
|
end
|
565
556
|
|
566
557
|
tmp = trigger[:type]
|
567
558
|
tmp = nil unless tmp.is_a?(Hash)
|
568
559
|
|
569
560
|
case trigger[:trigger_type]
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
561
|
+
when TASK_TIME_TRIGGER_DAILY
|
562
|
+
trig.DaysInterval = tmp[:days_interval] if tmp && tmp[:days_interval]
|
563
|
+
if trigger[:random_minutes_interval].to_i > 0
|
564
|
+
trig.RandomDelay = "PT#{trigger[:random_minutes_interval]}M"
|
565
|
+
end
|
566
|
+
when TASK_TIME_TRIGGER_WEEKLY
|
567
|
+
trig.DaysOfWeek = tmp[:days_of_week] if tmp && tmp[:days_of_week]
|
568
|
+
trig.WeeksInterval = tmp[:weeks_interval] if tmp && tmp[:weeks_interval]
|
569
|
+
if trigger[:random_minutes_interval].to_i > 0
|
570
|
+
trig.RandomDelay = "PT#{trigger[:random_minutes_interval] || 0}M"
|
571
|
+
end
|
572
|
+
when TASK_TIME_TRIGGER_MONTHLYDATE
|
573
|
+
trig.MonthsOfYear = tmp[:months] if tmp && tmp[:months]
|
574
|
+
trig.DaysOfMonth = tmp[:days] if tmp && tmp[:days]
|
575
|
+
if trigger[:random_minutes_interval].to_i > 0
|
576
|
+
trig.RandomDelay = "PT#{trigger[:random_minutes_interval] || 0}M"
|
577
|
+
end
|
578
|
+
trig.RunOnLastDayOfMonth = trigger[:run_on_last_day_of_month] if trigger[:run_on_last_day_of_month]
|
579
|
+
when TASK_TIME_TRIGGER_MONTHLYDOW
|
580
|
+
trig.MonthsOfYear = tmp[:months] if tmp && tmp[:months]
|
581
|
+
trig.DaysOfWeek = tmp[:days_of_week] if tmp && tmp[:days_of_week]
|
582
|
+
trig.WeeksOfMonth = tmp[:weeks_of_month] if tmp && tmp[:weeks_of_month]
|
583
|
+
if trigger[:random_minutes_interval].to_i > 0
|
584
|
+
trig.RandomDelay = "PT#{trigger[:random_minutes_interval] || 0}M"
|
585
|
+
end
|
586
|
+
trig.RunOnLastWeekOfMonth = trigger[:run_on_last_week_of_month] if trigger[:run_on_last_week_of_month]
|
587
|
+
when TASK_TIME_TRIGGER_ONCE
|
588
|
+
if trigger[:random_minutes_interval].to_i > 0
|
589
|
+
trig.RandomDelay = "PT#{trigger[:random_minutes_interval] || 0}M"
|
590
|
+
end
|
591
|
+
when TASK_EVENT_TRIGGER_AT_SYSTEMSTART
|
592
|
+
trig.Delay = "PT#{trigger[:delay_duration] || 0}M"
|
593
|
+
when TASK_EVENT_TRIGGER_AT_LOGON
|
594
|
+
trig.UserId = trigger[:user_id] if trigger[:user_id]
|
595
|
+
trig.Delay = "PT#{trigger[:delay_duration] || 0}M"
|
605
596
|
end
|
606
597
|
end
|
607
598
|
|
608
599
|
act = taskDefinition.Actions.Create(0)
|
609
|
-
act.Path =
|
610
|
-
|
611
|
-
@password = userinfo[:password]
|
612
|
-
@interactive = userinfo[:interactive]
|
600
|
+
act.Path = "cmd"
|
613
601
|
|
614
602
|
register_task_definition(taskDefinition, task, userinfo[:user], userinfo[:password])
|
615
603
|
|
@@ -634,7 +622,7 @@ module Win32
|
|
634
622
|
def trigger_string(index)
|
635
623
|
raise TypeError unless index.is_a?(Numeric)
|
636
624
|
check_for_active_task
|
637
|
-
index += 1
|
625
|
+
index += 1 # first item index is 1
|
638
626
|
|
639
627
|
begin
|
640
628
|
trigger = @task.Definition.Triggers.Item(index)
|
@@ -652,7 +640,7 @@ module Win32
|
|
652
640
|
def delete_trigger(index)
|
653
641
|
raise TypeError unless index.is_a?(Numeric)
|
654
642
|
check_for_active_task
|
655
|
-
index += 1
|
643
|
+
index += 1 # first item index is 1
|
656
644
|
|
657
645
|
definition = @task.Definition
|
658
646
|
definition.Triggers.Remove(index)
|
@@ -667,57 +655,57 @@ module Win32
|
|
667
655
|
def trigger(index)
|
668
656
|
raise TypeError unless index.is_a?(Numeric)
|
669
657
|
check_for_active_task
|
670
|
-
index += 1
|
658
|
+
index += 1 # first item index is 1
|
671
659
|
|
672
660
|
begin
|
673
661
|
trig = @task.Definition.Triggers.Item(index)
|
674
662
|
rescue WIN32OLERuntimeError => err
|
675
|
-
raise Error, ole_error(
|
663
|
+
raise Error, ole_error("Item", err)
|
676
664
|
end
|
677
665
|
|
678
666
|
trigger = {}
|
679
667
|
|
680
668
|
case trig.Type
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
669
|
+
when TASK_TIME_TRIGGER_DAILY
|
670
|
+
tmp = {}
|
671
|
+
tmp[:days_interval] = trig.DaysInterval
|
672
|
+
trigger[:type] = tmp
|
673
|
+
trigger[:random_minutes_interval] = time_in_minutes(trig.RandomDelay)
|
674
|
+
when TASK_TIME_TRIGGER_WEEKLY
|
675
|
+
tmp = {}
|
676
|
+
tmp[:weeks_interval] = trig.WeeksInterval
|
677
|
+
tmp[:days_of_week] = trig.DaysOfWeek
|
678
|
+
trigger[:type] = tmp
|
679
|
+
trigger[:random_minutes_interval] = time_in_minutes(trig.RandomDelay)
|
680
|
+
when TASK_TIME_TRIGGER_MONTHLYDATE
|
681
|
+
tmp = {}
|
682
|
+
tmp[:months] = trig.MonthsOfYear
|
683
|
+
tmp[:days] = trig.DaysOfMonth
|
684
|
+
trigger[:type] = tmp
|
685
|
+
trigger[:random_minutes_interval] = time_in_minutes(trig.RandomDelay)
|
686
|
+
trigger[:run_on_last_day_of_month] = trig.RunOnLastDayOfMonth
|
687
|
+
when TASK_TIME_TRIGGER_MONTHLYDOW
|
688
|
+
tmp = {}
|
689
|
+
tmp[:months] = trig.MonthsOfYear
|
690
|
+
tmp[:days_of_week] = trig.DaysOfWeek
|
691
|
+
tmp[:weeks_of_month] = trig.WeeksOfMonth
|
692
|
+
trigger[:type] = tmp
|
693
|
+
trigger[:random_minutes_interval] = time_in_minutes(trig.RandomDelay)
|
694
|
+
trigger[:run_on_last_week_of_month] = trig.RunOnLastWeekOfMonth
|
695
|
+
when TASK_TIME_TRIGGER_ONCE
|
696
|
+
tmp = {}
|
697
|
+
tmp[:once] = nil
|
698
|
+
trigger[:type] = tmp
|
699
|
+
trigger[:random_minutes_interval] = time_in_minutes(trig.RandomDelay)
|
700
|
+
when TASK_EVENT_TRIGGER_AT_SYSTEMSTART
|
701
|
+
trigger[:delay_duration] = time_in_minutes(trig.Delay)
|
702
|
+
when TASK_EVENT_TRIGGER_AT_LOGON
|
703
|
+
trigger[:user_id] = trig.UserId if trig.UserId.to_s != ""
|
704
|
+
trigger[:delay_duration] = time_in_minutes(trig.Delay)
|
705
|
+
when TASK_EVENT_TRIGGER_ON_IDLE
|
706
|
+
trigger[:execution_time_limit] = time_in_minutes(trig.ExecutionTimeLimit)
|
707
|
+
else
|
708
|
+
raise Error, "Unknown trigger type"
|
721
709
|
end
|
722
710
|
|
723
711
|
trigger[:start_year], trigger[:start_month], trigger[:start_day],
|
@@ -759,7 +747,7 @@ module Win32
|
|
759
747
|
#
|
760
748
|
def trigger=(trigger)
|
761
749
|
raise TypeError unless trigger.is_a?(Hash)
|
762
|
-
raise ArgumentError,
|
750
|
+
raise ArgumentError, "Unknown trigger type" unless valid_trigger_option(trigger[:trigger_type])
|
763
751
|
|
764
752
|
check_for_active_task
|
765
753
|
|
@@ -768,75 +756,70 @@ module Win32
|
|
768
756
|
definition = @task.Definition
|
769
757
|
definition.Triggers.Clear()
|
770
758
|
|
771
|
-
startTime = "%04d-%02d-%02dT%02d:%02d:00"
|
772
|
-
trigger[:start_year], trigger[:start_month],
|
773
|
-
trigger[:start_day], trigger[:start_hour], trigger[:start_minute]
|
774
|
-
]
|
759
|
+
startTime = format("%04d-%02d-%02dT%02d:%02d:00", trigger[:start_year], trigger[:start_month], trigger[:start_day], trigger[:start_hour], trigger[:start_minute])
|
775
760
|
|
776
|
-
endTime = "%04d-%02d-%02dT00:00:00"
|
777
|
-
trigger[:end_year], trigger[:end_month], trigger[:end_day]
|
778
|
-
]
|
761
|
+
endTime = format("%04d-%02d-%02dT00:00:00", trigger[:end_year], trigger[:end_month], trigger[:end_day])
|
779
762
|
|
780
|
-
trig = definition.Triggers.Create(
|
763
|
+
trig = definition.Triggers.Create(trigger[:trigger_type].to_i)
|
781
764
|
trig.Id = "RegistrationTriggerId#{definition.Triggers.Count}"
|
782
|
-
trig.StartBoundary = startTime if startTime !=
|
783
|
-
trig.EndBoundary = endTime if endTime !=
|
765
|
+
trig.StartBoundary = startTime if startTime != "0000-00-00T00:00:00"
|
766
|
+
trig.EndBoundary = endTime if endTime != "0000-00-00T00:00:00"
|
784
767
|
trig.Enabled = true
|
785
768
|
|
786
769
|
repetitionPattern = trig.Repetition
|
787
770
|
|
788
771
|
if trigger[:minutes_duration].to_i > 0
|
789
|
-
repetitionPattern.Duration = "PT#{trigger[:minutes_duration]||0}M"
|
772
|
+
repetitionPattern.Duration = "PT#{trigger[:minutes_duration] || 0}M"
|
790
773
|
end
|
791
774
|
|
792
775
|
if trigger[:minutes_interval].to_i > 0
|
793
|
-
repetitionPattern.Interval
|
776
|
+
repetitionPattern.Interval = "PT#{trigger[:minutes_interval] || 0}M"
|
794
777
|
end
|
795
778
|
|
796
779
|
tmp = trigger[:type]
|
797
780
|
tmp = nil unless tmp.is_a?(Hash)
|
798
781
|
|
799
782
|
case trigger[:trigger_type]
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
783
|
+
when TASK_TIME_TRIGGER_DAILY
|
784
|
+
trig.DaysInterval = tmp[:days_interval] if tmp && tmp[:days_interval]
|
785
|
+
if trigger[:random_minutes_interval].to_i > 0
|
786
|
+
trig.RandomDelay = "PT#{trigger[:random_minutes_interval]}M"
|
787
|
+
end
|
788
|
+
when TASK_TIME_TRIGGER_WEEKLY
|
789
|
+
trig.DaysOfWeek = tmp[:days_of_week] if tmp && tmp[:days_of_week]
|
790
|
+
trig.WeeksInterval = tmp[:weeks_interval] if tmp && tmp[:weeks_interval]
|
791
|
+
if trigger[:random_minutes_interval].to_i > 0
|
792
|
+
trig.RandomDelay = "PT#{trigger[:random_minutes_interval] || 0}M"
|
793
|
+
end
|
794
|
+
when TASK_TIME_TRIGGER_MONTHLYDATE
|
795
|
+
trig.MonthsOfYear = tmp[:months] if tmp && tmp[:months]
|
796
|
+
trig.DaysOfMonth = tmp[:days] if tmp && tmp[:days]
|
797
|
+
if trigger[:random_minutes_interval].to_i > 0
|
798
|
+
trig.RandomDelay = "PT#{trigger[:random_minutes_interval] || 0}M"
|
799
|
+
end
|
800
|
+
trig.RunOnLastDayOfMonth = trigger[:run_on_last_day_of_month] if trigger[:run_on_last_day_of_month]
|
801
|
+
when TASK_TIME_TRIGGER_MONTHLYDOW
|
802
|
+
trig.MonthsOfYear = tmp[:months] if tmp && tmp[:months]
|
803
|
+
trig.DaysOfWeek = tmp[:days_of_week] if tmp && tmp[:days_of_week]
|
804
|
+
trig.WeeksOfMonth = tmp[:weeks_of_month] if tmp && tmp[:weeks_of_month]
|
805
|
+
if trigger[:random_minutes_interval].to_i > 0
|
806
|
+
trig.RandomDelay = "PT#{trigger[:random_minutes_interval] || 0}M"
|
807
|
+
end
|
808
|
+
trig.RunOnLastWeekOfMonth = trigger[:run_on_last_week_of_month] if trigger[:run_on_last_week_of_month]
|
809
|
+
when TASK_TIME_TRIGGER_ONCE
|
810
|
+
if trigger[:random_minutes_interval].to_i > 0
|
811
|
+
trig.RandomDelay = "PT#{trigger[:random_minutes_interval] || 0}M"
|
812
|
+
end
|
813
|
+
when TASK_EVENT_TRIGGER_AT_SYSTEMSTART
|
814
|
+
trig.Delay = "PT#{trigger[:delay_duration] || 0}M"
|
815
|
+
when TASK_EVENT_TRIGGER_AT_LOGON
|
816
|
+
trig.UserId = trigger[:user_id] if trigger[:user_id]
|
817
|
+
trig.Delay = "PT#{trigger[:delay_duration] || 0}M"
|
818
|
+
when TASK_EVENT_TRIGGER_ON_IDLE
|
819
|
+
# for setting execution time limit Ref : https://msdn.microsoft.com/en-us/library/windows/desktop/aa380724(v=vs.85).aspx
|
820
|
+
if trigger[:execution_time_limit].to_i > 0
|
821
|
+
trig.ExecutionTimeLimit = "PT#{trigger[:execution_time_limit] || 0}M"
|
822
|
+
end
|
840
823
|
end
|
841
824
|
|
842
825
|
register_task_definition(definition)
|
@@ -849,81 +832,76 @@ module Win32
|
|
849
832
|
def add_trigger(index, trigger)
|
850
833
|
raise TypeError unless index.is_a?(Numeric)
|
851
834
|
raise TypeError unless trigger.is_a?(Hash)
|
852
|
-
raise ArgumentError,
|
835
|
+
raise ArgumentError, "Unknown trigger type" unless valid_trigger_option(trigger[:trigger_type])
|
853
836
|
|
854
837
|
check_for_active_task
|
855
838
|
|
856
839
|
definition = @task.Definition
|
857
840
|
|
858
|
-
startTime = "%04d-%02d-%02dT%02d:%02d:00"
|
859
|
-
trigger[:start_year], trigger[:start_month], trigger[:start_day],
|
860
|
-
trigger[:start_hour], trigger[:start_minute]
|
861
|
-
]
|
841
|
+
startTime = format("%04d-%02d-%02dT%02d:%02d:00", trigger[:start_year], trigger[:start_month], trigger[:start_day], trigger[:start_hour], trigger[:start_minute])
|
862
842
|
|
863
843
|
# Set defaults
|
864
844
|
trigger[:end_year] ||= 0
|
865
845
|
trigger[:end_month] ||= 0
|
866
846
|
trigger[:end_day] ||= 0
|
867
847
|
|
868
|
-
endTime = "%04d-%02d-%02dT00:00:00"
|
869
|
-
trigger[:end_year], trigger[:end_month], trigger[:end_day]
|
870
|
-
]
|
848
|
+
endTime = format("%04d-%02d-%02dT00:00:00", trigger[:end_year], trigger[:end_month], trigger[:end_day])
|
871
849
|
|
872
|
-
trig = definition.Triggers.Create(
|
850
|
+
trig = definition.Triggers.Create(trigger[:trigger_type].to_i)
|
873
851
|
trig.Id = "RegistrationTriggerId#{definition.Triggers.Count}"
|
874
|
-
trig.StartBoundary = startTime if startTime !=
|
875
|
-
trig.EndBoundary = endTime if endTime !=
|
852
|
+
trig.StartBoundary = startTime if startTime != "0000-00-00T00:00:00"
|
853
|
+
trig.EndBoundary = endTime if endTime != "0000-00-00T00:00:00"
|
876
854
|
trig.Enabled = true
|
877
855
|
|
878
856
|
repetitionPattern = trig.Repetition
|
879
857
|
|
880
858
|
if trigger[:minutes_duration].to_i > 0
|
881
|
-
repetitionPattern.Duration = "PT#{trigger[:minutes_duration]||0}M"
|
859
|
+
repetitionPattern.Duration = "PT#{trigger[:minutes_duration] || 0}M"
|
882
860
|
end
|
883
861
|
|
884
862
|
if trigger[:minutes_interval].to_i > 0
|
885
|
-
repetitionPattern.Interval
|
863
|
+
repetitionPattern.Interval = "PT#{trigger[:minutes_interval] || 0}M"
|
886
864
|
end
|
887
865
|
|
888
866
|
tmp = trigger[:type]
|
889
867
|
tmp = nil unless tmp.is_a?(Hash)
|
890
868
|
|
891
869
|
case trigger[:trigger_type]
|
892
|
-
|
893
|
-
|
894
|
-
|
870
|
+
when TASK_TIME_TRIGGER_DAILY
|
871
|
+
trig.DaysInterval = tmp[:days_interval] if tmp && tmp[:days_interval]
|
872
|
+
if trigger[:random_minutes_interval].to_i > 0
|
895
873
|
trig.RandomDelay = "PT#{trigger[:random_minutes_interval]}M"
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
trig.RandomDelay = "PT#{trigger[:random_minutes_interval]||0}M"
|
902
|
-
|
903
|
-
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
trig.RandomDelay = "PT#{trigger[:random_minutes_interval]||0}M"
|
916
|
-
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
trig.RandomDelay = "PT#{trigger[:random_minutes_interval]||0}M"
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
925
|
-
|
926
|
-
|
874
|
+
end
|
875
|
+
when TASK_TIME_TRIGGER_WEEKLY
|
876
|
+
trig.DaysOfWeek = tmp[:days_of_week] if tmp && tmp[:days_of_week]
|
877
|
+
trig.WeeksInterval = tmp[:weeks_interval] if tmp && tmp[:weeks_interval]
|
878
|
+
if trigger[:random_minutes_interval].to_i > 0
|
879
|
+
trig.RandomDelay = "PT#{trigger[:random_minutes_interval] || 0}M"
|
880
|
+
end
|
881
|
+
when TASK_TIME_TRIGGER_MONTHLYDATE
|
882
|
+
trig.MonthsOfYear = tmp[:months] if tmp && tmp[:months]
|
883
|
+
trig.DaysOfMonth = tmp[:days] if tmp && tmp[:days]
|
884
|
+
if trigger[:random_minutes_interval].to_i > 0
|
885
|
+
trig.RandomDelay = "PT#{trigger[:random_minutes_interval] || 0}M"
|
886
|
+
end
|
887
|
+
trig.RunOnLastDayOfMonth = trigger[:run_on_last_day_of_month] if trigger[:run_on_last_day_of_month]
|
888
|
+
when TASK_TIME_TRIGGER_MONTHLYDOW
|
889
|
+
trig.MonthsOfYear = tmp[:months] if tmp && tmp[:months]
|
890
|
+
trig.DaysOfWeek = tmp[:days_of_week] if tmp && tmp[:days_of_week]
|
891
|
+
trig.WeeksOfMonth = tmp[:weeks_of_month] if tmp && tmp[:weeks_of_month]
|
892
|
+
if trigger[:random_minutes_interval].to_i > 0
|
893
|
+
trig.RandomDelay = "PT#{trigger[:random_minutes_interval] || 0}M"
|
894
|
+
end
|
895
|
+
trig.RunOnLastWeekOfMonth = trigger[:run_on_last_week_of_month] if trigger[:run_on_last_week_of_month]
|
896
|
+
when TASK_TIME_TRIGGER_ONCE
|
897
|
+
if trigger[:random_minutes_interval].to_i > 0
|
898
|
+
trig.RandomDelay = "PT#{trigger[:random_minutes_interval] || 0}M"
|
899
|
+
end
|
900
|
+
when TASK_EVENT_TRIGGER_AT_SYSTEMSTART
|
901
|
+
trig.Delay = "PT#{trigger[:delay_duration] || 0}M"
|
902
|
+
when TASK_EVENT_TRIGGER_AT_LOGON
|
903
|
+
trig.UserId = trigger[:user_id] if trigger[:user_id]
|
904
|
+
trig.Delay = "PT#{trigger[:delay_duration] || 0}M"
|
927
905
|
end
|
928
906
|
|
929
907
|
register_task_definition(definition)
|
@@ -937,18 +915,18 @@ module Win32
|
|
937
915
|
def status
|
938
916
|
check_for_active_task
|
939
917
|
|
940
|
-
case @task.State
|
941
|
-
|
942
|
-
|
943
|
-
|
944
|
-
|
945
|
-
|
946
|
-
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
|
918
|
+
status = case @task.State
|
919
|
+
when 3
|
920
|
+
"ready"
|
921
|
+
when 4
|
922
|
+
"running"
|
923
|
+
when 2
|
924
|
+
"queued"
|
925
|
+
when 1
|
926
|
+
"not scheduled"
|
927
|
+
else
|
928
|
+
"unknown"
|
929
|
+
end
|
952
930
|
|
953
931
|
status
|
954
932
|
end
|
@@ -1031,7 +1009,7 @@ module Win32
|
|
1031
1009
|
|
1032
1010
|
begin
|
1033
1011
|
time = Time.parse(@task.LastRunTime)
|
1034
|
-
rescue
|
1012
|
+
rescue StandardError
|
1035
1013
|
# Ignore
|
1036
1014
|
end
|
1037
1015
|
|
@@ -1083,7 +1061,7 @@ module Win32
|
|
1083
1061
|
|
1084
1062
|
t = max_run_time
|
1085
1063
|
t /= 1000
|
1086
|
-
limit ="PT#{t}S"
|
1064
|
+
limit = "PT#{t}S"
|
1087
1065
|
|
1088
1066
|
definition = @task.Definition
|
1089
1067
|
definition.Settings.ExecutionTimeLimit = limit
|
@@ -1096,7 +1074,7 @@ module Win32
|
|
1096
1074
|
#
|
1097
1075
|
# @see https://docs.microsoft.com/en-us/windows/desktop/TaskSchd/idlesettings#properties
|
1098
1076
|
#
|
1099
|
-
IdleSettings = %i
|
1077
|
+
IdleSettings = %i{idle_duration restart_on_idle stop_on_idle_end wait_timeout}.freeze
|
1100
1078
|
|
1101
1079
|
# Configures tasks settings
|
1102
1080
|
#
|
@@ -1145,7 +1123,7 @@ module Win32
|
|
1145
1123
|
|
1146
1124
|
# Conversion of few settings
|
1147
1125
|
hash[:execution_time_limit] = hash[:max_run_time] unless hash[:max_run_time].nil?
|
1148
|
-
%i
|
1126
|
+
%i{execution_time_limit idle_duration restart_interval wait_timeout}.each do |setting|
|
1149
1127
|
hash[setting] = "PT#{hash[setting]}M" unless hash[setting].nil?
|
1150
1128
|
end
|
1151
1129
|
|
@@ -1155,16 +1133,15 @@ module Win32
|
|
1155
1133
|
if IdleSettings.any? { |setting| hash.key?(setting) }
|
1156
1134
|
idle_settings = task_settings.IdleSettings
|
1157
1135
|
IdleSettings.each do |setting|
|
1158
|
-
|
1159
|
-
|
1160
|
-
|
1161
|
-
|
1162
|
-
end
|
1136
|
+
next if hash[setting].nil?
|
1137
|
+
idle_settings.setproperty(camelize(setting.to_s), hash[setting])
|
1138
|
+
# This setting is not required to be configured now
|
1139
|
+
hash.delete(setting)
|
1163
1140
|
end
|
1164
1141
|
end
|
1165
1142
|
|
1166
1143
|
# XML settings are not to be configured
|
1167
|
-
%i
|
1144
|
+
%i{xml_text xml}.map { |x| hash.delete(x) }
|
1168
1145
|
|
1169
1146
|
hash.each do |setting, value|
|
1170
1147
|
setting = camelize(setting.to_s)
|
@@ -1313,7 +1290,7 @@ module Win32
|
|
1313
1290
|
# @return [String] In camel case format
|
1314
1291
|
#
|
1315
1292
|
def camelize(str)
|
1316
|
-
str.split(
|
1293
|
+
str.split("_").map(&:capitalize).join
|
1317
1294
|
end
|
1318
1295
|
|
1319
1296
|
# Converts all the keys of a hash to underscored-symbol format
|
@@ -1324,15 +1301,15 @@ module Win32
|
|
1324
1301
|
end
|
1325
1302
|
|
1326
1303
|
def valid_trigger_option(trigger_type)
|
1327
|
-
[
|
1328
|
-
|
1329
|
-
|
1304
|
+
[TASK_TIME_TRIGGER_ONCE, TASK_TIME_TRIGGER_DAILY, TASK_TIME_TRIGGER_WEEKLY,
|
1305
|
+
TASK_TIME_TRIGGER_MONTHLYDATE, TASK_TIME_TRIGGER_MONTHLYDOW, TASK_EVENT_TRIGGER_ON_IDLE,
|
1306
|
+
TASK_EVENT_TRIGGER_AT_SYSTEMSTART, TASK_EVENT_TRIGGER_AT_LOGON].include?(trigger_type.to_i)
|
1330
1307
|
end
|
1331
1308
|
|
1332
1309
|
def validate_trigger(hash)
|
1333
|
-
|
1310
|
+
%i{start_year start_month start_day}.each do |key|
|
1334
1311
|
raise ArgumentError, "#{key} must be set" unless hash[key]
|
1335
|
-
|
1312
|
+
end
|
1336
1313
|
end
|
1337
1314
|
|
1338
1315
|
# Configurable settings options
|
@@ -1345,17 +1322,17 @@ module Win32
|
|
1345
1322
|
# @return [Array]
|
1346
1323
|
#
|
1347
1324
|
def valid_settings_options
|
1348
|
-
%i
|
1325
|
+
%i{allow_demand_start allow_hard_terminate compatibility delete_expired_task_after
|
1349
1326
|
disallow_start_if_on_batteries disallow_start_on_remote_app_session enabled
|
1350
1327
|
execution_time_limit hidden idle_duration maintenance_settings max_run_time
|
1351
1328
|
multiple_instances network_settings priority restart_count restart_interval
|
1352
1329
|
restart_on_idle run_only_if_idle run_only_if_network_available
|
1353
1330
|
start_when_available stop_if_going_on_batteries stop_on_idle_end
|
1354
|
-
use_unified_scheduling_engine volatile wait_timeout wake_to_run xml xml_text
|
1331
|
+
use_unified_scheduling_engine volatile wait_timeout wake_to_run xml xml_text}
|
1355
1332
|
end
|
1356
1333
|
|
1357
1334
|
def check_for_active_task
|
1358
|
-
raise Error,
|
1335
|
+
raise Error, "No currently active task" if @task.nil?
|
1359
1336
|
end
|
1360
1337
|
|
1361
1338
|
# Checks if the user belongs to service accounts category
|
@@ -1382,11 +1359,8 @@ module Win32
|
|
1382
1359
|
SYSTEM_USERS.include?(user.to_s.upcase)
|
1383
1360
|
end
|
1384
1361
|
|
1385
|
-
#
|
1386
|
-
#
|
1387
|
-
# Raises the error in case of any failures
|
1388
|
-
#
|
1389
|
-
# Password should be nil for System Users. For other users, it is required.
|
1362
|
+
# System users will not require a password
|
1363
|
+
# Other users will require a password if the task is non-interactive.
|
1390
1364
|
#
|
1391
1365
|
# @param [String] user_id
|
1392
1366
|
# @param [String] password
|
@@ -1394,14 +1368,14 @@ module Win32
|
|
1394
1368
|
def check_credential_requirements(user_id, password)
|
1395
1369
|
user_id = user_id.to_s
|
1396
1370
|
password = password.to_s
|
1397
|
-
|
1371
|
+
|
1398
1372
|
if password.empty?
|
1399
|
-
unless system_user?(user_id)
|
1400
|
-
raise
|
1373
|
+
unless system_user?(user_id) || @interactive
|
1374
|
+
raise ArgumentError, "Password is required for non-system users"
|
1401
1375
|
end
|
1402
1376
|
else
|
1403
1377
|
if system_user?(user_id)
|
1404
|
-
raise
|
1378
|
+
raise ArgumentError, "Password is not required for system users"
|
1405
1379
|
end
|
1406
1380
|
end
|
1407
1381
|
end
|