win32-taskscheduler 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b74ccd6aa98c21f9e0a7bdd20c24e09f7e461450
4
- data.tar.gz: a0742bc2c56d80f282a1e5cd37fb1b809e0c3e70
3
+ metadata.gz: '08691b264f7dbe39c37043d65f3765f5949304c3'
4
+ data.tar.gz: 5247b4be4cf39cefcecb19c795e0dc158bf44ba1
5
5
  SHA512:
6
- metadata.gz: eaa9bc605ad45fd60797cf46fb9d4083054ead60552c92e10546e4f2e83247cbf0b6c063c9716e7f729271b4b0f7410fc52cdb349e72b281efea287d5252d8fb
7
- data.tar.gz: f338910febc7774ce538465684f39e4b6480eb5f5b78d769b56a2c89eb9a02e41d31ead7bba871c1138b09e138c929416dff779d29a2a005b9e3c3f7d589596e
6
+ metadata.gz: 9394becf37fc16d9fcff57728826f90388c94455f7fd082a5a86ccc87b04d319bf4835266d5119ff508daeed708abee096d49ee07e8ed69ea3e549830d8bf383
7
+ data.tar.gz: c59df6ee9dc73f263744e0464fdf1031277f66d85601b009995b913fcbb9cdcff10cc6fb41cf78b95ab8d2415b4483716c805b09438a4cd6ae567667355730c0
@@ -0,0 +1,122 @@
1
+ ## [v0.4.0](https://github.com/chef/win32-taskscheduler/tree/win32-taskscheduler-0.4.0) (5-Apr-2018)
2
+ - Updated code to create task without trigger. [#25](https://github.com/chef/win32-taskscheduler/pull/25) ([#Vasu1105](https://github.com/Vasu1105))
3
+ - Fix for execution time limit and weeks of month. [#23](https://github.com/chef/win32-taskscheduler/pull/23) ([#Vasu1105](https://github.com/Vasu1105))
4
+ - Added methods to get and set principal information of the task. [#22](https://github.com/chef/win32-taskscheduler/pull/22) ([#Nimesh-Msys](https://github.com/Nimesh-Msys))
5
+ - Added methods to retrieve settings(all/Idle/Network) of current task. [#21](https://github.com/chef/win32-taskscheduler/pull/21) ([#Nimesh-Msys](https://github.com/Nimesh-Msys))
6
+ - Refactored constants, moved predefined MSDN constns to another file. [#20](https://github.com/chef/win32-taskscheduler/pull/20) ([#Nimesh-Msys](https://github.com/Nimesh-Msys))
7
+ - Added code to handle on idle trigger and on idle settings. [#19](https://github.com/chef/win32-taskscheduler/pull/19) ([#Vasu1105](https://github.com/Vasu1105))
8
+ - Fix for trigger at_logon and at_system_start. [#18](https://github.com/chef/win32-taskscheduler/pull/18) ([#Nimesh-Msys](https://github.com/Nimesh-Msys))
9
+ - Added get_task and enabled? method. [#17](https://github.com/chef/win32-taskscheduler/pull/17) ([#Vasu1105](https://github.com/Vasu1105))
10
+ - Fix for undefined method 'weeks' error while updating week_of_month[#16](https://github.com/chef/win32-taskscheduler/pull/16) ([#Vasu1105](https://github.com/Vasu1105))
11
+ - Fix for handling days of month for trigger_type MONTHLYDATE. [#15](https://github.com/chef/win32-taskscheduler/pull/15)([#Vasu1105](https://github.com/Vasu1105))
12
+ - Fix for setting system user for scheduled task. [#14](https://github.com/chef/win32-taskscheduler/pull/14) ([#Vasu1105](https://github.com/Vasu1105))
13
+ - Fix for Wrong value is set for end_day, end_year, end_month it should be EndBoundary and not StartBoundary. [#13](https://github.com/chef/win32-taskscheduler/pull/13)([#Vasu1105](https://github.com/Vasu1105))
14
+
15
+ ## [v0.3.2](https://github.com/chef/win32-taskscheduler/tree/win32-taskscheduler-0.3.2) (18-Mar-2017)
16
+ - Use the block form for FFI::MemoryPointer in the error message helper
17
+ function. Thanks go to Ethan Brown for the suggestion.
18
+ - Fixed a potential bug in the helper module, which was also renamed to
19
+ help prevent any name collisions.
20
+ - Added the win32-taskscheduler.rb file for convenience.
21
+ - Added the configure_settings method.
22
+ - Added the configure_registration_info method.
23
+ - Added the description and description= aliases for comments.
24
+ - Added the author and author= aliases for creator.
25
+ - Some internal cleanup, moving common code to private methods.
26
+ - Rakefile now assumes Rubygems 2.0 or later for tasks.
27
+ - Gemspec cleanup, updated home page, removed old rubyforge_project reference.
28
+ - This gem is now signed.
29
+
30
+ ## [v0.3.1](https://github.com/chef/win32-taskscheduler/tree/win32-taskscheduler-0.3.1) (6-Jul-2014)
31
+ - Added FFI as a dependency. Thanks go to Maxime Lapointe for the spot.
32
+ - Some updates to the win_error helper method. Thanks go to Ethan J. Brown
33
+ for the suggestions.
34
+
35
+ ## [v0.3.0](https://github.com/chef/win32-taskscheduler/tree/win32-taskscheduler-0.3.0) (15-Jan-2014)
36
+ - Rewritten to use Win32OLE instead of using wrapping the C API. Benefits
37
+ include working on Windows Vista or later, and working with JRuby.
38
+ - Modified the constructor to accept 3rd and 4th arguments. These indicate
39
+ which folder to use, and whether or not to create it if it doesn't exist.
40
+ - The TaskScheduler#save method is now no longer necessary. It is retained
41
+ for backwards compatibility, but will raise a deprecation warning. In this
42
+ version simply calling TaskScheduler#activate will implement the task.
43
+ - Added support for the AT_SYSTEMSTART, AT_LOGON and ON_IDLE trigger types.
44
+ - Now requires the structured_warnings gem.
45
+ - Removed the doc directory and separate documentation file. Everything is
46
+ inlined now. There's still an example under the "examples" directory, too.
47
+ - Added test-unit, rake, and win32-security as development dependencies.
48
+ These are needed for testing only.
49
+
50
+ ## [v0.2.2](https://github.com/chef/win32-taskscheduler/tree/win32-taskscheduler-0.2.2)(29-Feb-2012)
51
+ - Moved some include statements inside the TaskScheduler class to avoid
52
+ polluting Object. Thanks go to Josh Cooper for the spot and patch.
53
+ - Minor formatting tweaks to silence 1.9 warnings.
54
+
55
+ ## [v0.2.1](https://github.com/chef/win32-taskscheduler/tree/win32-taskscheduler-0.2.1) (8-Oct-2011)
56
+ - Fixed a bug that would not allow task to run as SYSTEM. Thanks go to
57
+ Josh cooper for the spot and patch.
58
+ - Fixed a bug in new_work_item that would cause it to crash if you tried
59
+ to create a work item that already existed. An error is now raised instead.
60
+ Thanks go to Pete Higgins for the spot.
61
+ - The set_trigger and trigger= methods now internally transform and validate
62
+ the trigger hash in the same manner as new_work_item. Thanks again go to
63
+ Pete Higgins.
64
+ - Cleaned up the repo. The C source files have been removed from the main
65
+ repository (and this gem). They are in a separate branch on github for
66
+ anyone who misses them.
67
+ - Refactored the Rakefile, removing tasks related to the old C source files,
68
+ and added tasks for cleaning, building and installing a gem.
69
+ - Updated the README file, eliminating references to anything that was only
70
+ related to the older C version.
71
+
72
+ ## [v0.2.0](https://github.com/chef/win32-taskscheduler/tree/win32-taskscheduler-0.2.0)(19-Jun-2009)
73
+ - Rewritten in pure Ruby!
74
+ - The TaskScheduler::ONCE constant is now a valid trigger type. Thanks go to
75
+ Uri Iurgel for the spot and patch.
76
+ - Added the TaskScheduler#exists? method.
77
+ - Added the TaskScheduler#tasks alias for the TaskScheduler#enum method.
78
+ - The TaskScheduler#new_work_item method now accepts symbols as well as
79
+ strings for hash keys, and ignores case. Also, the keys are now validated.
80
+ - Renamed the example file and test file.
81
+ - Added the 'example' Rake task.
82
+ - Fixed some code in the README synopsis that was incorrect.
83
+
84
+ ## [v0.1.0](11-May-2008)
85
+ - The TaskScheduler#save instance method now accepts an optional file name.
86
+ - Most of the TaskScheduler setter methods now return the value specified
87
+ instead of true.
88
+ - Removed the RUN_ONLY_IF_DOCKED and RUN_IF_CONNECTED_TO_INTERNET constants.
89
+ The MSDN docs say that they are unused.
90
+ - Added more documentation. Much more rdoc friendly now.
91
+ - Added many more tests.
92
+ - Better type handling for bad arguments.
93
+ - Added a Rakefile with tasks for building, installation and testing.
94
+ - Added a gemspec.
95
+ - Inlined the rdoc documentation.
96
+ - Internal project reorganization and code cleanup.
97
+
98
+ ## [v0.0.3](1-Mar-2005)
99
+ - Bug fix for the bitFieldToHumanDays() internal function.
100
+ - Moved the 'examples' directory to the toplevel directory.
101
+ - Made the CHANGES and README files rdoc friendly.
102
+ - Minor updates to taskscheduler.h.
103
+
104
+ ## [v0.0.2](04-Aug-2004)
105
+ - Now uses the newer allocation framework and replaced all instances of the
106
+ deprecated STR2CSTR() function with StringValuePtr(). This means that, as
107
+ of this release, Ruby 1.8.0 or later is required.
108
+ - Modified the constructor to accept arguments. This is just some sugar for
109
+ creating a new task item in one call instead of two.
110
+ - The argument to trigger= now must be a hash. The same goes for the 'type'
111
+ sub-hash.
112
+ - Added the add_trigger() method. Actually, the C code for this method was
113
+ already in place, I simply forgot to create a corresponding Ruby method
114
+ for it.
115
+ - Removed the create_trigger() method. This was really nothing more than an
116
+ alias for trigger=(). I got confused somehow.
117
+ - Test suite modified and many more tests added.
118
+ - Documentation updates, including docs for a couple of methods that I had
119
+ accidentally omitted previously.
120
+
121
+ ## [v0.0.1](24-Apr-2004)
122
+ - Initial release
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
data/README CHANGED
@@ -58,10 +58,11 @@
58
58
 
59
59
  Please submit any bug reports to the project page at:
60
60
 
61
- http://github.com/djberg96/win32-taskscheduler
61
+ http://github.com/chef/win32-taskscheduler
62
62
 
63
63
  = Copyright
64
64
  (C) 2003-2017 Daniel J. Berger
65
+ (C) 2018 Chef Software, Inc.
65
66
  All Rights Reserved
66
67
 
67
68
  = License
@@ -0,0 +1,36 @@
1
+ <!---
2
+ This file is reset every time a new release is done. The contents of this file are for the currently unreleased version.
3
+
4
+ Example Note:
5
+
6
+ ## Example Heading
7
+ Details about the thing that changed that needs to get included in the Release Notes in markdown.
8
+ -->
9
+
10
+ # win32-taskscheduler 0.4.0 release notes:
11
+ In this release we have fixed some issues and added following methods.
12
+
13
+ `get_task`
14
+ Returns current active task with given name.
15
+
16
+ `configure_principals`
17
+ Sets the principals for current active task. The principal is hash with following possible options.
18
+ Expected principal hash: { id: STRING, display_name: STRING, user_id: STRING, logon_type: INTEGER, group_id: STRING, run_level: INTEGER }
19
+
20
+ 'principals'
21
+ Returns a hash containing all the principal information of the current task.
22
+
23
+ `execution_time_limit`
24
+ Returns execution time limit for current active task.
25
+
26
+ `settings`
27
+ Returns a hash containing all settings of the current task.
28
+
29
+ `idle_settings`
30
+ Returns a hash of idle settings of the current task.
31
+
32
+ `network_settings`
33
+ Returns a hash of network settings of the current task.
34
+
35
+ 'enabled?'
36
+ Returns true if current task is enabled
data/Rakefile CHANGED
@@ -9,7 +9,6 @@ namespace 'gem' do
9
9
  task :create => [:clean] do
10
10
  require 'rubygems/package'
11
11
  spec = eval(IO.read('win32-taskscheduler.gemspec'))
12
- spec.signing_key = File.join(Dir.home, '.ssh', 'gem-private_key.pem')
13
12
  Gem::Package.build(spec, true)
14
13
  end
15
14
 
@@ -1,21 +1,21 @@
1
- -----BEGIN CERTIFICATE-----
2
- MIIDcDCCAligAwIBAgIBATANBgkqhkiG9w0BAQUFADA/MREwDwYDVQQDDAhkamJl
3
- cmc5NjEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPyLGQBGRYDY29t
4
- MB4XDTE2MTIxMjAwMTQ1M1oXDTE3MTIxMjAwMTQ1M1owPzERMA8GA1UEAwwIZGpi
5
- ZXJnOTYxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixkARkWA2Nv
6
- bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMVtTm/wETO8yKVKRPBO
7
- VgPRvE94iEfKryOb/tQrmhGhchG2ALqdw/r54cGJvLaXeItrYJ6N8pSE/FSnN5jM
8
- xugUhHBprPl+AsQ4E+IBy0dKwyU8XjFoVYzWvT1wnqwQdSazdgFCfQqb51QCgUIT
9
- PGGakKlyzCb3Mbq30is8+QlRrqXt/JbpkUZbQwUqCdAulMT4oyPBk/L+48pbVX0s
10
- 4yj7YaVAqfGByAMTPXEmUS388lX+0xq8+GGir2Fuh0TpNW0ggr9BxprwqL0Mg4Oo
11
- YhM5L1y8Plolo8mOTN3+K8I3afZ0lD0BtwniVb6g+Ut/4aBjKy2+GyFwwNOu0gSj
12
- desCAwEAAaN3MHUwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFJfg
13
- HmQ0uDU3Z9A9hB1lQMjr5VZSMB0GA1UdEQQWMBSBEmRqYmVyZzk2QGdtYWlsLmNv
14
- bTAdBgNVHRIEFjAUgRJkamJlcmc5NkBnbWFpbC5jb20wDQYJKoZIhvcNAQEFBQAD
15
- ggEBACjRCHRP944MHIQJNCglZbDnZowybV2HxmG1uhnvRwrOjBA7CXemc+QSAL7K
16
- 7eXC4FdojVEJrnU7ZxuCmfQU+fvkEQKOnah1osG1874aPiDlwtjHclpeqcDgTUI7
17
- A7CF+OXK8x7ksFx205ruhPHKaPYtwVG/W/J+y7Wx8yl9rvwUgRBL5cVzTBiEz+AB
18
- NRT7yoHXXfFXjuQWN1eHunSbNds2ZTGQd64yBCujb17Xdl+F9tu4klkTga3gxP3P
19
- y3zoX1VttxnIZBojRM/s2A7c2aubMH2SVbXMR3ccVkB9XbYKl1OvCe7q85xEHit2
20
- Kbpico5nnyHqf7YSPmvZe8bCU94=
21
- -----END CERTIFICATE-----
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDcDCCAligAwIBAgIBATANBgkqhkiG9w0BAQUFADA/MREwDwYDVQQDDAhkamJl
3
+ cmc5NjEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPyLGQBGRYDY29t
4
+ MB4XDTE2MTIxMjAwMTQ1M1oXDTE3MTIxMjAwMTQ1M1owPzERMA8GA1UEAwwIZGpi
5
+ ZXJnOTYxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixkARkWA2Nv
6
+ bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMVtTm/wETO8yKVKRPBO
7
+ VgPRvE94iEfKryOb/tQrmhGhchG2ALqdw/r54cGJvLaXeItrYJ6N8pSE/FSnN5jM
8
+ xugUhHBprPl+AsQ4E+IBy0dKwyU8XjFoVYzWvT1wnqwQdSazdgFCfQqb51QCgUIT
9
+ PGGakKlyzCb3Mbq30is8+QlRrqXt/JbpkUZbQwUqCdAulMT4oyPBk/L+48pbVX0s
10
+ 4yj7YaVAqfGByAMTPXEmUS388lX+0xq8+GGir2Fuh0TpNW0ggr9BxprwqL0Mg4Oo
11
+ YhM5L1y8Plolo8mOTN3+K8I3afZ0lD0BtwniVb6g+Ut/4aBjKy2+GyFwwNOu0gSj
12
+ desCAwEAAaN3MHUwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFJfg
13
+ HmQ0uDU3Z9A9hB1lQMjr5VZSMB0GA1UdEQQWMBSBEmRqYmVyZzk2QGdtYWlsLmNv
14
+ bTAdBgNVHRIEFjAUgRJkamJlcmc5NkBnbWFpbC5jb20wDQYJKoZIhvcNAQEFBQAD
15
+ ggEBACjRCHRP944MHIQJNCglZbDnZowybV2HxmG1uhnvRwrOjBA7CXemc+QSAL7K
16
+ 7eXC4FdojVEJrnU7ZxuCmfQU+fvkEQKOnah1osG1874aPiDlwtjHclpeqcDgTUI7
17
+ A7CF+OXK8x7ksFx205ruhPHKaPYtwVG/W/J+y7Wx8yl9rvwUgRBL5cVzTBiEz+AB
18
+ NRT7yoHXXfFXjuQWN1eHunSbNds2ZTGQd64yBCujb17Xdl+F9tu4klkTga3gxP3P
19
+ y3zoX1VttxnIZBojRM/s2A7c2aubMH2SVbXMR3ccVkB9XbYKl1OvCe7q85xEHit2
20
+ Kbpico5nnyHqf7YSPmvZe8bCU94=
21
+ -----END CERTIFICATE-----
@@ -1,4 +1,6 @@
1
1
  require_relative 'windows/helper'
2
+ require_relative 'windows/time_calc_helper'
3
+ require_relative 'windows/constants'
2
4
  require 'win32ole'
3
5
  require 'socket'
4
6
  require 'time'
@@ -10,215 +12,111 @@ module Win32
10
12
  # The TaskScheduler class encapsulates a Windows scheduled task
11
13
  class TaskScheduler
12
14
  include Windows::TaskSchedulerHelper
15
+ include Windows::TimeCalcHelper
16
+ include Windows::TaskSchedulerConstants
13
17
 
14
18
  # The version of the win32-taskscheduler library
15
- VERSION = '0.3.2'.freeze
19
+ VERSION = '0.4.0'.freeze
16
20
 
17
21
  # The Error class is typically raised if any TaskScheduler methods fail.
18
22
  class Error < StandardError; end
19
23
 
20
- # Triggers
21
-
22
- # Trigger is set to run the task a single tim
23
- TASK_TIME_TRIGGER_ONCE = 0
24
-
25
- # Trigger is set to run the task on a daily interval
26
- TASK_TIME_TRIGGER_DAILY = 1
27
-
28
- # Trigger is set to run the task on specific days of a specific week & month
29
- TASK_TIME_TRIGGER_WEEKLY = 2
30
-
31
- # Trigger is set to run the task on specific day(s) of the month
32
- TASK_TIME_TRIGGER_MONTHLYDATE = 3
33
-
34
- # Trigger is set to run the task on specific day(s) of the month
35
- TASK_TIME_TRIGGER_MONTHLYDOW = 4
36
-
37
- # Trigger is set to run the task if the system remains idle for the amount
38
- # of time specified by the idle wait time of the task
39
- TASK_EVENT_TRIGGER_ON_IDLE = 5
40
-
41
- # Trigger is set to run the task at system startup
42
- TASK_EVENT_TRIGGER_AT_SYSTEMSTART = 6
43
-
44
- # Trigger is set to run the task when a user logs on
45
- TASK_EVENT_TRIGGER_AT_LOGON = 7
46
-
47
- # Daily Tasks
48
-
49
- # The task will run on Sunday
50
- TASK_SUNDAY = 0x1
51
-
52
- # The task will run on Monday
53
- TASK_MONDAY = 0x2
54
-
55
- # The task will run on Tuesday
56
- TASK_TUESDAY = 0x4
57
-
58
- # The task will run on Wednesday
59
- TASK_WEDNESDAY = 0x8
60
-
61
- # The task will run on Thursday
62
- TASK_THURSDAY = 0x10
63
-
64
- # The task will run on Friday
65
- TASK_FRIDAY = 0x20
66
-
67
- # The task will run on Saturday
68
- TASK_SATURDAY = 0x40
69
-
70
- # Weekly tasks
71
-
72
- # The task will run between the 1st and 7th day of the month
73
- TASK_FIRST_WEEK = 1
74
-
75
- # The task will run between the 8th and 14th day of the month
76
- TASK_SECOND_WEEK = 2
77
-
78
- # The task will run between the 15th and 21st day of the month
79
- TASK_THIRD_WEEK = 3
80
-
81
- # The task will run between the 22nd and 28th day of the month
82
- TASK_FOURTH_WEEK = 4
83
-
84
- # The task will run the last seven days of the month
85
- TASK_LAST_WEEK = 5
86
-
87
- # Monthly tasks
88
-
89
- # The task will run in January
90
- TASK_JANUARY = 0x1
91
-
92
- # The task will run in February
93
- TASK_FEBRUARY = 0x2
94
-
95
- # The task will run in March
96
- TASK_MARCH = 0x4
97
-
98
- # The task will run in April
99
- TASK_APRIL = 0x8
100
-
101
- # The task will run in May
102
- TASK_MAY = 0x10
103
-
104
- # The task will run in June
105
- TASK_JUNE = 0x20
106
-
107
- # The task will run in July
108
- TASK_JULY = 0x40
109
-
110
- # The task will run in August
111
- TASK_AUGUST = 0x80
112
-
113
- # The task will run in September
114
- TASK_SEPTEMBER = 0x100
115
-
116
- # The task will run in October
117
- TASK_OCTOBER = 0x200
118
-
119
- # The task will run in November
120
- TASK_NOVEMBER = 0x400
121
-
122
- # The task will run in December
123
- TASK_DECEMBER = 0x800
124
-
125
- # Flags
126
-
127
- # Used when converting AT service jobs into work items
128
- TASK_FLAG_INTERACTIVE = 0x1
129
-
130
- # The work item will be deleted when there are no more scheduled run times
131
- TASK_FLAG_DELETE_WHEN_DONE = 0x2
132
-
133
- # The work item is disabled. Useful for temporarily disabling a task
134
- TASK_FLAG_DISABLED = 0x4
135
-
136
- # The work item begins only if the computer is not in use at the scheduled
137
- # start time
138
- TASK_FLAG_START_ONLY_IF_IDLE = 0x10
139
-
140
- # The work item terminates if the computer makes an idle to non-idle
141
- # transition while the work item is running
142
- TASK_FLAG_KILL_ON_IDLE_END = 0x20
143
-
144
- # The work item does not start if the computer is running on battery power
145
- TASK_FLAG_DONT_START_IF_ON_BATTERIES = 0x40
146
-
147
- # The work item ends, and the associated application quits, if the computer
148
- # switches to battery power
149
- TASK_FLAG_KILL_IF_GOING_ON_BATTERIES = 0x80
150
-
151
- # The work item starts only if the computer is in a docking station
152
- TASK_FLAG_RUN_ONLY_IF_DOCKED = 0x100
153
-
154
- # The work item created will be hidden
155
- TASK_FLAG_HIDDEN = 0x200
156
-
157
- # The work item runs only if there is a valid internet connection
158
- TASK_FLAG_RUN_IF_CONNECTED_TO_INTERNET = 0x400
159
-
160
- # The work item starts again if the computer makes a non-idle to idle
161
- # transition
162
- TASK_FLAG_RESTART_ON_IDLE_RESUME = 0x800
163
-
164
- # The work item causes the system to be resumed, or awakened, if the
165
- # system is running on batter power
166
- TASK_FLAG_SYSTEM_REQUIRED = 0x1000
167
-
168
- # The work item runs only if a specified account is logged on interactively
169
- TASK_FLAG_RUN_ONLY_IF_LOGGED_ON = 0x2000
170
-
171
- # Triggers
172
-
173
- # The task will stop at some point in time
174
- TASK_TRIGGER_FLAG_HAS_END_DATE = 0x1
175
-
176
- # The task can be stopped at the end of the repetition period
177
- TASK_TRIGGER_FLAG_KILL_AT_DURATION_END = 0x2
178
-
179
- # The task trigger is disabled
180
- TASK_TRIGGER_FLAG_DISABLED = 0x4
181
-
182
- # :stopdoc:
24
+ # Shorthand constants
183
25
 
184
- TASK_MAX_RUN_TIMES = 1440
185
- TASKS_TO_RETRIEVE = 5
26
+ IDLE = IDLE_PRIORITY_CLASS
27
+ NORMAL = NORMAL_PRIORITY_CLASS
28
+ HIGH = HIGH_PRIORITY_CLASS
29
+ REALTIME = REALTIME_PRIORITY_CLASS
30
+ BELOW_NORMAL = BELOW_NORMAL_PRIORITY_CLASS
31
+ ABOVE_NORMAL = ABOVE_NORMAL_PRIORITY_CLASS
186
32
 
187
- # Task creation
33
+ ONCE = TASK_TIME_TRIGGER_ONCE
34
+ DAILY = TASK_TIME_TRIGGER_DAILY
35
+ WEEKLY = TASK_TIME_TRIGGER_WEEKLY
36
+ MONTHLYDATE = TASK_TIME_TRIGGER_MONTHLYDATE
37
+ MONTHLYDOW = TASK_TIME_TRIGGER_MONTHLYDOW
188
38
 
189
- TASK_VALIDATE_ONLY = 0x1
190
- TASK_CREATE = 0x2
191
- TASK_UPDATE = 0x4
192
- TASK_CREATE_OR_UPDATE = 0x6
193
- TASK_DISABLE = 0x8
194
- TASK_DONT_ADD_PRINCIPAL_ACE = 0x10
195
- TASK_IGNORE_REGISTRATION_TRIGGERS = 0x20
39
+ ON_IDLE = TASK_EVENT_TRIGGER_ON_IDLE
40
+ AT_SYSTEMSTART = TASK_EVENT_TRIGGER_AT_SYSTEMSTART
41
+ AT_LOGON = TASK_EVENT_TRIGGER_AT_LOGON
42
+ FIRST_WEEK = TASK_FIRST_WEEK
43
+ SECOND_WEEK = TASK_SECOND_WEEK
44
+ THIRD_WEEK = TASK_THIRD_WEEK
45
+ FOURTH_WEEK = TASK_FOURTH_WEEK
46
+ LAST_WEEK = TASK_LAST_WEEK
47
+ SUNDAY = TASK_SUNDAY
48
+ MONDAY = TASK_MONDAY
49
+ TUESDAY = TASK_TUESDAY
50
+ WEDNESDAY = TASK_WEDNESDAY
51
+ THURSDAY = TASK_THURSDAY
52
+ FRIDAY = TASK_FRIDAY
53
+ SATURDAY = TASK_SATURDAY
54
+ JANUARY = TASK_JANUARY
55
+ FEBRUARY = TASK_FEBRUARY
56
+ MARCH = TASK_MARCH
57
+ APRIL = TASK_APRIL
58
+ MAY = TASK_MAY
59
+ JUNE = TASK_JUNE
60
+ JULY = TASK_JULY
61
+ AUGUST = TASK_AUGUST
62
+ SEPTEMBER = TASK_SEPTEMBER
63
+ OCTOBER = TASK_OCTOBER
64
+ NOVEMBER = TASK_NOVEMBER
65
+ DECEMBER = TASK_DECEMBER
196
66
 
197
- # Task logon types
67
+ INTERACTIVE = TASK_FLAG_INTERACTIVE
68
+ DELETE_WHEN_DONE = TASK_FLAG_DELETE_WHEN_DONE
69
+ DISABLED = TASK_FLAG_DISABLED
70
+ START_ONLY_IF_IDLE = TASK_FLAG_START_ONLY_IF_IDLE
71
+ KILL_ON_IDLE_END = TASK_FLAG_KILL_ON_IDLE_END
72
+ DONT_START_IF_ON_BATTERIES = TASK_FLAG_DONT_START_IF_ON_BATTERIES
73
+ KILL_IF_GOING_ON_BATTERIES = TASK_FLAG_KILL_IF_GOING_ON_BATTERIES
74
+ RUN_ONLY_IF_DOCKED = TASK_FLAG_RUN_ONLY_IF_DOCKED
75
+ HIDDEN = TASK_FLAG_HIDDEN
76
+ RUN_IF_CONNECTED_TO_INTERNET = TASK_FLAG_RUN_IF_CONNECTED_TO_INTERNET
77
+ RESTART_ON_IDLE_RESUME = TASK_FLAG_RESTART_ON_IDLE_RESUME
78
+ SYSTEM_REQUIRED = TASK_FLAG_SYSTEM_REQUIRED
79
+ RUN_ONLY_IF_LOGGED_ON = TASK_FLAG_RUN_ONLY_IF_LOGGED_ON
198
80
 
199
- TASK_LOGON_NONE = 0
200
- TASK_LOGON_PASSWORD = 1
201
- TASK_LOGON_S4U = 2
202
- TASK_LOGON_INTERACTIVE_TOKEN = 3
203
- TASK_LOGON_GROUP = 4
204
- TASK_LOGON_SERVICE_ACCOUNT = 5
205
- TASK_LOGON_INTERACTIVE_TOKEN_OR_PASSWORD = 6
81
+ FLAG_HAS_END_DATE = TASK_TRIGGER_FLAG_HAS_END_DATE
82
+ FLAG_KILL_AT_DURATION_END = TASK_TRIGGER_FLAG_KILL_AT_DURATION_END
83
+ FLAG_DISABLED = TASK_TRIGGER_FLAG_DISABLED
206
84
 
207
- # Priority classes
85
+ MAX_RUN_TIMES = TASK_MAX_RUN_TIMES
208
86
 
209
- REALTIME_PRIORITY_CLASS = 0
210
- HIGH_PRIORITY_CLASS = 1
211
- ABOVE_NORMAL_PRIORITY_CLASS = 2 # Or 3
212
- NORMAL_PRIORITY_CLASS = 4 # Or 5, 6
213
- BELOW_NORMAL_PRIORITY_CLASS = 7 # Or 8
214
- IDLE_PRIORITY_CLASS = 9 # Or 10
87
+ FIRST = TASK_FIRST
88
+ SECOND = TASK_SECOND
89
+ THIRD = TASK_THIRD
90
+ FOURTH = TASK_FOURTH
91
+ FIFTH = TASK_FIFTH
92
+ SIXTH = TASK_SIXTH
93
+ SEVENTH = TASK_SEVENTH
94
+ EIGHTH = TASK_EIGHTH
95
+ NINETH = TASK_NINETH
96
+ TENTH = TASK_TENTH
97
+ ELEVENTH = TASK_ELEVENTH
98
+ TWELFTH = TASK_TWELFTH
99
+ THIRTEENTH = TASK_THIRTEENTH
100
+ FOURTEENTH = TASK_FOURTEENTH
101
+ FIFTEENTH = TASK_FIFTEENTH
102
+ SIXTEENTH = TASK_SIXTEENTH
103
+ SEVENTEENTH = TASK_SEVENTEENTH
104
+ EIGHTEENTH = TASK_EIGHTEENTH
105
+ NINETEENTH = TASK_NINETEENTH
106
+ TWENTIETH = TASK_TWENTIETH
107
+ TWENTY_FIRST = TASK_TWENTY_FIRST
108
+ TWENTY_SECOND = TASK_TWENTY_SECOND
109
+ TWENTY_THIRD = TASK_TWENTY_THIRD
110
+ TWENTY_FOURTH = TASK_TWENTY_FOURTH
111
+ TWENTY_FIFTH = TASK_TWENTY_FIFTH
112
+ TWENTY_SIXTH = TASK_TWENTY_SIXTH
113
+ TWENTY_SEVENTH = TASK_TWENTY_SEVENTH
114
+ TWENTY_EIGHTH = TASK_TWENTY_EIGHTH
115
+ TWENTY_NINTH = TASK_TWENTY_NINTH
116
+ THIRTYETH = TASK_THIRTYETH
117
+ THIRTY_FIRST = TASK_THIRTY_FIRST
118
+ LAST = TASK_LAST
215
119
 
216
- CLSCTX_INPROC_SERVER = 0x1
217
- CLSID_CTask = [0x148BD520,0xA2AB,0x11CE,0xB1,0x1F,0x00,0xAA,0x00,0x53,0x05,0x03].pack('LSSC8')
218
- CLSID_CTaskScheduler = [0x148BD52A,0xA2AB,0x11CE,0xB1,0x1F,0x00,0xAA,0x00,0x53,0x05,0x03].pack('LSSC8')
219
- IID_ITaskScheduler = [0x148BD527,0xA2AB,0x11CE,0xB1,0x1F,0x00,0xAA,0x00,0x53,0x05,0x03].pack('LSSC8')
220
- IID_ITask = [0x148BD524,0xA2AB,0x11CE,0xB1,0x1F,0x00,0xAA,0x00,0x53,0x05,0x03].pack('LSSC8')
221
- IID_IPersistFile = [0x0000010b,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46].pack('LSSC8')
222
120
 
223
121
  # :startdoc:
224
122
 
@@ -298,6 +196,19 @@ module Win32
298
196
  enum.include?(task)
299
197
  end
300
198
 
199
+ # Return the sepcified task if exist
200
+ #
201
+ def get_task(task)
202
+ raise TypeError unless task.is_a?(String)
203
+
204
+ begin
205
+ registeredTask = @root.GetTask(task)
206
+ @task = registeredTask
207
+ rescue WIN32OLERuntimeError => err
208
+ raise Error, ole_error('activate', err)
209
+ end
210
+ end
211
+
301
212
  # Activate the specified task.
302
213
  #
303
214
  def activate(task)
@@ -388,10 +299,12 @@ module Win32
388
299
 
389
300
  # Sets the +user+ and +password+ for the given task. If the user and
390
301
  # password are set properly then true is returned.
391
- #
302
+ # throws TypeError if password is not provided for other than system users
392
303
  def set_account_information(user, password)
393
304
  raise TypeError unless user.is_a?(String)
394
- raise TypeError unless password.is_a?(String)
305
+ unless SYSTEM_USERS.include?(user.upcase)
306
+ raise TypeError unless password.is_a?(String)
307
+ end
395
308
  check_for_active_task
396
309
 
397
310
  @password = password
@@ -582,8 +495,6 @@ module Win32
582
495
  raise TypeError unless task.is_a?(String)
583
496
  raise TypeError unless trigger.is_a?(Hash)
584
497
 
585
- validate_trigger(trigger)
586
-
587
498
  taskDefinition = @service.NewTask(0)
588
499
  taskDefinition.RegistrationInfo.Description = ''
589
500
  taskDefinition.RegistrationInfo.Author = ''
@@ -591,95 +502,85 @@ module Win32
591
502
  taskDefinition.Settings.Enabled = true
592
503
  taskDefinition.Settings.Hidden = false
593
504
 
594
- case trigger[:trigger_type]
595
- when TASK_TIME_TRIGGER_ONCE
596
- type = 1
597
- when TASK_TIME_TRIGGER_DAILY
598
- type = 2
599
- when TASK_TIME_TRIGGER_WEEKLY
600
- type = 3
601
- when TASK_TIME_TRIGGER_MONTHLYDATE
602
- type = 4
603
- when TASK_TIME_TRIGGER_MONTHLYDOW
604
- type = 5
605
- when TASK_EVENT_TRIGGER_ON_IDLE
606
- type = 6
607
- when TASK_EVENT_TRIGGER_AT_SYSTEMSTART
608
- type = 8
609
- when TASK_EVENT_TRIGGER_AT_LOGON
610
- type = 9
611
- else
612
- raise ArgumentError, 'Unknown trigger type'
613
- end
505
+ unless trigger.empty?
506
+ raise ArgumentError, 'Unknown trigger type' unless valid_trigger_option(trigger[:trigger_type])
507
+ validate_trigger(trigger)
614
508
 
615
- startTime = "%04d-%02d-%02dT%02d:%02d:00" % [
616
- trigger[:start_year], trigger[:start_month], trigger[:start_day],
617
- trigger[:start_hour], trigger[:start_minute]
618
- ]
619
-
620
- # Set defaults
621
- trigger[:end_year] ||= 0
622
- trigger[:end_month] ||= 0
623
- trigger[:end_day] ||= 0
509
+ startTime = "%04d-%02d-%02dT%02d:%02d:00" % [
510
+ trigger[:start_year], trigger[:start_month], trigger[:start_day],
511
+ trigger[:start_hour], trigger[:start_minute]
512
+ ]
624
513
 
625
- endTime = "%04d-%02d-%02dT00:00:00" % [
626
- trigger[:end_year], trigger[:end_month], trigger[:end_day]
627
- ]
514
+ # Set defaults
515
+ trigger[:end_year] ||= 0
516
+ trigger[:end_month] ||= 0
517
+ trigger[:end_day] ||= 0
628
518
 
629
- trig = taskDefinition.Triggers.Create(type)
630
- trig.Id = "RegistrationTriggerId#{taskDefinition.Triggers.Count}"
631
- trig.StartBoundary = startTime
632
- trig.EndBoundary = endTime if endTime != '0000-00-00T00:00:00'
633
- trig.Enabled = true
519
+ endTime = "%04d-%02d-%02dT00:00:00" % [
520
+ trigger[:end_year], trigger[:end_month], trigger[:end_day]
521
+ ]
634
522
 
635
- repetitionPattern = trig.Repetition
523
+ trig = taskDefinition.Triggers.Create(trigger[:trigger_type].to_i)
524
+ trig.Id = "RegistrationTriggerId#{taskDefinition.Triggers.Count}"
525
+ trig.StartBoundary = startTime
526
+ trig.EndBoundary = endTime if endTime != '0000-00-00T00:00:00'
527
+ trig.Enabled = true
636
528
 
637
- if trigger[:minutes_duration].to_i > 0
638
- repetitionPattern.Duration = "PT#{trigger[:minutes_duration]||0}M"
639
- end
529
+ repetitionPattern = trig.Repetition
640
530
 
641
- if trigger[:minutes_interval].to_i > 0
642
- repetitionPattern.Interval = "PT#{trigger[:minutes_interval]||0}M"
643
- end
531
+ if trigger[:minutes_duration].to_i > 0
532
+ repetitionPattern.Duration = "PT#{trigger[:minutes_duration]||0}M"
533
+ end
644
534
 
645
- tmp = trigger[:type]
646
- tmp = nil unless tmp.is_a?(Hash)
535
+ if trigger[:minutes_interval].to_i > 0
536
+ repetitionPattern.Interval = "PT#{trigger[:minutes_interval]||0}M"
537
+ end
647
538
 
648
- case trigger[:trigger_type]
649
- when TASK_TIME_TRIGGER_DAILY
650
- trig.DaysInterval = tmp[:days_interval] if tmp && tmp[:days_interval]
651
- if trigger[:random_minutes_interval].to_i > 0
652
- trig.RandomDelay = "PT#{trigger[:random_minutes_interval]}M"
653
- end
654
- when TASK_TIME_TRIGGER_WEEKLY
655
- trig.DaysOfWeek = tmp[:days_of_week] if tmp && tmp[:days_of_week]
656
- trig.WeeksInterval = tmp[:weeks_interval] if tmp && tmp[:weeks_interval]
657
- if trigger[:random_minutes_interval].to_i > 0
658
- trig.RandomDelay = "PT#{trigger[:random_minutes_interval]||0}M"
659
- end
660
- when TASK_TIME_TRIGGER_MONTHLYDATE
661
- trig.MonthsOfYear = tmp[:months] if tmp && tmp[:months]
662
- trig.DaysOfMonth = tmp[:days] if tmp && tmp[:days]
663
- if trigger[:random_minutes_interval].to_i > 0
664
- trig.RandomDelay = "PT#{trigger[:random_minutes_interval]||0}M"
665
- end
666
- when TASK_TIME_TRIGGER_MONTHLYDOW
667
- trig.MonthsOfYear = tmp[:months] if tmp && tmp[:months]
668
- trig.DaysOfWeek = tmp[:days_of_week] if tmp && tmp[:days_of_week]
669
- trig.WeeksOfMonth = tmp[:weeks] if tmp && tmp[:weeks]
670
- if trigger[:random_minutes_interval].to_i>0
671
- trig.RandomDelay = "PT#{trigger[:random_minutes_interval]||0}M"
672
- end
673
- when TASK_TIME_TRIGGER_ONCE
674
- if trigger[:random_minutes_interval].to_i > 0
675
- trig.RandomDelay = "PT#{trigger[:random_minutes_interval]||0}M"
676
- end
539
+ tmp = trigger[:type]
540
+ tmp = nil unless tmp.is_a?(Hash)
541
+
542
+ case trigger[:trigger_type]
543
+ when TASK_TIME_TRIGGER_DAILY
544
+ trig.DaysInterval = tmp[:days_interval] if tmp && tmp[:days_interval]
545
+ if trigger[:random_minutes_interval].to_i > 0
546
+ trig.RandomDelay = "PT#{trigger[:random_minutes_interval]}M"
547
+ end
548
+ when TASK_TIME_TRIGGER_WEEKLY
549
+ trig.DaysOfWeek = tmp[:days_of_week] if tmp && tmp[:days_of_week]
550
+ trig.WeeksInterval = tmp[:weeks_interval] if tmp && tmp[:weeks_interval]
551
+ if trigger[:random_minutes_interval].to_i > 0
552
+ trig.RandomDelay = "PT#{trigger[:random_minutes_interval]||0}M"
553
+ end
554
+ when TASK_TIME_TRIGGER_MONTHLYDATE
555
+ trig.MonthsOfYear = tmp[:months] if tmp && tmp[:months]
556
+ trig.DaysOfMonth = tmp[:days] if tmp && tmp[:days]
557
+ if trigger[:random_minutes_interval].to_i > 0
558
+ trig.RandomDelay = "PT#{trigger[:random_minutes_interval]||0}M"
559
+ end
560
+ trig.RunOnLastDayOfMonth = trigger[:run_on_last_day_of_month] if trigger[:run_on_last_day_of_month]
561
+ when TASK_TIME_TRIGGER_MONTHLYDOW
562
+ trig.MonthsOfYear = tmp[:months] if tmp && tmp[:months]
563
+ trig.DaysOfWeek = tmp[:days_of_week] if tmp && tmp[:days_of_week]
564
+ trig.WeeksOfMonth = tmp[:weeks_of_month] if tmp && tmp[:weeks_of_month]
565
+ if trigger[:random_minutes_interval].to_i>0
566
+ trig.RandomDelay = "PT#{trigger[:random_minutes_interval]||0}M"
567
+ end
568
+ trig.RunOnLastWeekOfMonth = trigger[:run_on_last_week_of_month] if trigger[:run_on_last_week_of_month]
569
+ when TASK_TIME_TRIGGER_ONCE
570
+ if trigger[:random_minutes_interval].to_i > 0
571
+ trig.RandomDelay = "PT#{trigger[:random_minutes_interval]||0}M"
572
+ end
573
+ when TASK_EVENT_TRIGGER_AT_SYSTEMSTART
574
+ trig.Delay = "PT#{trigger[:delay_duration]||0}M"
575
+ when TASK_EVENT_TRIGGER_AT_LOGON
576
+ trig.UserId = trigger[:user_id] if trigger[:user_id]
577
+ trig.Delay = "PT#{trigger[:delay_duration]||0}M"
578
+ end
677
579
  end
678
580
 
679
581
  act = taskDefinition.Actions.Create(0)
680
582
  act.Path = 'cmd'
681
583
 
682
-
683
584
  begin
684
585
  @task = @root.RegisterTaskDefinition(
685
586
  task,
@@ -756,59 +657,60 @@ module Win32
756
657
  end
757
658
 
758
659
  trigger = {}
759
- trigger[:start_year], trigger[:start_month],
760
- trigger[:start_day], trigger[:start_hour],
761
- trigger[:start_minute] = trig.StartBoundary.scan(/(\d+)-(\d+)-(\d+)T(\d+):(\d+)/).first
762
-
763
- trigger[:end_year], trigger[:end_month],
764
- trigger[:end_day] = trig.StartBoundary.scan(/(\d+)-(\d+)-(\d+)T/).first
765
-
766
- if trig.Repetition.Duration != ""
767
- trigger[:minutes_duration] = trig.Repetition.Duration.scan(/(\d+)M/)[0][0].to_i
768
- end
769
-
770
- if trig.Repetition.Interval != ""
771
- trigger[:minutes_interval] = trig.Repetition.Interval.scan(/(\d+)M/)[0][0].to_i
772
- end
773
-
774
- if trig.RandomDelay != ""
775
- trigger[:random_minutes_interval] = trig.RandomDelay.scan(/(\d+)M/)[0][0].to_i
776
- end
777
660
 
778
661
  case trig.Type
779
- when 2
780
- trigger[:trigger_type] = TASK_TIME_TRIGGER_DAILY
662
+ when TASK_TIME_TRIGGER_DAILY
781
663
  tmp = {}
782
664
  tmp[:days_interval] = trig.DaysInterval
783
665
  trigger[:type] = tmp
784
- when 3
785
- trigger[:trigger_type] = TASK_TIME_TRIGGER_WEEKLY
666
+ trigger[:random_minutes_interval] = time_in_minutes(trig.RandomDelay)
667
+ when TASK_TIME_TRIGGER_WEEKLY
786
668
  tmp = {}
787
669
  tmp[:weeks_interval] = trig.WeeksInterval
788
670
  tmp[:days_of_week] = trig.DaysOfWeek
789
671
  trigger[:type] = tmp
790
- when 4
791
- trigger[:trigger_type] = TASK_TIME_TRIGGER_MONTHLYDATE
672
+ trigger[:random_minutes_interval] = time_in_minutes(trig.RandomDelay)
673
+ when TASK_TIME_TRIGGER_MONTHLYDATE
792
674
  tmp = {}
793
675
  tmp[:months] = trig.MonthsOfYear
794
676
  tmp[:days] = trig.DaysOfMonth
795
677
  trigger[:type] = tmp
796
- when 5
797
- trigger[:trigger_type] = TASK_TIME_TRIGGER_MONTHLYDOW
678
+ trigger[:random_minutes_interval] = time_in_minutes(trig.RandomDelay)
679
+ trigger[:run_on_last_day_of_month] = trig.RunOnLastDayOfMonth
680
+ when TASK_TIME_TRIGGER_MONTHLYDOW
798
681
  tmp = {}
799
682
  tmp[:months] = trig.MonthsOfYear
800
683
  tmp[:days_of_week] = trig.DaysOfWeek
801
- tmp[:weeks] = trig.weeks
684
+ tmp[:weeks_of_month] = trig.WeeksOfMonth
802
685
  trigger[:type] = tmp
803
- when 1
804
- trigger[:trigger_type] = TASK_TIME_TRIGGER_ONCE
686
+ trigger[:random_minutes_interval] = time_in_minutes(trig.RandomDelay)
687
+ trigger[:run_on_last_week_of_month] = trig.RunOnLastWeekOfMonth
688
+ when TASK_TIME_TRIGGER_ONCE
805
689
  tmp = {}
806
690
  tmp[:once] = nil
807
691
  trigger[:type] = tmp
692
+ trigger[:random_minutes_interval] = time_in_minutes(trig.RandomDelay)
693
+ when TASK_EVENT_TRIGGER_AT_SYSTEMSTART
694
+ trigger[:delay_duration] = time_in_minutes(trig.Delay)
695
+ when TASK_EVENT_TRIGGER_AT_LOGON
696
+ trigger[:user_id] = trig.UserId if trig.UserId.to_s != ""
697
+ trigger[:delay_duration] = time_in_minutes(trig.Delay)
698
+ when TASK_EVENT_TRIGGER_ON_IDLE
699
+ trigger[:execution_time_limit] = time_in_minutes(trig.ExecutionTimeLimit)
808
700
  else
809
701
  raise Error, 'Unknown trigger type'
810
702
  end
811
703
 
704
+ trigger[:start_year], trigger[:start_month], trigger[:start_day],
705
+ trigger[:start_hour], trigger[:start_minute] = trig.StartBoundary.scan(/(\d+)-(\d+)-(\d+)T(\d+):(\d+)/).first
706
+
707
+ trigger[:end_year], trigger[:end_month],
708
+ trigger[:end_day] = trig.EndBoundary.scan(/(\d+)-(\d+)-(\d+)T/).first
709
+
710
+ trigger[:minutes_duration] = time_in_minutes(trig.Repetition.Duration)
711
+ trigger[:minutes_interval] = time_in_minutes(trig.Repetition.Interval)
712
+ trigger[:trigger_type] = trig.Type
713
+
812
714
  trigger
813
715
  end
814
716
 
@@ -838,6 +740,8 @@ module Win32
838
740
  #
839
741
  def trigger=(trigger)
840
742
  raise TypeError unless trigger.is_a?(Hash)
743
+ raise ArgumentError, 'Unknown trigger type' unless valid_trigger_option(trigger[:trigger_type])
744
+
841
745
  check_for_active_task
842
746
 
843
747
  validate_trigger(trigger)
@@ -845,27 +749,6 @@ module Win32
845
749
  definition = @task.Definition
846
750
  definition.Triggers.Clear()
847
751
 
848
- case trigger[:trigger_type]
849
- when TASK_TIME_TRIGGER_ONCE
850
- type = 1
851
- when TASK_TIME_TRIGGER_DAILY
852
- type = 2
853
- when TASK_TIME_TRIGGER_WEEKLY
854
- type = 3
855
- when TASK_TIME_TRIGGER_MONTHLYDATE
856
- type = 4
857
- when TASK_TIME_TRIGGER_MONTHLYDOW
858
- type = 5
859
- when TASK_EVENT_TRIGGER_ON_IDLE
860
- type = 6
861
- when TASK_EVENT_TRIGGER_AT_SYSTEM_START
862
- type = 8
863
- when TASK_EVENT_TRIGGER_AT_LOGON
864
- type = 9
865
- else
866
- raise Error, 'Unknown trigger type'
867
- end
868
-
869
752
  startTime = "%04d-%02d-%02dT%02d:%02d:00" % [
870
753
  trigger[:start_year], trigger[:start_month],
871
754
  trigger[:start_day], trigger[:start_hour], trigger[:start_minute]
@@ -875,7 +758,7 @@ module Win32
875
758
  trigger[:end_year], trigger[:end_month], trigger[:end_day]
876
759
  ]
877
760
 
878
- trig = definition.Triggers.Create(type)
761
+ trig = definition.Triggers.Create( trigger[:trigger_type].to_i )
879
762
  trig.Id = "RegistrationTriggerId#{definition.Triggers.Count}"
880
763
  trig.StartBoundary = startTime
881
764
  trig.EndBoundary = endTime if endTime != '0000-00-00T00:00:00'
@@ -912,17 +795,29 @@ module Win32
912
795
  if trigger[:random_minutes_interval].to_i > 0
913
796
  trig.RandomDelay = "PT#{trigger[:random_minutes_interval]||0}M"
914
797
  end
798
+ trig.RunOnLastDayOfMonth = trigger[:run_on_last_day_of_month] if trigger[:run_on_last_day_of_month]
915
799
  when TASK_TIME_TRIGGER_MONTHLYDOW
916
800
  trig.MonthsOfYear = tmp[:months] if tmp && tmp[:months]
917
801
  trig.DaysOfWeek = tmp[:days_of_week] if tmp && tmp[:days_of_week]
918
- trig.WeeksOfMonth = tmp[:weeks] if tmp && tmp[:weeks]
802
+ trig.WeeksOfMonth = tmp[:weeks_of_month] if tmp && tmp[:weeks_of_month]
919
803
  if trigger[:random_minutes_interval].to_i > 0
920
804
  trig.RandomDelay = "PT#{trigger[:random_minutes_interval]||0}M"
921
805
  end
806
+ trig.RunOnLastWeekOfMonth = trigger[:run_on_last_week_of_month] if trigger[:run_on_last_week_of_month]
922
807
  when TASK_TIME_TRIGGER_ONCE
923
808
  if trigger[:random_minutes_interval].to_i > 0
924
809
  trig.RandomDelay = "PT#{trigger[:random_minutes_interval]||0}M"
925
810
  end
811
+ when TASK_EVENT_TRIGGER_AT_SYSTEMSTART
812
+ trig.Delay = "PT#{trigger[:delay_duration]||0}M"
813
+ when TASK_EVENT_TRIGGER_AT_LOGON
814
+ trig.UserId = trigger[:user_id] if trigger[:user_id]
815
+ trig.Delay = "PT#{trigger[:delay_duration]||0}M"
816
+ when TASK_EVENT_TRIGGER_ON_IDLE
817
+ # for setting execution time limit Ref : https://msdn.microsoft.com/en-us/library/windows/desktop/aa380724(v=vs.85).aspx
818
+ if trigger[:execution_time_limit].to_i > 0
819
+ trig.ExecutionTimeLimit = "PT#{trigger[:execution_time_limit]||0}M"
820
+ end
926
821
  end
927
822
 
928
823
  update_task_definition(definition)
@@ -935,23 +830,11 @@ module Win32
935
830
  def add_trigger(index, trigger)
936
831
  raise TypeError unless index.is_a?(Numeric)
937
832
  raise TypeError unless trigger.is_a?(Hash)
833
+ raise ArgumentError, 'Unknown trigger type' unless valid_trigger_option(trigger[:trigger_type])
834
+
938
835
  check_for_active_task
939
836
 
940
837
  definition = @task.Definition
941
- case trigger[:trigger_type]
942
- when TASK_TIME_TRIGGER_DAILY
943
- type = 2
944
- when TASK_TIME_TRIGGER_WEEKLY
945
- type = 3
946
- when TASK_TIME_TRIGGER_MONTHLYDATE
947
- type = 4
948
- when TASK_TIME_TRIGGER_MONTHLYDOW
949
- type = 5
950
- when TASK_TIME_TRIGGER_ONCE
951
- type = 1
952
- else
953
- raise Error, 'Unknown trigger type'
954
- end
955
838
 
956
839
  startTime = "%04d-%02d-%02dT%02d:%02d:00" % [
957
840
  trigger[:start_year], trigger[:start_month], trigger[:start_day],
@@ -967,7 +850,7 @@ module Win32
967
850
  trigger[:end_year], trigger[:end_month], trigger[:end_day]
968
851
  ]
969
852
 
970
- trig = definition.Triggers.Create(type)
853
+ trig = definition.Triggers.Create( trigger[:trigger_type].to_i )
971
854
  trig.Id = "RegistrationTriggerId#{definition.Triggers.Count}"
972
855
  trig.StartBoundary = startTime
973
856
  trig.EndBoundary = endTime if endTime != '0000-00-00T00:00:00'
@@ -1002,19 +885,26 @@ module Win32
1002
885
  trig.MonthsOfYear = tmp[:months] if tmp && tmp[:months]
1003
886
  trig.DaysOfMonth = tmp[:days] if tmp && tmp[:days]
1004
887
  if trigger[:random_minutes_interval].to_i > 0
1005
- trig.RandomDelay = "PT#{trigger[:random_minutes_interval]||0}M"
888
+ trig.RandomDelay = "PT#{trigger[:random_minutes_interval]||0}M"
1006
889
  end
890
+ trig.RunOnLastDayOfMonth = trigger[:run_on_last_day_of_month] if trigger[:run_on_last_day_of_month]
1007
891
  when TASK_TIME_TRIGGER_MONTHLYDOW
1008
892
  trig.MonthsOfYear = tmp[:months] if tmp && tmp[:months]
1009
893
  trig.DaysOfWeek = tmp[:days_of_week] if tmp && tmp[:days_of_week]
1010
- trig.WeeksOfMonth = tmp[:weeks] if tmp && tmp[:weeks]
894
+ trig.WeeksOfMonth = tmp[:weeks_of_month] if tmp && tmp[:weeks_of_month]
1011
895
  if trigger[:random_minutes_interval].to_i > 0
1012
896
  trig.RandomDelay = "PT#{trigger[:random_minutes_interval]||0}M"
1013
897
  end
898
+ trig.RunOnLastWeekOfMonth = trigger[:run_on_last_week_of_month] if trigger[:run_on_last_week_of_month]
1014
899
  when TASK_TIME_TRIGGER_ONCE
1015
900
  if trigger[:random_minutes_interval].to_i > 0
1016
901
  trig.RandomDelay = "PT#{trigger[:random_minutes_interval]||0}M"
1017
902
  end
903
+ when TASK_EVENT_TRIGGER_AT_SYSTEMSTART
904
+ trig.Delay = "PT#{trigger[:delay_duration]||0}M"
905
+ when TASK_EVENT_TRIGGER_AT_LOGON
906
+ trig.UserId = trigger[:user_id] if trigger[:user_id]
907
+ trig.Delay = "PT#{trigger[:delay_duration]||0}M"
1018
908
  end
1019
909
 
1020
910
  update_task_definition(definition)
@@ -1033,6 +923,8 @@ module Win32
1033
923
  status = 'ready'
1034
924
  when 4
1035
925
  status = 'running'
926
+ when 2
927
+ status = 'queued'
1036
928
  when 1
1037
929
  status = 'not scheduled'
1038
930
  else
@@ -1042,6 +934,12 @@ module Win32
1042
934
  status
1043
935
  end
1044
936
 
937
+ # Returns true if current task is enabled
938
+ def enabled?
939
+ check_for_active_task
940
+ @task.enabled
941
+ end
942
+
1045
943
  # Returns the exit code from the last scheduled run.
1046
944
  #
1047
945
  def exit_code
@@ -1121,6 +1019,25 @@ module Win32
1121
1019
  time
1122
1020
  end
1123
1021
 
1022
+ # Returns idle settings for current active task
1023
+ #
1024
+ def idle_settings
1025
+ check_for_active_task
1026
+ idle_settings = {}
1027
+ idle_settings[:idle_duration] = @task.Definition.Settings.IdleSettings.IdleDuration
1028
+ idle_settings[:stop_on_idle_end] = @task.Definition.Settings.IdleSettings.StopOnIdleEnd
1029
+ idle_settings[:wait_timeout] = @task.Definition.Settings.IdleSettings.WaitTimeout
1030
+ idle_settings[:restart_on_idle] = @task.Definition.Settings.IdleSettings.RestartOnIdle
1031
+ idle_settings
1032
+ end
1033
+
1034
+ # Returns the execution time limit for current active task
1035
+ #
1036
+ def execution_time_limit
1037
+ check_for_active_task
1038
+ @task.Definition.Settings.ExecutionTimeLimit
1039
+ end
1040
+
1124
1041
  # Returns the maximum length of time, in milliseconds, that the task
1125
1042
  # will run before terminating.
1126
1043
  #
@@ -1203,9 +1120,12 @@ module Win32
1203
1120
  delete_expired_task_after = hash[:delete_expired_task_after]
1204
1121
  disallow_start_if_on_batteries = hash[:disallow_start_if_on_batteries]
1205
1122
  enabled = hash[:enabled]
1206
- execution_time_limit = hash[:execution_time_limit] || hash[:max_run_time]
1123
+ execution_time_limit = "PT#{hash[:execution_time_limit] || hash[:max_run_time] || 0}M"
1207
1124
  hidden = hash[:hidden]
1208
- idle_settings = hash[:idle_settings]
1125
+ idle_duration = "PT#{hash[:idle_duration]||0}M"
1126
+ stop_on_idle_end = hash[:stop_on_idle_end]
1127
+ wait_timeout = "PT#{hash[:wait_timeout]||0}M"
1128
+ restart_on_idle = hash[:restart_on_idle]
1209
1129
  network_settings = hash[:network_settings]
1210
1130
  priority = hash[:priority]
1211
1131
  restart_count = hash[:restart_count]
@@ -1225,7 +1145,10 @@ module Win32
1225
1145
  definition.Settings.Enabled = enabled if enabled
1226
1146
  definition.Settings.ExecutionTimeLimit = execution_time_limit if execution_time_limit
1227
1147
  definition.Settings.Hidden = hidden if hidden
1228
- definition.Settings.IdleSettings = idle_settings if idle_settings
1148
+ definition.Settings.IdleSettings.IdleDuration = idle_duration if idle_duration
1149
+ definition.Settings.IdleSettings.StopOnIdleEnd = stop_on_idle_end if stop_on_idle_end
1150
+ definition.Settings.IdleSettings.WaitTimeout = wait_timeout if wait_timeout
1151
+ definition.Settings.IdleSettings.RestartOnIdle = restart_on_idle if restart_on_idle
1229
1152
  definition.Settings.NetworkSettings = network_settings if network_settings
1230
1153
  definition.Settings.Priority = priority if priority
1231
1154
  definition.Settings.RestartCount = restart_count if restart_count
@@ -1289,71 +1212,88 @@ module Win32
1289
1212
  hash
1290
1213
  end
1291
1214
 
1292
- # Shorthand constants
1293
-
1294
- IDLE = IDLE_PRIORITY_CLASS
1295
- NORMAL = NORMAL_PRIORITY_CLASS
1296
- HIGH = HIGH_PRIORITY_CLASS
1297
- REALTIME = REALTIME_PRIORITY_CLASS
1298
- BELOW_NORMAL = BELOW_NORMAL_PRIORITY_CLASS
1299
- ABOVE_NORMAL = ABOVE_NORMAL_PRIORITY_CLASS
1215
+ # Sets the principals for current active task. The principal is hash with following possible options.
1216
+ # Expected principal hash: { id: STRING, display_name: STRING, user_id: STRING,
1217
+ # logon_type: INTEGER, group_id: STRING, run_level: INTEGER }
1218
+ #
1219
+ def configure_principals(principals)
1220
+ raise TypeError unless principals.is_a?(Hash)
1221
+ check_for_active_task
1222
+ definition = @task.Definition
1223
+ definition.Principal.Id = principals[:id] if principals[:id].to_s != ""
1224
+ definition.Principal.DisplayName = principals[:display_name] if principals[:display_name].to_s != ""
1225
+ definition.Principal.UserId = principals[:user_id] if principals[:user_id].to_s != ""
1226
+ definition.Principal.LogonType = principals[:logon_type] if principals[:logon_type].to_s != ""
1227
+ definition.Principal.GroupId = principals[:group_id] if principals[:group_id].to_s != ""
1228
+ definition.Principal.RunLevel = principals[:run_level] if principals[:run_level].to_s != ""
1229
+ update_task_definition(definition)
1230
+ principals
1231
+ end
1300
1232
 
1301
- ONCE = TASK_TIME_TRIGGER_ONCE
1302
- DAILY = TASK_TIME_TRIGGER_DAILY
1303
- WEEKLY = TASK_TIME_TRIGGER_WEEKLY
1304
- MONTHLYDATE = TASK_TIME_TRIGGER_MONTHLYDATE
1305
- MONTHLYDOW = TASK_TIME_TRIGGER_MONTHLYDOW
1233
+ # Returns a hash containing all the principal information of the current task
1234
+ def principals
1235
+ check_for_active_task
1236
+ principals_hash = {}
1237
+ @task.Definition.Principal.ole_get_methods.each do |principal|
1238
+ principals_hash[principal.name] = @task.Definition.Principal._getproperty(principal.dispid, [], [])
1239
+ end
1240
+ symbolize_keys(principals_hash)
1241
+ end
1306
1242
 
1307
- ON_IDLE = TASK_EVENT_TRIGGER_ON_IDLE
1308
- AT_SYSTEMSTART = TASK_EVENT_TRIGGER_AT_SYSTEMSTART
1309
- AT_LOGON = TASK_EVENT_TRIGGER_AT_LOGON
1310
- FIRST_WEEK = TASK_FIRST_WEEK
1311
- SECOND_WEEK = TASK_SECOND_WEEK
1312
- THIRD_WEEK = TASK_THIRD_WEEK
1313
- FOURTH_WEEK = TASK_FOURTH_WEEK
1314
- LAST_WEEK = TASK_LAST_WEEK
1315
- SUNDAY = TASK_SUNDAY
1316
- MONDAY = TASK_MONDAY
1317
- TUESDAY = TASK_TUESDAY
1318
- WEDNESDAY = TASK_WEDNESDAY
1319
- THURSDAY = TASK_THURSDAY
1320
- FRIDAY = TASK_FRIDAY
1321
- SATURDAY = TASK_SATURDAY
1322
- JANUARY = TASK_JANUARY
1323
- FEBRUARY = TASK_FEBRUARY
1324
- MARCH = TASK_MARCH
1325
- APRIL = TASK_APRIL
1326
- MAY = TASK_MAY
1327
- JUNE = TASK_JUNE
1328
- JULY = TASK_JULY
1329
- AUGUST = TASK_AUGUST
1330
- SEPTEMBER = TASK_SEPTEMBER
1331
- OCTOBER = TASK_OCTOBER
1332
- NOVEMBER = TASK_NOVEMBER
1333
- DECEMBER = TASK_DECEMBER
1243
+ # Returns a hash containing all settings of the current task
1244
+ def settings
1245
+ check_for_active_task
1246
+ settings_hash = {}
1247
+ @task.Definition.Settings.ole_get_methods.each do |setting|
1248
+ next if setting.name == "XmlText" # not needed
1249
+ settings_hash[setting.name] = @task.Definition.Settings._getproperty(setting.dispid, [], [])
1250
+ end
1334
1251
 
1335
- INTERACTIVE = TASK_FLAG_INTERACTIVE
1336
- DELETE_WHEN_DONE = TASK_FLAG_DELETE_WHEN_DONE
1337
- DISABLED = TASK_FLAG_DISABLED
1338
- START_ONLY_IF_IDLE = TASK_FLAG_START_ONLY_IF_IDLE
1339
- KILL_ON_IDLE_END = TASK_FLAG_KILL_ON_IDLE_END
1340
- DONT_START_IF_ON_BATTERIES = TASK_FLAG_DONT_START_IF_ON_BATTERIES
1341
- KILL_IF_GOING_ON_BATTERIES = TASK_FLAG_KILL_IF_GOING_ON_BATTERIES
1342
- RUN_ONLY_IF_DOCKED = TASK_FLAG_RUN_ONLY_IF_DOCKED
1343
- HIDDEN = TASK_FLAG_HIDDEN
1344
- RUN_IF_CONNECTED_TO_INTERNET = TASK_FLAG_RUN_IF_CONNECTED_TO_INTERNET
1345
- RESTART_ON_IDLE_RESUME = TASK_FLAG_RESTART_ON_IDLE_RESUME
1346
- SYSTEM_REQUIRED = TASK_FLAG_SYSTEM_REQUIRED
1347
- RUN_ONLY_IF_LOGGED_ON = TASK_FLAG_RUN_ONLY_IF_LOGGED_ON
1252
+ settings_hash["IdleSettings"] = idle_settings
1253
+ settings_hash["NetworkSettings"] = network_settings
1254
+ symbolize_keys(settings_hash)
1255
+ end
1348
1256
 
1349
- FLAG_HAS_END_DATE = TASK_TRIGGER_FLAG_HAS_END_DATE
1350
- FLAG_KILL_AT_DURATION_END = TASK_TRIGGER_FLAG_KILL_AT_DURATION_END
1351
- FLAG_DISABLED = TASK_TRIGGER_FLAG_DISABLED
1257
+ # Returns a hash of idle settings of the current task
1258
+ def idle_settings
1259
+ check_for_active_task
1260
+ settings_hash = {}
1261
+ @task.Definition.Settings.IdleSettings.ole_get_methods.each do |setting|
1262
+ settings_hash[setting.name] = @task.Definition.Settings.IdleSettings._getproperty(setting.dispid, [], [])
1263
+ end
1264
+ symbolize_keys(settings_hash)
1265
+ end
1352
1266
 
1353
- MAX_RUN_TIMES = TASK_MAX_RUN_TIMES
1267
+ # Returns a hash of network settings of the current task
1268
+ def network_settings
1269
+ check_for_active_task
1270
+ settings_hash = {}
1271
+ @task.Definition.Settings.NetworkSettings.ole_get_methods.each do |setting|
1272
+ settings_hash[setting.name] = @task.Definition.Settings.NetworkSettings._getproperty(setting.dispid, [], [])
1273
+ end
1274
+ symbolize_keys(settings_hash)
1275
+ end
1354
1276
 
1355
1277
  private
1356
1278
 
1279
+ # Returns a camle-case string to its underscore format
1280
+ def underscore(string)
1281
+ string.gsub(/([a-z\d])([A-Z])/, '\1_\2'.freeze).downcase
1282
+ end
1283
+
1284
+ # Converts all the keys of a hash to underscored-symbol format
1285
+ def symbolize_keys(hash)
1286
+ hash.each_with_object({}) do |(k, v), h|
1287
+ h[underscore(k.to_s).to_sym] = v.is_a?(Hash) ? symbolize_keys(v) : v
1288
+ end
1289
+ end
1290
+
1291
+ def valid_trigger_option(trigger_type)
1292
+ [ TASK_TIME_TRIGGER_ONCE, TASK_TIME_TRIGGER_DAILY, TASK_TIME_TRIGGER_WEEKLY,
1293
+ TASK_TIME_TRIGGER_MONTHLYDATE, TASK_TIME_TRIGGER_MONTHLYDOW, TASK_EVENT_TRIGGER_ON_IDLE,
1294
+ TASK_EVENT_TRIGGER_AT_SYSTEMSTART, TASK_EVENT_TRIGGER_AT_LOGON ].include?(trigger_type.to_i)
1295
+ end
1296
+
1357
1297
  def validate_trigger(hash)
1358
1298
  [:start_year, :start_month, :start_day].each{ |key|
1359
1299
  raise ArgumentError, "#{key} must be set" unless hash[key]
@@ -1380,4 +1320,5 @@ module Win32
1380
1320
  raise Error, ole_error(method_name, err)
1381
1321
  end
1382
1322
  end
1323
+ # :stopdoc:
1383
1324
  end