win32-taskscheduler 0.3.2 → 0.4.0

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 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