win32-taskscheduler 2.0.1 → 2.0.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|