win32-taskscheduler 2.0.1 → 2.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/win32-taskscheduler.rb +1 -1
- data/lib/win32/taskscheduler.rb +266 -292
- data/lib/win32/taskscheduler/constants.rb +6 -6
- data/lib/win32/taskscheduler/helper.rb +10 -10
- data/lib/win32/taskscheduler/sid.rb +12 -12
- data/lib/win32/taskscheduler/time_calc_helper.rb +71 -40
- data/lib/win32/taskscheduler/version.rb +1 -1
- metadata +5 -53
- data/CHANGELOG.md +0 -184
- data/Gemfile +0 -3
- data/README.md +0 -78
- data/RELEASE_NOTES.md +0 -14
- data/Rakefile +0 -38
- data/VERSION +0 -1
- data/appveyor.yml +0 -40
- data/examples/taskscheduler_example.rb +0 -54
- data/spec/functional/win32/taskscheduler/time_calc_helper_spec.rb +0 -392
- data/spec/functional/win32/taskscheduler_spec.rb +0 -883
- data/spec/spec_helper.rb +0 -224
- data/spec/unit/win32/taskscheduler/constants_spec.rb +0 -20
- data/spec/unit/win32/taskscheduler/time_calc_helper_spec.rb +0 -217
- data/spec/unit/win32/taskscheduler_spec.rb +0 -169
- data/test/test_taskscheduler.rb +0 -690
- data/win32-taskscheduler.gemspec +0 -34
data/spec/spec_helper.rb
DELETED
@@ -1,224 +0,0 @@
|
|
1
|
-
libx = File.expand_path('lib', __dir__)
|
2
|
-
$LOAD_PATH.unshift(libx) unless $LOAD_PATH.include?(libx)
|
3
|
-
|
4
|
-
require 'date'
|
5
|
-
|
6
|
-
# In order to test some dummy task and folder, we are creating
|
7
|
-
# 'Test' folder and consider it as 'root'.
|
8
|
-
# After the test case, all the above created elements
|
9
|
-
# i.e, 'Test', Tasks and nested folders will be deleted.
|
10
|
-
# It will ensure No Harm be caused to any existing tasks at root
|
11
|
-
|
12
|
-
# Creating folder 'Test'; This will be treated as root
|
13
|
-
def create_test_folder
|
14
|
-
@service ||= service
|
15
|
-
@root_path = '\\'
|
16
|
-
@test_path = '\\Test'
|
17
|
-
@root_folder = @service.GetFolder(@root_path)
|
18
|
-
@test_folder = @root_folder.CreateFolder(@test_path)
|
19
|
-
@ts.instance_variable_set(:@root, @test_folder) if @ts
|
20
|
-
end
|
21
|
-
|
22
|
-
# Deleting the test folder its nested folder(if any)
|
23
|
-
# And the tasks within(if any)
|
24
|
-
def clear_them
|
25
|
-
if @test_folder
|
26
|
-
delete_all(@test_folder)
|
27
|
-
else
|
28
|
-
@test_folder = nil
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
# Logic to delete tasks and folder using Win32OLE methods
|
33
|
-
def delete_all(folder)
|
34
|
-
delete_tasks_in(folder)
|
35
|
-
folder.GetFolders(0).each do |nested_folder|
|
36
|
-
delete_all(nested_folder)
|
37
|
-
end
|
38
|
-
@root_folder.DeleteFolder(folder.Path, 0)
|
39
|
-
end
|
40
|
-
|
41
|
-
# Deleting the task in specified folder using Win32OLE methods
|
42
|
-
def delete_tasks_in(folder)
|
43
|
-
folder.GetTasks(0).each do |task|
|
44
|
-
folder.DeleteTask(task.Name, 0)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
# Returns Win32 Service object
|
49
|
-
def service
|
50
|
-
service = WIN32OLE.new('Schedule.Service')
|
51
|
-
service.Connect
|
52
|
-
service
|
53
|
-
end
|
54
|
-
|
55
|
-
# Returns no of task in the specified folder
|
56
|
-
def no_of_tasks(folder = @test_folder)
|
57
|
-
if folder.is_a?(String)
|
58
|
-
folder = @test_path + folder
|
59
|
-
folder = @service.GetFolder(folder)
|
60
|
-
end
|
61
|
-
folder.GetTasks(0).Count
|
62
|
-
end
|
63
|
-
|
64
|
-
# Steps to create (Register) a task
|
65
|
-
# This is an example activity to test
|
66
|
-
# the related functionalities over a task in RSpecs
|
67
|
-
def create_task
|
68
|
-
return nil unless @service
|
69
|
-
@task_definition = @service.NewTask(0)
|
70
|
-
task_registration
|
71
|
-
task_prinicipals
|
72
|
-
task_settings
|
73
|
-
task_triggers
|
74
|
-
task_action
|
75
|
-
register_task
|
76
|
-
end
|
77
|
-
|
78
|
-
def task_registration
|
79
|
-
reg_info = @task_definition.RegistrationInfo
|
80
|
-
reg_info.Description = 'Sample task for testing purpose'
|
81
|
-
reg_info.Author = 'Rspec'
|
82
|
-
end
|
83
|
-
|
84
|
-
def task_prinicipals
|
85
|
-
principal = @task_definition.Principal
|
86
|
-
principal.LogonType = 3 # Interactive Logon
|
87
|
-
end
|
88
|
-
|
89
|
-
def task_settings
|
90
|
-
settings = @task_definition.Settings
|
91
|
-
settings.Enabled = true
|
92
|
-
settings.StartWhenAvailable = true
|
93
|
-
settings.Hidden = false
|
94
|
-
end
|
95
|
-
|
96
|
-
def task_triggers
|
97
|
-
triggers = @task_definition.Triggers
|
98
|
-
trigger = triggers.Create(1) # Time
|
99
|
-
start_time, end_time = start_end_time
|
100
|
-
trigger.StartBoundary = start_time
|
101
|
-
trigger.EndBoundary = end_time
|
102
|
-
trigger.ExecutionTimeLimit = 'PT5M' # Five minutes
|
103
|
-
trigger.Id = 'TimeTriggerId'
|
104
|
-
trigger.Enabled = true
|
105
|
-
end
|
106
|
-
|
107
|
-
def task_action
|
108
|
-
action = @task_definition.Actions.Create(0)
|
109
|
-
action.Path = @app
|
110
|
-
end
|
111
|
-
|
112
|
-
# Registering(Creating) a task in test folder
|
113
|
-
def register_task
|
114
|
-
@current_task = @test_folder.RegisterTaskDefinition(
|
115
|
-
@task, # Name of the task
|
116
|
-
@task_definition, # Definition
|
117
|
-
6, # Flag: TASK_CREATE_OR_UPDATE
|
118
|
-
nil, # UserId
|
119
|
-
nil, # Password
|
120
|
-
3
|
121
|
-
)
|
122
|
-
@ts.instance_variable_set(:@task, @current_task) if @ts
|
123
|
-
end
|
124
|
-
|
125
|
-
def start_end_time
|
126
|
-
t = Date.new(2010)
|
127
|
-
start_time = t.strftime('%FT%T')
|
128
|
-
end_time = (t + 5).strftime('%FT%T') # 5 Days
|
129
|
-
[start_time, end_time]
|
130
|
-
end
|
131
|
-
|
132
|
-
def tasksch_err
|
133
|
-
Win32::TaskScheduler::Error
|
134
|
-
end
|
135
|
-
|
136
|
-
# Methods to build all types of triggers and their values
|
137
|
-
|
138
|
-
def all_triggers
|
139
|
-
all_triggers = {}
|
140
|
-
|
141
|
-
%w[ONCE DAILY WEEKLY MONTHLYDATE MONTHLYDOW
|
142
|
-
ON_IDLE AT_SYSTEMSTART AT_LOGON].each do |trig_type|
|
143
|
-
trigger = {}
|
144
|
-
trigger[:trigger_type] = Win32::TaskScheduler.class_eval(trig_type)
|
145
|
-
start_end_params(trigger)
|
146
|
-
other_trigger_params(trig_type, trigger)
|
147
|
-
all_triggers[trig_type] = trigger
|
148
|
-
end
|
149
|
-
|
150
|
-
all_triggers
|
151
|
-
end
|
152
|
-
|
153
|
-
def start_end_params(trigger)
|
154
|
-
%i[start_year end_year].each do |t|
|
155
|
-
trigger[t] = '2030'
|
156
|
-
end
|
157
|
-
|
158
|
-
%i[start_month start_day start_hour start_minute].each do |t|
|
159
|
-
trigger[t] = '02'
|
160
|
-
end
|
161
|
-
|
162
|
-
%i[end_day end_month].each do |t|
|
163
|
-
trigger[t] = '03'
|
164
|
-
end
|
165
|
-
|
166
|
-
%i[minutes_duration minutes_interval].each do |t|
|
167
|
-
trigger[t] = 2
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
def other_trigger_params(trig_type, trigger)
|
172
|
-
type = {}
|
173
|
-
case trig_type
|
174
|
-
when 'ONCE'
|
175
|
-
trigger[:type] = type
|
176
|
-
type[:once] = nil
|
177
|
-
trigger[:random_minutes_interval] = 2
|
178
|
-
when 'DAILY'
|
179
|
-
trigger[:type] = type
|
180
|
-
type[:days_interval] = 2
|
181
|
-
trigger[:random_minutes_interval] = 2
|
182
|
-
when 'WEEKLY'
|
183
|
-
trigger[:type] = type
|
184
|
-
type[:weeks_interval] = 2
|
185
|
-
type[:days_of_week] = sunday
|
186
|
-
trigger[:random_minutes_interval] = 2
|
187
|
-
when 'MONTHLYDATE'
|
188
|
-
trigger[:type] = type
|
189
|
-
type[:months] = january
|
190
|
-
type[:days] = first_day
|
191
|
-
trigger[:run_on_last_day_of_month] = false
|
192
|
-
trigger[:random_minutes_interval] = 2
|
193
|
-
when 'MONTHLYDOW'
|
194
|
-
trigger[:type] = type
|
195
|
-
type[:months] = january
|
196
|
-
type[:days_of_week] = sunday
|
197
|
-
type[:weeks_of_month] = first_week
|
198
|
-
trigger[:run_on_last_week_of_month] = false
|
199
|
-
trigger[:random_minutes_interval] = 2
|
200
|
-
when 'ON_IDLE'
|
201
|
-
trigger[:execution_time_limit] = 2
|
202
|
-
when 'AT_SYSTEMSTART'
|
203
|
-
trigger[:delay_duration] = 2
|
204
|
-
when 'AT_LOGON'
|
205
|
-
trigger[:user_id] = 'SYSTEM'
|
206
|
-
trigger[:delay_duration] = 2
|
207
|
-
end
|
208
|
-
end
|
209
|
-
|
210
|
-
def sunday
|
211
|
-
Win32::TaskScheduler::SUNDAY
|
212
|
-
end
|
213
|
-
|
214
|
-
def january
|
215
|
-
Win32::TaskScheduler::JANUARY
|
216
|
-
end
|
217
|
-
|
218
|
-
def first_day
|
219
|
-
Win32::TaskScheduler::FIRST
|
220
|
-
end
|
221
|
-
|
222
|
-
def first_week
|
223
|
-
Win32::TaskScheduler::FIRST_WEEK
|
224
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'win32/taskscheduler'
|
3
|
-
require 'win32/taskscheduler/constants'
|
4
|
-
|
5
|
-
RSpec.describe Win32::TaskScheduler, :windows_only do
|
6
|
-
describe 'Ensuring trigger constants' do
|
7
|
-
subject(:ts) { Win32::TaskScheduler }
|
8
|
-
describe 'to handle scheduled tasks' do
|
9
|
-
[:ONCE, :DAILY, :WEEKLY, :MONTHLYDATE, :MONTHLYDOW].each do |const|
|
10
|
-
it { should be_const_defined(const) }
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
describe 'to handle other types' do
|
15
|
-
[:AT_LOGON, :AT_SYSTEMSTART, :ON_IDLE].each do |const|
|
16
|
-
it { should be_const_defined(const) }
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
@@ -1,217 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'win32/taskscheduler/time_calc_helper'
|
3
|
-
|
4
|
-
RSpec.describe Win32::TaskScheduler::TimeCalcHelper do
|
5
|
-
let(:object) { klass.new }
|
6
|
-
let(:klass) do
|
7
|
-
Class.new do
|
8
|
-
include Win32::TaskScheduler::TimeCalcHelper
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
describe '#is_leap_year?' do
|
13
|
-
it 'require an year in integer format' do
|
14
|
-
expect { object.is_leap_year? }.to raise_error(ArgumentError)
|
15
|
-
expect { object.is_leap_year?('year') }.to raise_error(NoMethodError)
|
16
|
-
end
|
17
|
-
|
18
|
-
it 'returns true for leap years' do
|
19
|
-
year = 2000
|
20
|
-
expect(object.is_leap_year?(year)).to be_truthy
|
21
|
-
year = 2004
|
22
|
-
expect(object.is_leap_year?(year)).to be_truthy
|
23
|
-
end
|
24
|
-
|
25
|
-
it 'returns false for non-leap years' do
|
26
|
-
year = 1900
|
27
|
-
expect(object.is_leap_year?(year)).to be_falsy
|
28
|
-
year = 2001
|
29
|
-
expect(object.is_leap_year?(year)).to be_falsy
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
describe '#days_in_month' do
|
34
|
-
it 'require month and year in integer format' do
|
35
|
-
expect { object.days_in_month }.to raise_error(ArgumentError)
|
36
|
-
expect { object.days_in_month('month', 'year') }.to raise_error(TypeError)
|
37
|
-
end
|
38
|
-
|
39
|
-
context 'leap year' do
|
40
|
-
year = 2000
|
41
|
-
it 'January will have 31 days' do
|
42
|
-
month = 1
|
43
|
-
expect(object.days_in_month(month, year)).to eql(31)
|
44
|
-
end
|
45
|
-
|
46
|
-
it 'February will have 29 days' do
|
47
|
-
month = 2
|
48
|
-
expect(object.days_in_month(month, year)).to eql(29)
|
49
|
-
end
|
50
|
-
|
51
|
-
it 'November will have 30 days' do
|
52
|
-
month = 11
|
53
|
-
expect(object.days_in_month(month, year)).to eql(30)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
context 'non-leap year' do
|
58
|
-
year = 2003
|
59
|
-
it 'January will have 31 days' do
|
60
|
-
month = 1
|
61
|
-
expect(object.days_in_month(month, year)).to eql(31)
|
62
|
-
end
|
63
|
-
|
64
|
-
it 'February will have 28 days' do
|
65
|
-
month = 2
|
66
|
-
expect(object.days_in_month(month, year)).to eql(28)
|
67
|
-
end
|
68
|
-
|
69
|
-
it 'November will have 30 days' do
|
70
|
-
month = 11
|
71
|
-
expect(object.days_in_month(month, year)).to eql(30)
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
describe '#time_details' do
|
77
|
-
it 'require a time string in String format' do
|
78
|
-
expect { object.time_details }.to raise_error(ArgumentError)
|
79
|
-
expect { object.time_details(1234) }.to raise_error(TypeError)
|
80
|
-
end
|
81
|
-
|
82
|
-
it 'returns an empty hash if no string is passed' do
|
83
|
-
expect(object.time_details(nil)).to be_a(Hash)
|
84
|
-
expect(object.time_details(nil)).to be_empty
|
85
|
-
end
|
86
|
-
|
87
|
-
context 'of MSDN time string' do
|
88
|
-
it 'returns hash with date' do
|
89
|
-
time_str = 'P10Y10M10D'
|
90
|
-
time_hsh = { year: '10', month: '10', day: '10' }
|
91
|
-
expect(object.time_details(time_str)).to eq(time_hsh)
|
92
|
-
end
|
93
|
-
|
94
|
-
it 'returns hash with time' do
|
95
|
-
time_str = 'PT10H10M10S'
|
96
|
-
time_hsh = { hour: '10', min: '10', sec: '10' }
|
97
|
-
expect(object.time_details(time_str)).to eq(time_hsh)
|
98
|
-
end
|
99
|
-
|
100
|
-
it 'returns hash with date-time' do
|
101
|
-
time_str = 'P10Y10M10DT10H10M10S'
|
102
|
-
time_hsh = { year: '10', month: '10', day: '10',
|
103
|
-
hour: '10', min: '10', sec: '10' }
|
104
|
-
expect(object.time_details(time_str)).to eq(time_hsh)
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
describe '#time_in_seconds' do
|
110
|
-
it 'require a time string in String format' do
|
111
|
-
expect { object.time_in_seconds }.to raise_error(ArgumentError)
|
112
|
-
expect { object.time_in_seconds(1234) }.to raise_error(TypeError)
|
113
|
-
end
|
114
|
-
|
115
|
-
it 'returns zero if no string is passed' do
|
116
|
-
expect(object.time_in_seconds(nil)).to be_zero
|
117
|
-
end
|
118
|
-
|
119
|
-
context 'in leap year' do
|
120
|
-
before do
|
121
|
-
time_now = Time.new(2004)
|
122
|
-
allow(Time).to receive(:now).and_return(time_now)
|
123
|
-
end
|
124
|
-
|
125
|
-
it 'returns seconds for date' do
|
126
|
-
time_str = 'P10Y10M10D'
|
127
|
-
expect(object.time_in_seconds(time_str)).to eq(342_748_800)
|
128
|
-
end
|
129
|
-
|
130
|
-
it 'returns seconds for time' do
|
131
|
-
time_str = 'PT10H10M10S'
|
132
|
-
expect(object.time_in_seconds(time_str)).to eq(36_610)
|
133
|
-
end
|
134
|
-
|
135
|
-
it 'returns seconds for date-time' do
|
136
|
-
time_str = 'P10Y10M10DT10H10M10S'
|
137
|
-
expect(object.time_in_seconds(time_str)).to eq(342_785_410)
|
138
|
-
end
|
139
|
-
end
|
140
|
-
context 'in non-leap year' do
|
141
|
-
before do
|
142
|
-
time_now = Time.new(2003)
|
143
|
-
allow(Time).to receive(:now).and_return(time_now)
|
144
|
-
end
|
145
|
-
|
146
|
-
it 'returns seconds for date' do
|
147
|
-
time_str = 'P10Y10M10D'
|
148
|
-
expect(object.time_in_seconds(time_str)).to eq(342_748_800)
|
149
|
-
end
|
150
|
-
|
151
|
-
it 'returns seconds for time' do
|
152
|
-
time_str = 'PT10H10M10S'
|
153
|
-
expect(object.time_in_seconds(time_str)).to eq(36_610)
|
154
|
-
end
|
155
|
-
|
156
|
-
it 'returns seconds for date-time' do
|
157
|
-
time_str = 'P10Y10M10DT10H10M10S'
|
158
|
-
expect(object.time_in_seconds(time_str)).to eq(342_785_410)
|
159
|
-
end
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
163
|
-
describe '#time_in_minutes' do
|
164
|
-
it 'require a time string in String format' do
|
165
|
-
expect { object.time_in_minutes }.to raise_error(ArgumentError)
|
166
|
-
expect { object.time_in_minutes(1234) }.to raise_error(TypeError)
|
167
|
-
end
|
168
|
-
|
169
|
-
it 'returns zero if no string is passed' do
|
170
|
-
expect(object.time_in_minutes(nil)).to be_zero
|
171
|
-
end
|
172
|
-
|
173
|
-
context 'in leap year' do
|
174
|
-
before do
|
175
|
-
time_now = Time.new(2004)
|
176
|
-
allow(Time).to receive(:now).and_return(time_now)
|
177
|
-
end
|
178
|
-
|
179
|
-
it 'returns minutes for date' do
|
180
|
-
time_str = 'P10Y10M10D'
|
181
|
-
expect(object.time_in_minutes(time_str)).to eq(5_712_480)
|
182
|
-
end
|
183
|
-
|
184
|
-
it 'returns minutes for time' do
|
185
|
-
time_str = 'PT10H10M10S'
|
186
|
-
expect(object.time_in_minutes(time_str)).to eq(610)
|
187
|
-
end
|
188
|
-
|
189
|
-
it 'returns minutes for date-time' do
|
190
|
-
time_str = 'P10Y10M10DT10H10M10S'
|
191
|
-
expect(object.time_in_minutes(time_str)).to eq(5_713_090)
|
192
|
-
end
|
193
|
-
end
|
194
|
-
|
195
|
-
context 'in non-leap year' do
|
196
|
-
before do
|
197
|
-
time_now = Time.new(2003)
|
198
|
-
allow(Time).to receive(:now).and_return(time_now)
|
199
|
-
end
|
200
|
-
|
201
|
-
it 'returns minutes for date' do
|
202
|
-
time_str = 'P10Y10M10D'
|
203
|
-
expect(object.time_in_minutes(time_str)).to eq(5_712_480)
|
204
|
-
end
|
205
|
-
|
206
|
-
it 'returns minutes for time' do
|
207
|
-
time_str = 'PT10H10M10S'
|
208
|
-
expect(object.time_in_minutes(time_str)).to eq(610)
|
209
|
-
end
|
210
|
-
|
211
|
-
it 'returns minutes for date-time' do
|
212
|
-
time_str = 'P10Y10M10DT10H10M10S'
|
213
|
-
expect(object.time_in_minutes(time_str)).to eq(5_713_090)
|
214
|
-
end
|
215
|
-
end
|
216
|
-
end
|
217
|
-
end
|