Class: Win32::TaskScheduler

Inherits:
Object
  • Object
show all
Includes:
Helper, SID, TaskSchedulerConstants, TimeCalcHelper
Defined in:
lib/win32/taskscheduler.rb,
lib/win32/taskscheduler/sid.rb,
lib/win32/taskscheduler/helper.rb,
lib/win32/taskscheduler/version.rb,
lib/win32/taskscheduler/constants.rb,
lib/win32/taskscheduler/time_calc_helper.rb

Overview

The TaskScheduler class encapsulates a Windows scheduled task

Defined Under Namespace

Modules: Helper, SID, TaskSchedulerConstants, TimeCalcHelper Classes: Error

Constant Summary collapse

IDLE =

Shorthand constants

IDLE_PRIORITY_CLASS
NORMAL =
NORMAL_PRIORITY_CLASS
HIGH =
HIGH_PRIORITY_CLASS
REALTIME =
REALTIME_PRIORITY_CLASS
BELOW_NORMAL =
BELOW_NORMAL_PRIORITY_CLASS
ABOVE_NORMAL =
ABOVE_NORMAL_PRIORITY_CLASS
ONCE =
TASK_TIME_TRIGGER_ONCE
DAILY =
TASK_TIME_TRIGGER_DAILY
WEEKLY =
TASK_TIME_TRIGGER_WEEKLY
MONTHLYDATE =
TASK_TIME_TRIGGER_MONTHLYDATE
MONTHLYDOW =
TASK_TIME_TRIGGER_MONTHLYDOW
ON_IDLE =
TASK_EVENT_TRIGGER_ON_IDLE
AT_SYSTEMSTART =
TASK_EVENT_TRIGGER_AT_SYSTEMSTART
AT_LOGON =
TASK_EVENT_TRIGGER_AT_LOGON
FIRST_WEEK =
TASK_FIRST_WEEK
SECOND_WEEK =
TASK_SECOND_WEEK
THIRD_WEEK =
TASK_THIRD_WEEK
FOURTH_WEEK =
TASK_FOURTH_WEEK
LAST_WEEK =
TASK_LAST_WEEK
SUNDAY =
TASK_SUNDAY
MONDAY =
TASK_MONDAY
TUESDAY =
TASK_TUESDAY
WEDNESDAY =
TASK_WEDNESDAY
THURSDAY =
TASK_THURSDAY
FRIDAY =
TASK_FRIDAY
SATURDAY =
TASK_SATURDAY
JANUARY =
TASK_JANUARY
FEBRUARY =
TASK_FEBRUARY
MARCH =
TASK_MARCH
APRIL =
TASK_APRIL
MAY =
TASK_MAY
JUNE =
TASK_JUNE
JULY =
TASK_JULY
AUGUST =
TASK_AUGUST
SEPTEMBER =
TASK_SEPTEMBER
OCTOBER =
TASK_OCTOBER
NOVEMBER =
TASK_NOVEMBER
DECEMBER =
TASK_DECEMBER
INTERACTIVE =
TASK_FLAG_INTERACTIVE
DELETE_WHEN_DONE =
TASK_FLAG_DELETE_WHEN_DONE
DISABLED =
TASK_FLAG_DISABLED
START_ONLY_IF_IDLE =
TASK_FLAG_START_ONLY_IF_IDLE
KILL_ON_IDLE_END =
TASK_FLAG_KILL_ON_IDLE_END
DONT_START_IF_ON_BATTERIES =
TASK_FLAG_DONT_START_IF_ON_BATTERIES
KILL_IF_GOING_ON_BATTERIES =
TASK_FLAG_KILL_IF_GOING_ON_BATTERIES
RUN_ONLY_IF_DOCKED =
TASK_FLAG_RUN_ONLY_IF_DOCKED
HIDDEN =
TASK_FLAG_HIDDEN
RUN_IF_CONNECTED_TO_INTERNET =
TASK_FLAG_RUN_IF_CONNECTED_TO_INTERNET
RESTART_ON_IDLE_RESUME =
TASK_FLAG_RESTART_ON_IDLE_RESUME
SYSTEM_REQUIRED =
TASK_FLAG_SYSTEM_REQUIRED
RUN_ONLY_IF_LOGGED_ON =
TASK_FLAG_RUN_ONLY_IF_LOGGED_ON
FLAG_HAS_END_DATE =
TASK_TRIGGER_FLAG_HAS_END_DATE
FLAG_KILL_AT_DURATION_END =
TASK_TRIGGER_FLAG_KILL_AT_DURATION_END
FLAG_DISABLED =
TASK_TRIGGER_FLAG_DISABLED
MAX_RUN_TIMES =
TASK_MAX_RUN_TIMES
FIRST =
TASK_FIRST
SECOND =
TASK_SECOND
THIRD =
TASK_THIRD
FOURTH =
TASK_FOURTH
FIFTH =
TASK_FIFTH
SIXTH =
TASK_SIXTH
SEVENTH =
TASK_SEVENTH
EIGHTH =
TASK_EIGHTH
NINETH =
TASK_NINETH
TENTH =
TASK_TENTH
ELEVENTH =
TASK_ELEVENTH
TWELFTH =
TASK_TWELFTH
THIRTEENTH =
TASK_THIRTEENTH
FOURTEENTH =
TASK_FOURTEENTH
FIFTEENTH =
TASK_FIFTEENTH
SIXTEENTH =
TASK_SIXTEENTH
SEVENTEENTH =
TASK_SEVENTEENTH
EIGHTEENTH =
TASK_EIGHTEENTH
NINETEENTH =
TASK_NINETEENTH
TWENTIETH =
TASK_TWENTIETH
TWENTY_FIRST =
TASK_TWENTY_FIRST
TWENTY_SECOND =
TASK_TWENTY_SECOND
TWENTY_THIRD =
TASK_TWENTY_THIRD
TWENTY_FOURTH =
TASK_TWENTY_FOURTH
TWENTY_FIFTH =
TASK_TWENTY_FIFTH
TWENTY_SIXTH =
TASK_TWENTY_SIXTH
TWENTY_SEVENTH =
TASK_TWENTY_SEVENTH
TWENTY_EIGHTH =
TASK_TWENTY_EIGHTH
TWENTY_NINTH =
TASK_TWENTY_NINTH
THIRTYETH =
TASK_THIRTYETH
THIRTY_FIRST =
TASK_THIRTY_FIRST
LAST =
TASK_LAST
IdleSettings =

The Idle settings of a task

%i{idle_duration restart_on_idle stop_on_idle_end wait_timeout}.freeze
VERSION =

The version of the win32-taskscheduler library

"2.0.4".freeze

Constants included from SID

SID::BUILT_IN_GROUPS, SID::ERROR_INSUFFICIENT_BUFFER, SID::SERVICE_ACCOUNT_USERS

Constants included from Helper

Helper::FORMAT_MESSAGE_FROM_SYSTEM, Helper::FORMAT_MESSAGE_IGNORE_INSERTS, Helper::FORMAT_MESSAGE_MAX_WIDTH_MASK

Constants included from TimeCalcHelper

TimeCalcHelper::DAYS_IN_A_MONTH

Constants included from TaskSchedulerConstants

TaskSchedulerConstants::ABOVE_NORMAL_PRIORITY_CLASS, TaskSchedulerConstants::BELOW_NORMAL_PRIORITY_CLASS, TaskSchedulerConstants::BUILT_IN_GROUPS, TaskSchedulerConstants::CLSCTX_INPROC_SERVER, TaskSchedulerConstants::CLSID_CTask, TaskSchedulerConstants::CLSID_CTaskScheduler, TaskSchedulerConstants::HIGH_PRIORITY_CLASS, TaskSchedulerConstants::IDLE_PRIORITY_CLASS, TaskSchedulerConstants::IID_IPersistFile, TaskSchedulerConstants::IID_ITask, TaskSchedulerConstants::IID_ITaskScheduler, TaskSchedulerConstants::NORMAL_PRIORITY_CLASS, TaskSchedulerConstants::REALTIME_PRIORITY_CLASS, TaskSchedulerConstants::SERVICE_ACCOUNT_USERS, TaskSchedulerConstants::SYSTEM_USERS, TaskSchedulerConstants::TASKS_TO_RETRIEVE, TaskSchedulerConstants::TASK_APRIL, TaskSchedulerConstants::TASK_AUGUST, TaskSchedulerConstants::TASK_CREATE, TaskSchedulerConstants::TASK_CREATE_OR_UPDATE, TaskSchedulerConstants::TASK_DECEMBER, TaskSchedulerConstants::TASK_DISABLE, TaskSchedulerConstants::TASK_DONT_ADD_PRINCIPAL_ACE, TaskSchedulerConstants::TASK_EIGHTEENTH, TaskSchedulerConstants::TASK_EIGHTH, TaskSchedulerConstants::TASK_ELEVENTH, TaskSchedulerConstants::TASK_EVENT_TRIGGER_AT_LOGON, TaskSchedulerConstants::TASK_EVENT_TRIGGER_AT_SYSTEMSTART, TaskSchedulerConstants::TASK_EVENT_TRIGGER_ON_IDLE, TaskSchedulerConstants::TASK_FEBRUARY, TaskSchedulerConstants::TASK_FIFTEENTH, TaskSchedulerConstants::TASK_FIFTH, TaskSchedulerConstants::TASK_FIRST, TaskSchedulerConstants::TASK_FIRST_WEEK, TaskSchedulerConstants::TASK_FLAG_DELETE_WHEN_DONE, TaskSchedulerConstants::TASK_FLAG_DISABLED, TaskSchedulerConstants::TASK_FLAG_DONT_START_IF_ON_BATTERIES, TaskSchedulerConstants::TASK_FLAG_HIDDEN, TaskSchedulerConstants::TASK_FLAG_INTERACTIVE, TaskSchedulerConstants::TASK_FLAG_KILL_IF_GOING_ON_BATTERIES, TaskSchedulerConstants::TASK_FLAG_KILL_ON_IDLE_END, TaskSchedulerConstants::TASK_FLAG_RESTART_ON_IDLE_RESUME, TaskSchedulerConstants::TASK_FLAG_RUN_IF_CONNECTED_TO_INTERNET, TaskSchedulerConstants::TASK_FLAG_RUN_ONLY_IF_DOCKED, TaskSchedulerConstants::TASK_FLAG_RUN_ONLY_IF_LOGGED_ON, TaskSchedulerConstants::TASK_FLAG_START_ONLY_IF_IDLE, TaskSchedulerConstants::TASK_FLAG_SYSTEM_REQUIRED, TaskSchedulerConstants::TASK_FOURTEENTH, TaskSchedulerConstants::TASK_FOURTH, TaskSchedulerConstants::TASK_FOURTH_WEEK, TaskSchedulerConstants::TASK_FRIDAY, TaskSchedulerConstants::TASK_IGNORE_REGISTRATION_TRIGGERS, TaskSchedulerConstants::TASK_JANUARY, TaskSchedulerConstants::TASK_JULY, TaskSchedulerConstants::TASK_JUNE, TaskSchedulerConstants::TASK_LAST, TaskSchedulerConstants::TASK_LAST_WEEK, TaskSchedulerConstants::TASK_LOGON_GROUP, TaskSchedulerConstants::TASK_LOGON_INTERACTIVE_TOKEN, TaskSchedulerConstants::TASK_LOGON_INTERACTIVE_TOKEN_OR_PASSWORD, TaskSchedulerConstants::TASK_LOGON_NONE, TaskSchedulerConstants::TASK_LOGON_PASSWORD, TaskSchedulerConstants::TASK_LOGON_S4U, TaskSchedulerConstants::TASK_LOGON_SERVICE_ACCOUNT, TaskSchedulerConstants::TASK_MARCH, TaskSchedulerConstants::TASK_MAX_RUN_TIMES, TaskSchedulerConstants::TASK_MAY, TaskSchedulerConstants::TASK_MONDAY, TaskSchedulerConstants::TASK_NINETEENTH, TaskSchedulerConstants::TASK_NINETH, TaskSchedulerConstants::TASK_NOVEMBER, TaskSchedulerConstants::TASK_OCTOBER, TaskSchedulerConstants::TASK_RUNLEVEL_HIGHEST, TaskSchedulerConstants::TASK_RUNLEVEL_LUA, TaskSchedulerConstants::TASK_SATURDAY, TaskSchedulerConstants::TASK_SECOND, TaskSchedulerConstants::TASK_SECOND_WEEK, TaskSchedulerConstants::TASK_SEPTEMBER, TaskSchedulerConstants::TASK_SEVENTEENTH, TaskSchedulerConstants::TASK_SEVENTH, TaskSchedulerConstants::TASK_SIXTEENTH, TaskSchedulerConstants::TASK_SIXTH, TaskSchedulerConstants::TASK_SUNDAY, TaskSchedulerConstants::TASK_TENTH, TaskSchedulerConstants::TASK_THIRD, TaskSchedulerConstants::TASK_THIRD_WEEK, TaskSchedulerConstants::TASK_THIRTEENTH, TaskSchedulerConstants::TASK_THIRTYETH, TaskSchedulerConstants::TASK_THIRTY_FIRST, TaskSchedulerConstants::TASK_THURSDAY, TaskSchedulerConstants::TASK_TIME_TRIGGER_DAILY, TaskSchedulerConstants::TASK_TIME_TRIGGER_MONTHLYDATE, TaskSchedulerConstants::TASK_TIME_TRIGGER_MONTHLYDOW, TaskSchedulerConstants::TASK_TIME_TRIGGER_ONCE, TaskSchedulerConstants::TASK_TIME_TRIGGER_WEEKLY, TaskSchedulerConstants::TASK_TRIGGER_FLAG_DISABLED, TaskSchedulerConstants::TASK_TRIGGER_FLAG_HAS_END_DATE, TaskSchedulerConstants::TASK_TRIGGER_FLAG_KILL_AT_DURATION_END, TaskSchedulerConstants::TASK_TRIGGER_REGISTRATION, TaskSchedulerConstants::TASK_TRIGGER_SESSION_STATE_CHANGE, TaskSchedulerConstants::TASK_TUESDAY, TaskSchedulerConstants::TASK_TWELFTH, TaskSchedulerConstants::TASK_TWENTIETH, TaskSchedulerConstants::TASK_TWENTY_EIGHTH, TaskSchedulerConstants::TASK_TWENTY_FIFTH, TaskSchedulerConstants::TASK_TWENTY_FIRST, TaskSchedulerConstants::TASK_TWENTY_FOURTH, TaskSchedulerConstants::TASK_TWENTY_NINTH, TaskSchedulerConstants::TASK_TWENTY_SECOND, TaskSchedulerConstants::TASK_TWENTY_SEVENTH, TaskSchedulerConstants::TASK_TWENTY_SIXTH, TaskSchedulerConstants::TASK_TWENTY_THIRD, TaskSchedulerConstants::TASK_UPDATE, TaskSchedulerConstants::TASK_VALIDATE_ONLY, TaskSchedulerConstants::TASK_WEDNESDAY

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from SID

BuiltinAdministrators, BuiltinUsers, Guests, LocalSystem, NtLocal, NtNetwork, account, account_names, from_string_sid, utf8_to_wide

Methods included from Helper

#ole_error, #win_error

Methods included from TimeCalcHelper

#days_in_month, #dt_tm_string_to_hash, #extra_days, #extra_months, #extra_time, #is_leap_year?, #time_details, #time_in_minutes, #time_in_seconds

Constructor Details

#initialize(task = nil, trigger = nil, folder = root_path, force = false) ⇒ TaskScheduler

Returns a new TaskScheduler object, attached to folder. If that folder does not exist, but the force option is set to true, then it will be created. Otherwise an error will be raised. The default is to use the root folder.

If task and trigger are present, then a new task is generated as well. This is effectively the same as .new + #new_work_item.

Raises:

  • (ArgumentError)


136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/win32/taskscheduler.rb', line 136

def initialize(task = nil, trigger = nil, folder = root_path, force = false)
  @folder = folder
  @force  = force

  @host     = Socket.gethostname
  @task     = nil
  @password = nil

  raise ArgumentError, "invalid folder" unless folder.include?('\\')

  unless [TrueClass, FalseClass].include?(force.class)
    raise TypeError, "invalid force value"
  end

  begin
    @service = WIN32OLE.new("Schedule.Service")
  rescue WIN32OLERuntimeError => err
    raise Error, err.inspect
  end

  @service.Connect

  if folder != root_path
    begin
      @root = @service.GetFolder(folder)
    rescue WIN32OLERuntimeError => err
      if force
        @root = @service.GetFolder(root_path)
        @root = @root.CreateFolder(folder)
      else
        raise ArgumentError, "folder '#{folder}' not found"
      end
    end
  else
    @root = @service.GetFolder(folder)
  end

  new_work_item(task, trigger) if task && trigger
end

Instance Attribute Details

#hostObject (readonly) Also known as: machine

Returns the value of attribute host.



122
123
124
# File 'lib/win32/taskscheduler.rb', line 122

def host
  @host
end

#passwordObject

:startdoc:



121
122
123
# File 'lib/win32/taskscheduler.rb', line 121

def password
  @password
end

Instance Method Details

#account_informationString

Returns the user or group associated with the task or nil if no one has been associated with the task yet

Returns:

  • (String)

    user or group associated with the task



342
343
344
345
346
347
348
349
350
# File 'lib/win32/taskscheduler.rb', line 342

def 
  if @task.nil?
    nil
  elsif !@task.Definition.Principal.UserId.empty?
    @task.Definition.Principal.UserId
  else
    @task.Definition.Principal.GroupId
  end
end

#activate(task) ⇒ Object

Activate the specified task.

Raises:

  • (TypeError)


240
241
242
243
244
245
246
247
248
249
250
# File 'lib/win32/taskscheduler.rb', line 240

def activate(task)
  raise TypeError unless task.is_a?(String)

  begin
    registeredTask = @root.GetTask(task)
    registeredTask.Enabled = 1
    @task = registeredTask
  rescue WIN32OLERuntimeError => err
    raise Error, ole_error("activate", err)
  end
end

#add_trigger(index, trigger) ⇒ Object

Adds a trigger at the specified index.

Raises:

  • (TypeError)


832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
# File 'lib/win32/taskscheduler.rb', line 832

def add_trigger(index, trigger)
  raise TypeError unless index.is_a?(Numeric)
  raise TypeError unless trigger.is_a?(Hash)
  raise ArgumentError, "Unknown trigger type" unless valid_trigger_option(trigger[:trigger_type])

  check_for_active_task

  definition = @task.Definition

  startTime = format("%04d-%02d-%02dT%02d:%02d:00", trigger[:start_year], trigger[:start_month], trigger[:start_day], trigger[:start_hour], trigger[:start_minute])

  # Set defaults
  trigger[:end_year]  ||= 0
  trigger[:end_month] ||= 0
  trigger[:end_day]   ||= 0

  endTime = format("%04d-%02d-%02dT00:00:00", trigger[:end_year], trigger[:end_month], trigger[:end_day])

  trig = definition.Triggers.Create(trigger[:trigger_type].to_i)
  trig.Id = "RegistrationTriggerId#{definition.Triggers.Count}"
  trig.StartBoundary = startTime if startTime != "0000-00-00T00:00:00"
  trig.EndBoundary = endTime if endTime != "0000-00-00T00:00:00"
  trig.Enabled = true

  repetitionPattern = trig.Repetition

  if trigger[:minutes_duration].to_i > 0
    repetitionPattern.Duration = "PT#{trigger[:minutes_duration] || 0}M"
  end

  if trigger[:minutes_interval].to_i > 0
    repetitionPattern.Interval = "PT#{trigger[:minutes_interval] || 0}M"
  end

  tmp = trigger[:type]
  tmp = nil unless tmp.is_a?(Hash)

  case trigger[:trigger_type]
  when TASK_TIME_TRIGGER_DAILY
    trig.DaysInterval = tmp[:days_interval] if tmp && tmp[:days_interval]
    if trigger[:random_minutes_interval].to_i > 0
      trig.RandomDelay = "PT#{trigger[:random_minutes_interval]}M"
    end
  when TASK_TIME_TRIGGER_WEEKLY
    trig.DaysOfWeek = tmp[:days_of_week] if tmp && tmp[:days_of_week]
    trig.WeeksInterval = tmp[:weeks_interval] if tmp && tmp[:weeks_interval]
    if trigger[:random_minutes_interval].to_i > 0
      trig.RandomDelay = "PT#{trigger[:random_minutes_interval] || 0}M"
    end
  when TASK_TIME_TRIGGER_MONTHLYDATE
    trig.MonthsOfYear = tmp[:months] if tmp && tmp[:months]
    trig.DaysOfMonth = tmp[:days] if tmp && tmp[:days]
    if trigger[:random_minutes_interval].to_i > 0
      trig.RandomDelay = "PT#{trigger[:random_minutes_interval] || 0}M"
    end
    trig.RunOnLastDayOfMonth = trigger[:run_on_last_day_of_month] if trigger[:run_on_last_day_of_month]
  when TASK_TIME_TRIGGER_MONTHLYDOW
    trig.MonthsOfYear = tmp[:months] if tmp && tmp[:months]
    trig.DaysOfWeek = tmp[:days_of_week] if tmp && tmp[:days_of_week]
    trig.WeeksOfMonth = tmp[:weeks_of_month] if tmp && tmp[:weeks_of_month]
    if trigger[:random_minutes_interval].to_i > 0
      trig.RandomDelay = "PT#{trigger[:random_minutes_interval] || 0}M"
    end
    trig.RunOnLastWeekOfMonth = trigger[:run_on_last_week_of_month] if trigger[:run_on_last_week_of_month]
  when TASK_TIME_TRIGGER_ONCE
    if trigger[:random_minutes_interval].to_i > 0
      trig.RandomDelay = "PT#{trigger[:random_minutes_interval] || 0}M"
    end
  when TASK_EVENT_TRIGGER_AT_SYSTEMSTART
    trig.Delay = "PT#{trigger[:delay_duration] || 0}M"
  when TASK_EVENT_TRIGGER_AT_LOGON
    trig.UserId = trigger[:user_id] if trigger[:user_id]
    trig.Delay = "PT#{trigger[:delay_duration] || 0}M"
  end

  register_task_definition(definition)

  true
end

#application_nameObject

Returns the name of the application associated with the task. If no application is associated with the task then nil is returned.



355
356
357
358
359
360
361
362
363
364
365
366
367
368
# File 'lib/win32/taskscheduler.rb', line 355

def application_name
  check_for_active_task

  app = nil

  @task.Definition.Actions.each do |action|
    if action.Type == 0 # TASK_ACTION_EXEC
      app = action.Path
      break
    end
  end

  app
end

#application_name=(app) ⇒ Object

Sets the name of the application associated with the task.

Raises:

  • (TypeError)


372
373
374
375
376
377
378
379
380
381
382
383
384
385
# File 'lib/win32/taskscheduler.rb', line 372

def application_name=(app)
  raise TypeError unless app.is_a?(String)
  check_for_active_task

  definition = @task.Definition

  definition.Actions.each do |action|
    action.Path = app if action.Type == 0
  end

  register_task_definition(definition)

  app
end

#commentObject Also known as: description

Returns the comment associated with the task, if any.



949
950
951
952
# File 'lib/win32/taskscheduler.rb', line 949

def comment
  check_for_active_task
  @task.Definition.RegistrationInfo.Description
end

#comment=(comment) ⇒ Object Also known as: description=

Sets the comment for the task.

Raises:

  • (TypeError)


958
959
960
961
962
963
964
965
966
967
# File 'lib/win32/taskscheduler.rb', line 958

def comment=(comment)
  raise TypeError unless comment.is_a?(String)
  check_for_active_task

  definition = @task.Definition
  definition.RegistrationInfo.Description = comment
  register_task_definition(definition)

  comment
end

#configure_principals(principals) ⇒ Object

Sets the principals for current active task. The principal is hash with following possible options. Expected principal hash: { id: STRING, display_name: STRING, user_id: STRING, logon_type: INTEGER, group_id: STRING, run_level: INTEGER }

Raises:

  • (TypeError)


1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
# File 'lib/win32/taskscheduler.rb', line 1207

def configure_principals(principals)
  raise TypeError unless principals.is_a?(Hash)
  check_for_active_task
  definition = @task.Definition
  definition.Principal.Id = principals[:id] if principals[:id].to_s != ""
  definition.Principal.DisplayName = principals[:display_name] if principals[:display_name].to_s != ""
  definition.Principal.UserId = principals[:user_id] if principals[:user_id].to_s != ""
  definition.Principal.LogonType = principals[:logon_type] if principals[:logon_type].to_s != ""
  definition.Principal.GroupId = principals[:group_id] if principals[:group_id].to_s != ""
  definition.Principal.RunLevel = principals[:run_level] if principals[:run_level].to_s != ""
  @interactive = true if principals[:logon_type] == TASK_LOGON_INTERACTIVE_TOKEN
  register_task_definition(definition)
  principals
end

#configure_registration_info(hash) ⇒ Object

Set registration information options. The possible options are:

  • author

  • date

  • description (or comment)

  • documentation

  • security_descriptor (should be a Win32::Security::SID)

  • source

  • uri

  • version

  • xml_text (or xml)

Note that most of these options have standalone methods as well, e.g. calling ts.configure_registration_info(:author => ‘Dan’) is the same as calling ts.author = ‘Dan’.

Raises:

  • (TypeError)


1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
# File 'lib/win32/taskscheduler.rb', line 1172

def configure_registration_info(hash)
  raise TypeError unless hash.is_a?(Hash)
  check_for_active_task

  definition = @task.Definition

  author = hash[:author]
  date = hash[:date]
  description = hash[:description] || hash[:comment]
  documentation = hash[:documentation]
  security_descriptor = hash[:security_descriptor]
  source = hash[:source]
  uri = hash[:uri]
  version = hash[:version]
  xml_text = hash[:xml_text] || hash[:xml]

  definition.RegistrationInfo.Author = author if author
  definition.RegistrationInfo.Date = date if date
  definition.RegistrationInfo.Description = description if description
  definition.RegistrationInfo.Documentation = documentation if documentation
  definition.RegistrationInfo.SecurityDescriptor = security_descriptor if security_descriptor
  definition.RegistrationInfo.Source = source if source
  definition.RegistrationInfo.URI = uri if uri
  definition.RegistrationInfo.Version = version if version
  definition.RegistrationInfo.XmlText = xml_text if xml_text

  register_task_definition(definition)

  hash
end

#configure_settings(settings_hash) ⇒ Hash

Configures tasks settings

Parameters:

  • settings_hash (Hash)

    The settings to configure a task

Options Hash (settings_hash):

  • :allow_demand_start (Boolean)

    The subject

  • :allow_hard_terminate (Boolean)
  • :disallow_start_if_on_batteries (Boolean)
  • :disallow_start_on_remote_app_session (Boolean)
  • :enabled (Boolean)
  • :hidden (Boolean)
  • :run_only_if_idle (Boolean)
  • :run_only_if_network_available (Boolean)
  • :start_when_available (Boolean)
  • :stop_if_going_on_batteries (Boolean)
  • :use_unified_scheduling_engine (Boolean)
  • :volatile (Boolean)
  • :wake_to_run (Boolean)
  • :restart_on_idle (Boolean)

    The Idle Setting

  • :stop_on_idle_end (Boolean)

    The Idle Setting

  • :compatibility (Integer)
  • :multiple_instances (Integer)
  • :priority (Integer)
  • :restart_count (Integer)
  • :delete_expired_task_after (String)
  • :execution_time_limit (String)
  • :restart_interval (String)
  • :idle_duration (String)

    The Idle Setting

  • :wait_timeout (String)

    The Idle Setting

Returns:

  • (Hash)

    User input

Raises:

  • (TypeError)

See Also:



1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
# File 'lib/win32/taskscheduler.rb', line 1111

def configure_settings(settings_hash)
  raise TypeError, "User input settings are required in hash" unless settings_hash.is_a?(Hash)

  check_for_active_task
  definition = @task.Definition

  # Check for invalid setting
  invalid_settings = settings_hash.keys - valid_settings_options
  raise TypeError, "Invalid setting passed: #{invalid_settings.join(', ')}" unless invalid_settings.empty?

  # Some modification is required in user input
  hash = settings_hash.dup

  # Conversion of few settings
  hash[:execution_time_limit] = hash[:max_run_time] unless hash[:max_run_time].nil?
  %i{execution_time_limit idle_duration restart_interval wait_timeout}.each do |setting|
    hash[setting] = "PT#{hash[setting]}M" unless hash[setting].nil?
  end

  task_settings = definition.Settings

  # Some Idle setting needs to be configured
  if IdleSettings.any? { |setting| hash.key?(setting) }
    idle_settings = task_settings.IdleSettings
    IdleSettings.each do |setting|
      next if hash[setting].nil?
      idle_settings.setproperty(camelize(setting.to_s), hash[setting])
      # This setting is not required to be configured now
      hash.delete(setting)
    end
  end

  # XML settings are not to be configured
  %i{xml_text xml}.map { |x| hash.delete(x) }

  hash.each do |setting, value|
    setting = camelize(setting.to_s)
    definition.Settings.setproperty(setting, value)
  end

  register_task_definition(definition)

  settings_hash
end

#creatorObject Also known as: author

Returns the name of the user who created the task.



973
974
975
976
# File 'lib/win32/taskscheduler.rb', line 973

def creator
  check_for_active_task
  @task.Definition.RegistrationInfo.Author
end

#creator=(creator) ⇒ Object Also known as: author=

Sets the creator for the task.

Raises:

  • (TypeError)


982
983
984
985
986
987
988
989
990
991
# File 'lib/win32/taskscheduler.rb', line 982

def creator=(creator)
  raise TypeError unless creator.is_a?(String)
  check_for_active_task

  definition = @task.Definition
  definition.RegistrationInfo.Author = creator
  register_task_definition(definition)

  creator
end

#delete(task) ⇒ Object

Delete the specified task name.

Raises:

  • (TypeError)


254
255
256
257
258
259
260
261
262
# File 'lib/win32/taskscheduler.rb', line 254

def delete(task)
  raise TypeError unless task.is_a?(String)

  begin
    @root.DeleteTask(task, 0)
  rescue WIN32OLERuntimeError => err
    raise Error, ole_error("DeleteTask", err)
  end
end

#delete_trigger(index) ⇒ Object

Deletes the trigger at the specified index. – TODO: Fix.

Raises:

  • (TypeError)


640
641
642
643
644
645
646
647
648
649
650
# File 'lib/win32/taskscheduler.rb', line 640

def delete_trigger(index)
  raise TypeError unless index.is_a?(Numeric)
  check_for_active_task
  index += 1 # first item index is 1

  definition = @task.Definition
  definition.Triggers.Remove(index)
  register_task_definition(definition)

  index
end

#enabled?Boolean

Returns true if current task is enabled

Returns:

  • (Boolean)


935
936
937
938
# File 'lib/win32/taskscheduler.rb', line 935

def enabled?
  check_for_active_task
  @task.enabled
end

#enumObject Also known as: tasks

Returns an array of scheduled task names.



178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/win32/taskscheduler.rb', line 178

def enum
  # Get the task folder that contains the tasks.
  taskCollection = @root.GetTasks(0)

  array = []

  taskCollection.each do |registeredTask|
    array << registeredTask.Name
  end

  array
end

#execution_time_limitObject

Returns the execution time limit for current active task



1021
1022
1023
1024
# File 'lib/win32/taskscheduler.rb', line 1021

def execution_time_limit
  check_for_active_task
  @task.Definition.Settings.ExecutionTimeLimit
end

#exists?(full_task_path) ⇒ Boolean

Returns whether or not the specified task exists.

Returns:

  • (Boolean)


195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
# File 'lib/win32/taskscheduler.rb', line 195

def exists?(full_task_path)
  path = nil
  task_name = nil

  if full_task_path.include?('\\')
    *path, task_name = full_task_path.split('\\')
  else
    task_name = full_task_path
  end

  folder = path.nil? ? root_path : path.join('\\')

  begin
    root = @service.GetFolder(folder)
  rescue WIN32OLERuntimeError => err
    return false
  end

  if root.nil?
    return false
  else
    begin
      task = root.GetTask(task_name)
      return task && task.Name == task_name
    rescue WIN32OLERuntimeError => err
      return false
    end
  end
end

#exit_codeObject

Returns the exit code from the last scheduled run.



942
943
944
945
# File 'lib/win32/taskscheduler.rb', line 942

def exit_code
  check_for_active_task
  @task.LastTaskResult
end

#get_task(task) ⇒ Object

Return the sepcified task if exist

Raises:

  • (TypeError)


227
228
229
230
231
232
233
234
235
236
# File 'lib/win32/taskscheduler.rb', line 227

def get_task(task)
  raise TypeError unless task.is_a?(String)

  begin
    registeredTask = @root.GetTask(task)
    @task = registeredTask
  rescue WIN32OLERuntimeError => err
    raise Error, ole_error("activate", err)
  end
end

#idle_settingsObject

Returns a hash of idle settings of the current task



1247
1248
1249
1250
1251
1252
1253
1254
# File 'lib/win32/taskscheduler.rb', line 1247

def idle_settings
  check_for_active_task
  settings_hash = {}
  @task.Definition.Settings.IdleSettings.ole_get_methods.each do |setting|
    settings_hash[setting.name] = @task.Definition.Settings.IdleSettings._getproperty(setting.dispid, [], [])
  end
  symbolize_keys(settings_hash)
end

#machine=(host) ⇒ Object Also known as: host=

Set the host on which the various TaskScheduler methods will execute. This method may require administrative privileges.

Raises:

  • (TypeError)


292
293
294
295
296
297
298
299
300
301
302
303
# File 'lib/win32/taskscheduler.rb', line 292

def machine=(host)
  raise TypeError unless host.is_a?(String)

  begin
    @service.Connect(host)
  rescue WIN32OLERuntimeError => err
    raise Error, ole_error("Connect", err)
  end

  @host = host
  host
end

#max_run_timeObject

Returns the maximum length of time, in milliseconds, that the task will run before terminating.



1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
# File 'lib/win32/taskscheduler.rb', line 1029

def max_run_time
  check_for_active_task

  t = @task.Definition.Settings.ExecutionTimeLimit
  year = t.scan(/(\d+?)Y/).flatten.first
  month = t.scan(/(\d+?)M/).flatten.first
  day = t.scan(/(\d+?)D/).flatten.first
  hour = t.scan(/(\d+?)H/).flatten.first
  min = t.scan(/T.*(\d+?)M/).flatten.first
  sec = t.scan(/(\d+?)S/).flatten.first

  time = 0
  time += year.to_i * 365 if year
  time += month.to_i * 30 if month
  time += day.to_i if day
  time *= 24
  time += hour.to_i if hour
  time *= 60
  time += min.to_i if min
  time *= 60
  time += sec.to_i if sec
  time *= 1000

  time
end

#max_run_time=(max_run_time) ⇒ Object

Sets the maximum length of time, in milliseconds, that the task can run before terminating. Returns the value you specified if successful.

Raises:

  • (TypeError)


1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
# File 'lib/win32/taskscheduler.rb', line 1058

def max_run_time=(max_run_time)
  raise TypeError unless max_run_time.is_a?(Numeric)
  check_for_active_task

  t = max_run_time
  t /= 1000
  limit = "PT#{t}S"

  definition = @task.Definition
  definition.Settings.ExecutionTimeLimit = limit
  register_task_definition(definition)

  max_run_time
end

#most_recent_run_timeObject

Returns a Time object indicating the most recent time the task ran or nil if the task has never run.



1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
# File 'lib/win32/taskscheduler.rb', line 1005

def most_recent_run_time
  check_for_active_task

  time = nil

  begin
    time = Time.parse(@task.LastRunTime)
  rescue StandardError
    # Ignore
  end

  time
end

#network_settingsObject

Returns a hash of network settings of the current task



1257
1258
1259
1260
1261
1262
1263
1264
# File 'lib/win32/taskscheduler.rb', line 1257

def network_settings
  check_for_active_task
  settings_hash = {}
  @task.Definition.Settings.NetworkSettings.ole_get_methods.each do |setting|
    settings_hash[setting.name] = @task.Definition.Settings.NetworkSettings._getproperty(setting.dispid, [], [])
  end
  symbolize_keys(settings_hash)
end

#new_work_item(task, trigger, userinfo = { user: nil, password: nil, interactive: false }) ⇒ Object Also known as: new_task

Creates a new work item (scheduled job) with the given trigger. The trigger variable is a hash of options that define when the scheduled job should run.

Raises:

  • (TypeError)


511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
# File 'lib/win32/taskscheduler.rb', line 511

def new_work_item(task, trigger, userinfo = { user: nil, password: nil, interactive: false })
  raise TypeError unless userinfo.is_a?(Hash) && task.is_a?(String) && trigger.is_a?(Hash)

  # If user ID is not given, consider it as a 'SYSTEM' user
  userinfo[:user] = SERVICE_ACCOUNT_USERS.first if userinfo[:user].to_s.empty?
  @password = userinfo[:password]
  @interactive = userinfo[:interactive]

  check_credential_requirements(userinfo[:user], userinfo[:password])

  taskDefinition = @service.NewTask(0)
  taskDefinition.RegistrationInfo.Description = ""
  taskDefinition.RegistrationInfo.Author = ""
  taskDefinition.Settings.StartWhenAvailable = false
  taskDefinition.Settings.Enabled = true
  taskDefinition.Settings.Hidden = false

  unless trigger.empty?
    raise ArgumentError, "Unknown trigger type" unless valid_trigger_option(trigger[:trigger_type])
    validate_trigger(trigger)

    startTime = format("%04d-%02d-%02dT%02d:%02d:00", trigger[:start_year], trigger[:start_month], trigger[:start_day], trigger[:start_hour], trigger[:start_minute])

    # Set defaults
    trigger[:end_year]  ||= 0
    trigger[:end_month] ||= 0
    trigger[:end_day]   ||= 0

    endTime = format("%04d-%02d-%02dT00:00:00", trigger[:end_year], trigger[:end_month], trigger[:end_day])

    trig = taskDefinition.Triggers.Create(trigger[:trigger_type].to_i)
    trig.Id = "RegistrationTriggerId#{taskDefinition.Triggers.Count}"
    trig.StartBoundary = startTime if startTime != "0000-00-00T00:00:00"
    trig.EndBoundary = endTime if endTime != "0000-00-00T00:00:00"
    trig.Enabled = true

    repetitionPattern = trig.Repetition

    if trigger[:minutes_duration].to_i > 0
      repetitionPattern.Duration = "PT#{trigger[:minutes_duration] || 0}M"
    end

    if trigger[:minutes_interval].to_i > 0
      repetitionPattern.Interval = "PT#{trigger[:minutes_interval] || 0}M"
    end

    tmp = trigger[:type]
    tmp = nil unless tmp.is_a?(Hash)

    case trigger[:trigger_type]
    when TASK_TIME_TRIGGER_DAILY
      trig.DaysInterval = tmp[:days_interval] if tmp && tmp[:days_interval]
      if trigger[:random_minutes_interval].to_i > 0
        trig.RandomDelay = "PT#{trigger[:random_minutes_interval]}M"
      end
    when TASK_TIME_TRIGGER_WEEKLY
      trig.DaysOfWeek = tmp[:days_of_week] if tmp && tmp[:days_of_week]
      trig.WeeksInterval = tmp[:weeks_interval] if tmp && tmp[:weeks_interval]
      if trigger[:random_minutes_interval].to_i > 0
        trig.RandomDelay = "PT#{trigger[:random_minutes_interval] || 0}M"
      end
    when TASK_TIME_TRIGGER_MONTHLYDATE
      trig.MonthsOfYear = tmp[:months] if tmp && tmp[:months]
      trig.DaysOfMonth = tmp[:days] if tmp && tmp[:days]
      if trigger[:random_minutes_interval].to_i > 0
        trig.RandomDelay = "PT#{trigger[:random_minutes_interval] || 0}M"
      end
      trig.RunOnLastDayOfMonth = trigger[:run_on_last_day_of_month] if trigger[:run_on_last_day_of_month]
    when TASK_TIME_TRIGGER_MONTHLYDOW
      trig.MonthsOfYear = tmp[:months] if tmp && tmp[:months]
      trig.DaysOfWeek = tmp[:days_of_week] if tmp && tmp[:days_of_week]
      trig.WeeksOfMonth = tmp[:weeks_of_month] if tmp && tmp[:weeks_of_month]
      if trigger[:random_minutes_interval].to_i > 0
        trig.RandomDelay = "PT#{trigger[:random_minutes_interval] || 0}M"
      end
      trig.RunOnLastWeekOfMonth = trigger[:run_on_last_week_of_month] if trigger[:run_on_last_week_of_month]
    when TASK_TIME_TRIGGER_ONCE
      if trigger[:random_minutes_interval].to_i > 0
        trig.RandomDelay = "PT#{trigger[:random_minutes_interval] || 0}M"
      end
    when TASK_EVENT_TRIGGER_AT_SYSTEMSTART
      trig.Delay = "PT#{trigger[:delay_duration] || 0}M"
    when TASK_EVENT_TRIGGER_AT_LOGON
      trig.UserId = trigger[:user_id] if trigger[:user_id]
      trig.Delay = "PT#{trigger[:delay_duration] || 0}M"
    end
  end

  act = taskDefinition.Actions.Create(0)
  act.Path = "cmd"

  register_task_definition(taskDefinition, task, userinfo[:user], userinfo[:password])

  @task = @root.GetTask(task)
end

#next_run_timeObject

Returns a Time object that indicates the next time the task will run.



997
998
999
1000
# File 'lib/win32/taskscheduler.rb', line 997

def next_run_time
  check_for_active_task
  @task.NextRunTime
end

#parametersObject

Returns the command line parameters for the task.



389
390
391
392
393
394
395
396
397
398
399
# File 'lib/win32/taskscheduler.rb', line 389

def parameters
  check_for_active_task

  param = nil

  @task.Definition.Actions.each do |action|
    param = action.Arguments if action.Type == 0
  end

  param
end

#parameters=(param) ⇒ Object

Sets the parameters for the task. These parameters are passed as command line arguments to the application the task will run. To clear the command line parameters set it to an empty string. – NOTE: Again, it seems the task must be reactivated to be picked up.

Raises:

  • (TypeError)


407
408
409
410
411
412
413
414
415
416
417
418
419
420
# File 'lib/win32/taskscheduler.rb', line 407

def parameters=(param)
  raise TypeError unless param.is_a?(String)
  check_for_active_task

  definition = @task.Definition

  definition.Actions.each do |action|
    action.Arguments = param if action.Type == 0
  end

  register_task_definition(definition)

  param
end

#principalsObject

Returns a hash containing all the principal information of the current task



1223
1224
1225
1226
1227
1228
1229
1230
# File 'lib/win32/taskscheduler.rb', line 1223

def principals
  check_for_active_task
  principals_hash = {}
  @task.Definition.Principal.ole_get_methods.each do |principal|
    principals_hash[principal.name] = @task.Definition.Principal._getproperty(principal.dispid, [], [])
  end
  symbolize_keys(principals_hash)
end

#priorityObject

Returns the task’s priority level. Possible values are ‘idle’, ‘lowest’. ‘below_normal_8’, ‘below_normal_7’, ‘normal_6’, ‘normal_5’, ‘normal_4’, ‘above_normal_3’, ‘above_normal_2’, ‘highest’, ‘critical’ and ‘unknown’.



459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
# File 'lib/win32/taskscheduler.rb', line 459

def priority
  check_for_active_task

  priority = case @task.Definition.Settings.Priority
             when 0
               "critical"
             when 1
               "highest"
             when 2
               "above_normal_2"
             when 3
               "above_normal_3"
             when 4
               "normal_4"
             when 5
               "normal_5"
             when 6
               "normal_6"
             when 7
               "below_normal_7"
             when 8
               "below_normal_8"
             when 9
               "lowest"
             when 10
               "idle"
             else
               "unknown"
             end

  priority
end

#priority=(priority) ⇒ Object

Sets the priority of the task. The priority should be a numeric priority constant value.

Raises:

  • (TypeError)


495
496
497
498
499
500
501
502
503
504
505
# File 'lib/win32/taskscheduler.rb', line 495

def priority=(priority)
  raise TypeError unless priority.is_a?(Numeric)
  check_for_active_task

  definition = @task.Definition
  definition.Settings.Priority = priority

  register_task_definition(definition)

  priority
end

#root_path(path = '\\') ⇒ Object



124
125
126
# File 'lib/win32/taskscheduler.rb', line 124

def root_path(path = '\\')
  path
end

#runObject

Execute the current task.



266
267
268
269
# File 'lib/win32/taskscheduler.rb', line 266

def run
  check_for_active_task
  @task.run(nil)
end

#save(_file = nil) ⇒ Object

This method no longer has any effect. It is a no-op that remains for backwards compatibility. It will be removed in 0.4.0.



274
275
276
277
278
# File 'lib/win32/taskscheduler.rb', line 274

def save(_file = nil)
  warn DeprecatedMethodWarning, "this method is no longer necessary"
  check_for_active_task
  # Do nothing, deprecated.
end

#set_account_information(user_id, password, interactive) ⇒ Object

Sets the user and password for the given task. If the user and password are set properly then true is returned. throws TypeError if password is not provided for other than system users



329
330
331
332
333
334
335
336
# File 'lib/win32/taskscheduler.rb', line 329

def (user_id, password, interactive)
  @interactive ||= interactive
  check_credential_requirements(user_id, password)
  check_for_active_task
  @password = password
  register_task_definition(@task.Definition, @task.Path, user_id, password)
  true
end

#set_machine(host, user = nil, domain = nil, password = nil) ⇒ Object Also known as: set_host

Similar to the TaskScheduler#machine= method, this method also allows you to pass a user, domain and password as needed. This method may require administrative privileges.

Raises:

  • (TypeError)


309
310
311
312
313
314
315
316
317
318
319
320
# File 'lib/win32/taskscheduler.rb', line 309

def set_machine(host, user = nil, domain = nil, password = nil)
  raise TypeError unless host.is_a?(String)

  begin
    @service.Connect(host, user, domain, password)
  rescue WIN32OLERuntimeError => err
    raise Error, ole_error("Connect", err)
  end

  @host = host
  host
end

#settingsObject

Returns a hash containing all settings of the current task



1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
# File 'lib/win32/taskscheduler.rb', line 1233

def settings
  check_for_active_task
  settings_hash = {}
  @task.Definition.Settings.ole_get_methods.each do |setting|
    next if setting.name == "XmlText" # not needed
    settings_hash[setting.name] = @task.Definition.Settings._getproperty(setting.dispid, [], [])
  end

  settings_hash["IdleSettings"] = idle_settings
  settings_hash["NetworkSettings"] = network_settings
  symbolize_keys(settings_hash)
end

#statusObject

Returns the status of the currently active task. Possible values are ‘ready’, ‘running’, ‘not scheduled’ or ‘unknown’.



915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
# File 'lib/win32/taskscheduler.rb', line 915

def status
  check_for_active_task

  status = case @task.State
           when 3
             "ready"
           when 4
             "running"
           when 2
             "queued"
           when 1
             "not scheduled"
           else
             "unknown"
           end

  status
end

#task_user_id(definition) ⇒ String

Returns the user or group associated with the task. If no one is associated, it returns the default user i.e., ‘SYSTEM’

Parameters:

  • definition (WIN32OLE)

Returns:

  • (String)

    user_id



1272
1273
1274
1275
1276
1277
# File 'lib/win32/taskscheduler.rb', line 1272

def task_user_id(definition)
  user_id = definition.Principal.UserId.to_s
  user_id = definition.Principal.GroupId.to_s if user_id.empty?
  user_id = SERVICE_ACCOUNT_USERS.first if user_id.empty?
  user_id
end

#terminateObject Also known as: stop

Terminate (stop) the current task.



282
283
284
285
# File 'lib/win32/taskscheduler.rb', line 282

def terminate
  check_for_active_task
  @task.stop(nil)
end

#trigger(index) ⇒ Object

Returns a hash that describes the trigger at the given index for the current task.

Raises:

  • (TypeError)


655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
# File 'lib/win32/taskscheduler.rb', line 655

def trigger(index)
  raise TypeError unless index.is_a?(Numeric)
  check_for_active_task
  index += 1 # first item index is 1

  begin
    trig = @task.Definition.Triggers.Item(index)
  rescue WIN32OLERuntimeError => err
    raise Error, ole_error("Item", err)
  end

  trigger = {}

  case trig.Type
  when TASK_TIME_TRIGGER_DAILY
    tmp = {}
    tmp[:days_interval] = trig.DaysInterval
    trigger[:type] = tmp
    trigger[:random_minutes_interval] = time_in_minutes(trig.RandomDelay)
  when TASK_TIME_TRIGGER_WEEKLY
    tmp = {}
    tmp[:weeks_interval] = trig.WeeksInterval
    tmp[:days_of_week] = trig.DaysOfWeek
    trigger[:type] = tmp
    trigger[:random_minutes_interval] = time_in_minutes(trig.RandomDelay)
  when TASK_TIME_TRIGGER_MONTHLYDATE
    tmp = {}
    tmp[:months] = trig.MonthsOfYear
    tmp[:days] = trig.DaysOfMonth
    trigger[:type] = tmp
    trigger[:random_minutes_interval] = time_in_minutes(trig.RandomDelay)
    trigger[:run_on_last_day_of_month] = trig.RunOnLastDayOfMonth
  when TASK_TIME_TRIGGER_MONTHLYDOW
    tmp = {}
    tmp[:months] = trig.MonthsOfYear
    tmp[:days_of_week] = trig.DaysOfWeek
    tmp[:weeks_of_month] = trig.WeeksOfMonth
    trigger[:type] = tmp
    trigger[:random_minutes_interval] = time_in_minutes(trig.RandomDelay)
    trigger[:run_on_last_week_of_month] = trig.RunOnLastWeekOfMonth
  when TASK_TIME_TRIGGER_ONCE
    tmp = {}
    tmp[:once] = nil
    trigger[:type] = tmp
    trigger[:random_minutes_interval] = time_in_minutes(trig.RandomDelay)
  when TASK_EVENT_TRIGGER_AT_SYSTEMSTART
    trigger[:delay_duration] = time_in_minutes(trig.Delay)
  when TASK_EVENT_TRIGGER_AT_LOGON
    trigger[:user_id] = trig.UserId if trig.UserId.to_s != ""
    trigger[:delay_duration] = time_in_minutes(trig.Delay)
  when TASK_EVENT_TRIGGER_ON_IDLE
    trigger[:execution_time_limit] = time_in_minutes(trig.ExecutionTimeLimit)
  else
    raise Error, "Unknown trigger type"
  end

  trigger[:start_year], trigger[:start_month], trigger[:start_day],
  trigger[:start_hour], trigger[:start_minute] = trig.StartBoundary.scan(/(\d+)-(\d+)-(\d+)T(\d+):(\d+)/).first

  trigger[:end_year], trigger[:end_month],
  trigger[:end_day] = trig.EndBoundary.scan(/(\d+)-(\d+)-(\d+)T/).first

  trigger[:minutes_duration] = time_in_minutes(trig.Repetition.Duration)
  trigger[:minutes_interval] = time_in_minutes(trig.Repetition.Interval)
  trigger[:trigger_type] = trig.Type

  trigger
end

#trigger=(trigger) ⇒ Object

Sets the trigger for the currently active task. The trigger is a hash with the following possible options:

  • days

  • days_interval

  • days_of_week

  • end_day

  • end_month

  • end_year

  • flags

  • minutes_duration

  • minutes_interval

  • months

  • random_minutes_interval

  • start_day

  • start_hour

  • start_minute

  • start_month

  • start_year

  • trigger_type

  • type

  • weeks

  • weeks_interval

Raises:

  • (TypeError)


748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
# File 'lib/win32/taskscheduler.rb', line 748

def trigger=(trigger)
  raise TypeError unless trigger.is_a?(Hash)
  raise ArgumentError, "Unknown trigger type" unless valid_trigger_option(trigger[:trigger_type])

  check_for_active_task

  validate_trigger(trigger)

  definition = @task.Definition
  definition.Triggers.Clear()

  startTime = format("%04d-%02d-%02dT%02d:%02d:00", trigger[:start_year], trigger[:start_month], trigger[:start_day], trigger[:start_hour], trigger[:start_minute])

  endTime = format("%04d-%02d-%02dT00:00:00", trigger[:end_year], trigger[:end_month], trigger[:end_day])

  trig = definition.Triggers.Create(trigger[:trigger_type].to_i)
  trig.Id = "RegistrationTriggerId#{definition.Triggers.Count}"
  trig.StartBoundary = startTime if startTime != "0000-00-00T00:00:00"
  trig.EndBoundary = endTime if endTime != "0000-00-00T00:00:00"
  trig.Enabled = true

  repetitionPattern = trig.Repetition

  if trigger[:minutes_duration].to_i > 0
    repetitionPattern.Duration = "PT#{trigger[:minutes_duration] || 0}M"
  end

  if trigger[:minutes_interval].to_i > 0
    repetitionPattern.Interval = "PT#{trigger[:minutes_interval] || 0}M"
  end

  tmp = trigger[:type]
  tmp = nil unless tmp.is_a?(Hash)

  case trigger[:trigger_type]
  when TASK_TIME_TRIGGER_DAILY
    trig.DaysInterval = tmp[:days_interval] if tmp && tmp[:days_interval]
    if trigger[:random_minutes_interval].to_i > 0
      trig.RandomDelay = "PT#{trigger[:random_minutes_interval]}M"
    end
  when TASK_TIME_TRIGGER_WEEKLY
    trig.DaysOfWeek = tmp[:days_of_week] if tmp && tmp[:days_of_week]
    trig.WeeksInterval = tmp[:weeks_interval] if tmp && tmp[:weeks_interval]
    if trigger[:random_minutes_interval].to_i > 0
      trig.RandomDelay = "PT#{trigger[:random_minutes_interval] || 0}M"
    end
  when TASK_TIME_TRIGGER_MONTHLYDATE
    trig.MonthsOfYear = tmp[:months] if tmp && tmp[:months]
    trig.DaysOfMonth = tmp[:days] if tmp && tmp[:days]
    if trigger[:random_minutes_interval].to_i > 0
      trig.RandomDelay = "PT#{trigger[:random_minutes_interval] || 0}M"
    end
    trig.RunOnLastDayOfMonth = trigger[:run_on_last_day_of_month] if trigger[:run_on_last_day_of_month]
  when TASK_TIME_TRIGGER_MONTHLYDOW
    trig.MonthsOfYear = tmp[:months] if tmp && tmp[:months]
    trig.DaysOfWeek = tmp[:days_of_week] if tmp && tmp[:days_of_week]
    trig.WeeksOfMonth = tmp[:weeks_of_month] if tmp && tmp[:weeks_of_month]
    if trigger[:random_minutes_interval].to_i > 0
      trig.RandomDelay = "PT#{trigger[:random_minutes_interval] || 0}M"
    end
    trig.RunOnLastWeekOfMonth = trigger[:run_on_last_week_of_month] if trigger[:run_on_last_week_of_month]
  when TASK_TIME_TRIGGER_ONCE
    if trigger[:random_minutes_interval].to_i > 0
      trig.RandomDelay = "PT#{trigger[:random_minutes_interval] || 0}M"
    end
  when TASK_EVENT_TRIGGER_AT_SYSTEMSTART
    trig.Delay = "PT#{trigger[:delay_duration] || 0}M"
  when TASK_EVENT_TRIGGER_AT_LOGON
    trig.UserId = trigger[:user_id] if trigger[:user_id]
    trig.Delay = "PT#{trigger[:delay_duration] || 0}M"
  when TASK_EVENT_TRIGGER_ON_IDLE
    # for setting execution time limit Ref : https://msdn.microsoft.com/en-us/library/windows/desktop/aa380724(v=vs.85).aspx
    if trigger[:execution_time_limit].to_i > 0
      trig.ExecutionTimeLimit = "PT#{trigger[:execution_time_limit] || 0}M"
    end
  end

  register_task_definition(definition)

  trigger
end

#trigger_countObject

Returns the number of triggers associated with the active task.

Raises:



611
612
613
614
615
# File 'lib/win32/taskscheduler.rb', line 611

def trigger_count
  raise Error, "No currently active task" if @task.nil?

  @task.Definition.Triggers.Count
end

#trigger_string(index) ⇒ Object

Returns a string that describes the current trigger at the specified index for the active task.

Example: “At 7:14 AM every day, starting 4/11/2015”

Raises:

  • (TypeError)


622
623
624
625
626
627
628
629
630
631
632
633
634
# File 'lib/win32/taskscheduler.rb', line 622

def trigger_string(index)
  raise TypeError unless index.is_a?(Numeric)
  check_for_active_task
  index += 1 # first item index is 1

  begin
    trigger = @task.Definition.Triggers.Item(index)
  rescue WIN32OLERuntimeError
    raise Error, "No trigger found at index '#{index}'"
  end

  "Starting #{trigger.StartBoundary}"
end

#working_directoryObject

Returns the working directory for the task.



424
425
426
427
428
429
430
431
432
433
434
# File 'lib/win32/taskscheduler.rb', line 424

def working_directory
  check_for_active_task

  dir = nil

  @task.Definition.Actions.each do |action|
    dir = action.WorkingDirectory if action.Type == 0
  end

  dir
end

#working_directory=(dir) ⇒ Object

Sets the working directory for the task. – TODO: Why do I have to reactivate the task to see the change?

Raises:

  • (TypeError)


440
441
442
443
444
445
446
447
448
449
450
451
452
453
# File 'lib/win32/taskscheduler.rb', line 440

def working_directory=(dir)
  raise TypeError unless dir.is_a?(String)
  check_for_active_task

  definition = @task.Definition

  definition.Actions.each do |action|
    action.WorkingDirectory = dir if action.Type == 0
  end

  register_task_definition(definition)

  dir
end