Class: Win32::TaskScheduler
- Extended by:
- FFI::Library
- Includes:
- Puppet::Util::Windows::String
- Defined in:
- lib/puppet/util/windows/taskscheduler.rb
Overview
The TaskScheduler class encapsulates taskscheduler settings and behavior
Defined Under Namespace
Constant Summary collapse
- IDLE =
Shorthand constants
Puppet::Util::Windows::Process::IDLE_PRIORITY_CLASS
- NORMAL =
Puppet::Util::Windows::Process::NORMAL_PRIORITY_CLASS
- HIGH =
Puppet::Util::Windows::Process::HIGH_PRIORITY_CLASS
- REALTIME =
Puppet::Util::Windows::Process::REALTIME_PRIORITY_CLASS
- BELOW_NORMAL =
Puppet::Util::Windows::Process::BELOW_NORMAL_PRIORITY_CLASS
- ABOVE_NORMAL =
Puppet::Util::Windows::Process::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
- MAX_PATH =
unfortunately MSTask.h does not specify the limits for any settings so these were determined with some experimentation if values too large are written, its suspected there may be internal limits may be exceeded, corrupting the job used for max application name and path values
260
- MAX_ACCOUNT_LENGTH =
UNLEN from lmcons.h is 256 technet.microsoft.com/it-it/library/bb726984(en-us).aspx specifies 104
256
- MAX_PARAMETERS_LENGTH =
command line max length is limited to 8191, choose something high but still enough that we don’t blow out CLI
4096
- MAX_COMMENT_LENGTH =
in testing, this value could be set to a length of 99999, but saving / loading the task failed
8192
Class Attribute Summary collapse
-
.com_initialized ⇒ Object
Returns the value of attribute com_initialized.
Instance Method Summary collapse
-
#account_information ⇒ Object
Returns the user associated with the task or nil if no user has yet been associated with the task.
-
#activate(task) ⇒ Object
Activate the specified task.
-
#add_trigger(index, trigger) ⇒ Object
Adds a trigger at the specified index.
-
#application_name ⇒ Object
Returns the name of the application associated with the task.
-
#application_name=(app) ⇒ Object
Sets the application name associated with the task.
-
#comment ⇒ Object
Returns the comment associated with the task, if any.
-
#comment=(comment) ⇒ Object
Sets the comment for the task.
-
#creator ⇒ Object
Returns the name of the user who created the task.
-
#creator=(creator) ⇒ Object
Sets the creator for the task.
-
#delete(task) ⇒ Object
Delete the specified task name.
-
#delete_trigger(index) ⇒ Object
Deletes the trigger at the specified index.
-
#enum ⇒ Object
(also: #tasks)
Returns an array of scheduled task names.
-
#exists?(job_name) ⇒ Boolean
Returns whether or not the scheduled task exists.
-
#exit_code ⇒ Object
Returns the exit code from the last scheduled run.
-
#flags ⇒ Object
Returns the flags (integer) that modify the behavior of the work item.
-
#flags=(flags) ⇒ Object
Sets an OR’d value of flags that modify the behavior of the work item.
-
#initialize(work_item = nil, trigger = nil) ⇒ TaskScheduler
constructor
Returns a new TaskScheduler object.
-
#machine=(host) ⇒ Object
(also: #host=)
Set the host on which the various TaskScheduler methods will execute.
-
#max_run_time ⇒ Object
Returns the maximum length of time, in milliseconds, that the task will run before terminating.
-
#max_run_time=(max_run_time) ⇒ Object
Sets the maximum length of time, in milliseconds, that the task can run before terminating.
-
#most_recent_run_time ⇒ Object
Returns a Time object indicating the most recent time the task ran or nil if the task has never run.
-
#new_work_item(task, trigger) ⇒ Object
(also: #new_task)
Creates a new work item (scheduled job) with the given
trigger
. -
#next_run_time ⇒ Object
Returns a Time object that indicates the next time the task will run.
-
#parameters ⇒ Object
Returns the command line parameters for the task.
-
#parameters=(param) ⇒ Object
Sets the parameters for the task.
-
#priority ⇒ Object
Returns the task’s priority level.
-
#priority=(priority) ⇒ Object
Sets the priority of the task.
-
#run ⇒ Object
Execute the current task.
-
#save(file = nil) ⇒ Object
Saves the current task.
-
#set_account_information(user, password) ⇒ Object
Sets the
user
andpassword
for the given task. -
#status ⇒ Object
Returns the status of the currently active task.
-
#terminate ⇒ Object
Terminate the current task.
-
#trigger(index) ⇒ Object
Returns a hash that describes the trigger at the given index for the current task.
-
#trigger=(trigger) ⇒ Object
Sets the trigger for the currently active task.
-
#trigger_count ⇒ Object
Returns the number of triggers associated with the active task.
-
#working_directory ⇒ Object
Returns the working directory for the task.
-
#working_directory=(dir) ⇒ Object
Sets the working directory for the task.
Methods included from FFI::Library
Methods included from Puppet::Util::Windows::String
Constructor Details
#initialize(work_item = nil, trigger = nil) ⇒ TaskScheduler
Returns a new TaskScheduler object. If a work_item (and possibly the the trigger) are passed as arguments then a new work item is created and associated with that trigger, although you can still activate other tasks with the same handle.
This is really just a bit of convenience. Passing arguments to the constructor is the same as calling TaskScheduler.new plus TaskScheduler#new_work_item.
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/puppet/util/windows/taskscheduler.rb', line 184 def initialize(work_item=nil, trigger=nil) @pITS = nil @pITask = nil if ! self.class.com_initialized Puppet::Util::Windows::COM.InitializeCom() self.class.com_initialized = true end @pITS = COM::TaskScheduler.new at_exit do begin @pITS.Release if @pITS && !@pITS.null? @pITS = nil rescue end end if work_item if trigger raise TypeError unless trigger.is_a?(Hash) new_work_item(work_item, trigger) end end end |
Class Attribute Details
.com_initialized ⇒ Object
Returns the value of attribute com_initialized.
18 19 20 |
# File 'lib/puppet/util/windows/taskscheduler.rb', line 18 def com_initialized @com_initialized end |
Instance Method Details
#account_information ⇒ Object
Returns the user associated with the task or nil if no user has yet been associated with the task.
372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 |
# File 'lib/puppet/util/windows/taskscheduler.rb', line 372 def account_information raise Error.new(_('No current task scheduler. ITaskScheduler is NULL.')) if @pITS.nil? raise Error.new(_('No currently active task. ITask is NULL.')) if @pITask.nil? # default under certain failures user = nil begin FFI::MemoryPointer.new(:pointer) do |ptr| @pITask.GetAccountInformation(ptr) ptr.read_com_memory_pointer do |str_ptr| user = str_ptr.read_arbitrary_wide_string_up_to(MAX_ACCOUNT_LENGTH) if ! str_ptr.null? end end rescue Puppet::Util::Windows::Error => e raise e unless e.code == SCHED_E_ACCOUNT_INFORMATION_NOT_SET || e.code == SCHED_E_NO_SECURITY_SERVICES || e.code == ERROR_NONE_MAPPED end user end |
#activate(task) ⇒ Object
Activate the specified task.
245 246 247 248 249 250 251 252 253 254 255 256 257 |
# File 'lib/puppet/util/windows/taskscheduler.rb', line 245 def activate(task) raise Error.new(_('No current task scheduler. ITaskScheduler is NULL.')) if @pITS.nil? raise TypeError unless task.is_a?(String) FFI::MemoryPointer.new(:pointer) do |ptr| @pITS.Activate(wide_string(task), IID_ITask, ptr) reset_current_task @pITask = COM::Task.new(ptr.read_pointer) end @pITask end |
#add_trigger(index, trigger) ⇒ Object
Adds a trigger at the specified index.
660 661 662 663 664 665 666 667 668 |
# File 'lib/puppet/util/windows/taskscheduler.rb', line 660 def add_trigger(index, trigger) raise Error.new(_('No current task scheduler. ITaskScheduler is NULL.')) if @pITS.nil? raise Error.new(_('No currently active task. ITask is NULL.')) if @pITask.nil? raise TypeError unless trigger.is_a?(Hash) @pITask.UseInstance(COM::TaskTrigger, :GetTrigger, index) do |pITaskTrigger| populate_trigger(pITaskTrigger, trigger) end end |
#application_name ⇒ Object
Returns the name of the application associated with the task.
397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 |
# File 'lib/puppet/util/windows/taskscheduler.rb', line 397 def application_name raise Error.new(_('No current task scheduler. ITaskScheduler is NULL.')) if @pITS.nil? raise Error.new(_('No currently active task. ITask is NULL.')) if @pITask.nil? app = nil FFI::MemoryPointer.new(:pointer) do |ptr| @pITask.GetApplicationName(ptr) ptr.read_com_memory_pointer do |str_ptr| app = str_ptr.read_arbitrary_wide_string_up_to(MAX_PATH) if ! str_ptr.null? end end app end |
#application_name=(app) ⇒ Object
Sets the application name associated with the task.
416 417 418 419 420 421 422 423 424 425 426 427 428 |
# File 'lib/puppet/util/windows/taskscheduler.rb', line 416 def application_name=(app) raise Error.new(_('No current task scheduler. ITaskScheduler is NULL.')) if @pITS.nil? raise Error.new(_('No currently active task. ITask is NULL.')) if @pITask.nil? raise TypeError unless app.is_a?(String) # the application name is written to a .job file on disk, so is subject to path limitations if app.length > MAX_PATH raise Error.new(_("Application name has exceeded maximum allowed length %{max}") % { max: MAX_PATH }) end @pITask.SetApplicationName(wide_string(app)) app end |
#comment ⇒ Object
Returns the comment associated with the task, if any.
744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 |
# File 'lib/puppet/util/windows/taskscheduler.rb', line 744 def comment raise Error.new(_('No currently active task. ITask is NULL.')) if @pITask.nil? comment = nil FFI::MemoryPointer.new(:pointer) do |ptr| @pITask.GetComment(ptr) ptr.read_com_memory_pointer do |str_ptr| comment = str_ptr.read_arbitrary_wide_string_up_to(MAX_COMMENT_LENGTH) if ! str_ptr.null? end end comment end |
#comment=(comment) ⇒ Object
Sets the comment for the task.
762 763 764 765 766 767 768 769 770 771 772 |
# File 'lib/puppet/util/windows/taskscheduler.rb', line 762 def comment=(comment) raise Error.new(_('No currently active task. ITask is NULL.')) if @pITask.nil? raise TypeError unless comment.is_a?(String) if comment.length > MAX_COMMENT_LENGTH raise Error.new(_("Comment has exceeded maximum allowed length %{max}") % { max: MAX_COMMENT_LENGTH }) end @pITask.SetComment(wide_string(comment)) comment end |
#creator ⇒ Object
Returns the name of the user who created the task.
776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 |
# File 'lib/puppet/util/windows/taskscheduler.rb', line 776 def creator raise Error.new(_('No currently active task. ITask is NULL.')) if @pITask.nil? creator = nil FFI::MemoryPointer.new(:pointer) do |ptr| @pITask.GetCreator(ptr) ptr.read_com_memory_pointer do |str_ptr| creator = str_ptr.read_arbitrary_wide_string_up_to(MAX_ACCOUNT_LENGTH) if ! str_ptr.null? end end creator end |
#creator=(creator) ⇒ Object
Sets the creator for the task.
794 795 796 797 798 799 800 801 802 803 804 805 |
# File 'lib/puppet/util/windows/taskscheduler.rb', line 794 def creator=(creator) raise Error.new(_('No currently active task. ITask is NULL.')) if @pITask.nil? raise TypeError unless creator.is_a?(String) if creator.length > MAX_ACCOUNT_LENGTH raise Error.new(_("Creator has exceeded maximum allowed length %{max}") % { max: MAX_ACCOUNT_LENGTH }) end @pITask.SetCreator(wide_string(creator)) creator end |
#delete(task) ⇒ Object
Delete the specified task name.
261 262 263 264 265 266 267 268 |
# File 'lib/puppet/util/windows/taskscheduler.rb', line 261 def delete(task) raise Error.new(_('No current task scheduler. ITaskScheduler is NULL.')) if @pITS.nil? raise TypeError unless task.is_a?(String) @pITS.Delete(wide_string(task)) true end |
#delete_trigger(index) ⇒ Object
Deletes the trigger at the specified index.
611 612 613 614 615 616 617 |
# File 'lib/puppet/util/windows/taskscheduler.rb', line 611 def delete_trigger(index) raise Error.new(_('No current task scheduler. ITaskScheduler is NULL.')) if @pITS.nil? raise Error.new(_('No currently active task. ITask is NULL.')) if @pITask.nil? @pITask.DeleteTrigger(index) index end |
#enum ⇒ Object Also known as: tasks
Returns an array of scheduled task names.
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 |
# File 'lib/puppet/util/windows/taskscheduler.rb', line 212 def enum raise Error.new(_('No current task scheduler. ITaskScheduler is NULL.')) if @pITS.nil? array = [] @pITS.UseInstance(COM::EnumWorkItems, :Enum) do |pIEnum| FFI::MemoryPointer.new(:pointer) do |names_array_ptr_ptr| FFI::MemoryPointer.new(:win32_ulong) do |fetched_count_ptr| # awkward usage, if number requested is available, returns S_OK (0), or if less were returned returns S_FALSE (1) while (pIEnum.Next(TASKS_TO_RETRIEVE, names_array_ptr_ptr, fetched_count_ptr) >= Puppet::Util::Windows::COM::S_OK) count = fetched_count_ptr.read_win32_ulong break if count == 0 names_array_ptr_ptr.read_com_memory_pointer do |names_array_ptr| # iterate over the array of pointers name_ptr_ptr = FFI::Pointer.new(:pointer, names_array_ptr) for i in 0 ... count name_ptr_ptr[i].read_com_memory_pointer do |name_ptr| array << name_ptr.read_arbitrary_wide_string_up_to(MAX_PATH) end end end end end end end array end |
#exists?(job_name) ⇒ Boolean
Returns whether or not the scheduled task exists.
870 871 872 873 |
# File 'lib/puppet/util/windows/taskscheduler.rb', line 870 def exists?(job_name) # task name comparison is case insensitive tasks.any? { |name| name.casecmp(job_name + '.job') == 0 } end |
#exit_code ⇒ Object
Returns the exit code from the last scheduled run.
725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 |
# File 'lib/puppet/util/windows/taskscheduler.rb', line 725 def exit_code raise Error.new(_('No currently active task. ITask is NULL.')) if @pITask.nil? status = 0 begin FFI::MemoryPointer.new(:dword, 1) do |ptr| @pITask.GetExitCode(ptr) status = ptr.read_dword end rescue Puppet::Util::Windows::Error => e raise e unless e.code == SCHED_S_TASK_HAS_NOT_RUN end status end |
#flags ⇒ Object
Returns the flags (integer) that modify the behavior of the work item. You must OR the return value to determine the flags yourself.
673 674 675 676 677 678 679 680 681 682 683 684 |
# File 'lib/puppet/util/windows/taskscheduler.rb', line 673 def flags raise Error.new(_('No currently active task. ITask is NULL.')) if @pITask.nil? flags = 0 FFI::MemoryPointer.new(:dword, 1) do |ptr| @pITask.GetFlags(ptr) flags = ptr.read_dword end flags end |
#flags=(flags) ⇒ Object
Sets an OR’d value of flags that modify the behavior of the work item.
688 689 690 691 692 693 694 |
# File 'lib/puppet/util/windows/taskscheduler.rb', line 688 def flags=(flags) raise Error.new(_('No current task scheduler. ITaskScheduler is NULL.')) if @pITS.nil? raise Error.new(_('No currently active task. ITask is NULL.')) if @pITask.nil? @pITask.SetFlags(flags) flags end |
#machine=(host) ⇒ Object Also known as: host=
Set the host on which the various TaskScheduler methods will execute.
313 314 315 316 317 318 319 320 |
# File 'lib/puppet/util/windows/taskscheduler.rb', line 313 def machine=(host) raise Error.new(_('No current task scheduler. ITaskScheduler is NULL.')) if @pITS.nil? raise TypeError unless host.is_a?(String) @pITS.SetTargetComputer(wide_string(host)) host end |
#max_run_time ⇒ Object
Returns the maximum length of time, in milliseconds, that the task will run before terminating.
845 846 847 848 849 850 851 852 853 854 855 856 |
# File 'lib/puppet/util/windows/taskscheduler.rb', line 845 def max_run_time raise Error.new(_('No currently active task. ITask is NULL.')) if @pITask.nil? max_run_time = nil FFI::MemoryPointer.new(:dword, 1) do |ptr| @pITask.GetMaxRunTime(ptr) max_run_time = ptr.read_dword end max_run_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.
861 862 863 864 865 866 867 |
# File 'lib/puppet/util/windows/taskscheduler.rb', line 861 def max_run_time=(max_run_time) raise Error.new(_('No currently active task. ITask is NULL.')) if @pITask.nil? raise TypeError unless max_run_time.is_a?(Numeric) @pITask.SetMaxRunTime(max_run_time) max_run_time end |
#most_recent_run_time ⇒ Object
Returns a Time object indicating the most recent time the task ran or nil if the task has never run.
825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 |
# File 'lib/puppet/util/windows/taskscheduler.rb', line 825 def most_recent_run_time raise Error.new(_('No currently active task. ITask is NULL.')) if @pITask.nil? time = nil begin FFI::MemoryPointer.new(WIN32::SYSTEMTIME.size) do |ptr| @pITask.GetMostRecentRunTime(ptr) time = WIN32::SYSTEMTIME.new(ptr).to_local_time end rescue Puppet::Util::Windows::Error => e raise e unless e.code == SCHED_S_TASK_HAS_NOT_RUN end time end |
#new_work_item(task, trigger) ⇒ 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.
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 |
# File 'lib/puppet/util/windows/taskscheduler.rb', line 553 def new_work_item(task, trigger) raise TypeError unless trigger.is_a?(Hash) raise Error.new(_('No current task scheduler. ITaskScheduler is NULL.')) if @pITS.nil? # I'm working around github issue #1 here. enum.each{ |name| if name.downcase == task.downcase + '.job' raise Error.new(_("task '%{task}' already exists") % { task: task }) end } FFI::MemoryPointer.new(:pointer) do |ptr| @pITS.NewWorkItem(wide_string(task), CLSID_CTask, IID_ITask, ptr) reset_current_task @pITask = COM::Task.new(ptr.read_pointer) FFI::MemoryPointer.new(:word, 1) do |trigger_index_ptr| # Without the 'enum.include?' check above the code segfaults here if the # task already exists. This should probably be handled properly instead # of simply avoiding the issue. @pITask.UseInstance(COM::TaskTrigger, :CreateTrigger, trigger_index_ptr) do |pITaskTrigger| populate_trigger(pITaskTrigger, trigger) end end end # preload task with the SYSTEM account # empty string '' means 'SYSTEM' per MSDN, so default it # given an account is necessary for creation of a task # note that a user may set SYSTEM explicitly, but that has problems # https://msdn.microsoft.com/en-us/library/windows/desktop/aa381276(v=vs.85).aspx set_account_information('', nil) @pITask end |
#next_run_time ⇒ Object
Returns a Time object that indicates the next time the task will run.
809 810 811 812 813 814 815 816 817 818 819 820 |
# File 'lib/puppet/util/windows/taskscheduler.rb', line 809 def next_run_time raise Error.new(_('No currently active task. ITask is NULL.')) if @pITask.nil? time = nil FFI::MemoryPointer.new(WIN32::SYSTEMTIME.size) do |ptr| @pITask.GetNextRunTime(ptr) time = WIN32::SYSTEMTIME.new(ptr).to_local_time end time end |
#parameters ⇒ Object
Returns the command line parameters for the task.
432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 |
# File 'lib/puppet/util/windows/taskscheduler.rb', line 432 def parameters raise Error.new(_('No current task scheduler. ITaskScheduler is NULL.')) if @pITS.nil? raise Error.new(_('No currently active task. ITask is NULL.')) if @pITask.nil? param = nil FFI::MemoryPointer.new(:pointer) do |ptr| @pITask.GetParameters(ptr) ptr.read_com_memory_pointer do |str_ptr| param = str_ptr.read_arbitrary_wide_string_up_to(MAX_PARAMETERS_LENGTH) if ! str_ptr.null? end 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.
453 454 455 456 457 458 459 460 461 462 463 464 465 |
# File 'lib/puppet/util/windows/taskscheduler.rb', line 453 def parameters=(param) raise Error.new(_('No current task scheduler. ITaskScheduler is NULL.')) if @pITS.nil? raise Error.new(_('No currently active task. ITask is NULL.')) if @pITask.nil? raise TypeError unless param.is_a?(String) if param.length > MAX_PARAMETERS_LENGTH raise Error.new(_("Parameters has exceeded maximum allowed length %{max}") % { max: MAX_PARAMETERS_LENGTH }) end @pITask.SetParameters(wide_string(param)) param end |
#priority ⇒ Object
Returns the task’s priority level. Possible values are ‘idle’, ‘normal’, ‘high’, ‘realtime’, ‘below_normal’, ‘above_normal’, and ‘unknown’.
506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 |
# File 'lib/puppet/util/windows/taskscheduler.rb', line 506 def priority raise Error.new(_('No current task scheduler. ITaskScheduler is NULL.')) if @pITS.nil? raise Error.new(_('No currently active task. ITask is NULL.')) if @pITask.nil? priority_name = '' FFI::MemoryPointer.new(:dword, 1) do |ptr| @pITask.GetPriority(ptr) pri = ptr.read_dword if (pri & IDLE) != 0 priority_name = 'idle' elsif (pri & NORMAL) != 0 priority_name = 'normal' elsif (pri & HIGH) != 0 priority_name = 'high' elsif (pri & REALTIME) != 0 priority_name = 'realtime' elsif (pri & BELOW_NORMAL) != 0 priority_name = 'below_normal' elsif (pri & ABOVE_NORMAL) != 0 priority_name = 'above_normal' else priority_name = 'unknown' end end priority_name end |
#priority=(priority) ⇒ Object
Sets the priority of the task. The priority
should be a numeric priority constant value.
539 540 541 542 543 544 545 546 547 |
# File 'lib/puppet/util/windows/taskscheduler.rb', line 539 def priority=(priority) raise Error.new(_('No current task scheduler. ITaskScheduler is NULL.')) if @pITS.nil? raise Error.new(_('No currently active task. ITask is NULL.')) if @pITask.nil? raise TypeError unless priority.is_a?(Numeric) @pITask.SetPriority(priority) priority end |
#run ⇒ Object
Execute the current task.
272 273 274 275 276 |
# File 'lib/puppet/util/windows/taskscheduler.rb', line 272 def run raise Error.new(_('No currently active task. ITask is NULL.')) if @pITask.nil? @pITask.Run end |
#save(file = nil) ⇒ Object
Saves the current task. Tasks must be saved before they can be activated. The .job file itself is typically stored in the C:WINDOWSTasks folder.
If file
(an absolute path) is specified then the job is saved to that file instead. A ‘.job’ extension is recommended but not enforced.
284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 |
# File 'lib/puppet/util/windows/taskscheduler.rb', line 284 def save(file = nil) raise Error.new(_('No currently active task. ITask is NULL.')) if @pITask.nil? raise Error.new(_('Account information must be set on the current task to save it properly.')) if !@account_information_set reset = true begin @pITask.QueryInstance(COM::PersistFile) do |pIPersistFile| wide_file = wide_string(file) pIPersistFile.Save(wide_file, 1) pIPersistFile.SaveCompleted(wide_file) end rescue reset = false ensure reset_current_task if reset end end |
#set_account_information(user, password) ⇒ Object
Sets the user
and password
for the given task. If the user and password are set properly then true is returned.
In some cases the job may be created, but the account information was bad. In this case the task is created but a warning is generated and false is returned.
Note that if intending to use SYSTEM, specify an empty user and nil password
Calling task.set_account_information(‘SYSTEM’, nil) will generally not work, except for one special case where flags are also set like: task.flags = Win32::TaskScheduler::TASK_FLAG_RUN_ONLY_IF_LOGGED_ON
This must be done prior to the 1st save() call for the task to be properly registered and visible through the MMC snap-in / schtasks.exe
340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 |
# File 'lib/puppet/util/windows/taskscheduler.rb', line 340 def set_account_information(user, password) raise Error.new(_('No current task scheduler. ITaskScheduler is NULL.')) if @pITS.nil? raise Error.new(_('No currently active task. ITask is NULL.')) if @pITask.nil? bool = false begin if (user.nil? || user=="") && (password.nil? || password=="") @pITask.SetAccountInformation(wide_string(""), FFI::Pointer::NULL) else if user.length > MAX_ACCOUNT_LENGTH raise Error.new(_("User has exceeded maximum allowed length %{max}") % { max: MAX_ACCOUNT_LENGTH }) end user = wide_string(user) password = wide_string(password) @pITask.SetAccountInformation(user, password) end @account_information_set = true bool = true rescue Puppet::Util::Windows::Error => e raise e unless e.code == SCHED_E_ACCOUNT_INFORMATION_NOT_SET warn _('job created, but password was invalid') end bool end |
#status ⇒ Object
Returns the status of the currently active task. Possible values are ‘ready’, ‘running’, ‘not scheduled’ or ‘unknown’.
699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 |
# File 'lib/puppet/util/windows/taskscheduler.rb', line 699 def status raise Error.new(_('No currently active task. ITask is NULL.')) if @pITask.nil? st = nil FFI::MemoryPointer.new(:hresult, 1) do |ptr| @pITask.GetStatus(ptr) st = ptr.read_hresult end case st when SCHED_S_TASK_READY status = 'ready' when SCHED_S_TASK_RUNNING status = 'running' when SCHED_S_TASK_NOT_SCHEDULED status = 'not scheduled' else status = 'unknown' end status end |
#terminate ⇒ Object
Terminate the current task.
305 306 307 308 309 |
# File 'lib/puppet/util/windows/taskscheduler.rb', line 305 def terminate raise Error.new(_('No currently active task. ITask is NULL.')) if @pITask.nil? @pITask.Terminate end |
#trigger(index) ⇒ Object
Returns a hash that describes the trigger at the given index for the current task.
622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 |
# File 'lib/puppet/util/windows/taskscheduler.rb', line 622 def trigger(index) raise Error.new(_('No current task scheduler. ITaskScheduler is NULL.')) if @pITS.nil? raise Error.new(_('No currently active task. ITask is NULL.')) if @pITask.nil? trigger = {} @pITask.UseInstance(COM::TaskTrigger, :GetTrigger, index) do |pITaskTrigger| FFI::MemoryPointer.new(COM::TASK_TRIGGER.size) do |task_trigger_ptr| pITaskTrigger.GetTrigger(task_trigger_ptr) trigger = populate_hash_from_trigger(COM::TASK_TRIGGER.new(task_trigger_ptr)) end end trigger end |
#trigger=(trigger) ⇒ Object
Sets the trigger for the currently active task.
640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 |
# File 'lib/puppet/util/windows/taskscheduler.rb', line 640 def trigger=(trigger) raise Error.new(_('No current task scheduler. ITaskScheduler is NULL.')) if @pITS.nil? raise Error.new(_('No currently active task. ITask is NULL.')) if @pITask.nil? raise TypeError unless trigger.is_a?(Hash) FFI::MemoryPointer.new(:word, 1) do |trigger_index_ptr| # Without the 'enum.include?' check above the code segfaults here if the # task already exists. This should probably be handled properly instead # of simply avoiding the issue. @pITask.UseInstance(COM::TaskTrigger, :CreateTrigger, trigger_index_ptr) do |pITaskTrigger| populate_trigger(pITaskTrigger, trigger) end end trigger end |
#trigger_count ⇒ Object
Returns the number of triggers associated with the active task.
595 596 597 598 599 600 601 602 603 604 605 606 607 |
# File 'lib/puppet/util/windows/taskscheduler.rb', line 595 def trigger_count raise Error.new(_('No current task scheduler. ITaskScheduler is NULL.')) if @pITS.nil? raise Error.new(_('No currently active task. ITask is NULL.')) if @pITask.nil? count = 0 FFI::MemoryPointer.new(:word, 1) do |ptr| @pITask.GetTriggerCount(ptr) count = ptr.read_word end count end |
#working_directory ⇒ Object
Returns the working directory for the task.
469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 |
# File 'lib/puppet/util/windows/taskscheduler.rb', line 469 def working_directory raise Error.new(_('No current task scheduler. ITaskScheduler is NULL.')) if @pITS.nil? raise Error.new(_('No currently active task. ITask is NULL.')) if @pITask.nil? dir = nil FFI::MemoryPointer.new(:pointer) do |ptr| @pITask.GetWorkingDirectory(ptr) ptr.read_com_memory_pointer do |str_ptr| dir = str_ptr.read_arbitrary_wide_string_up_to(MAX_PATH) if ! str_ptr.null? end end dir end |
#working_directory=(dir) ⇒ Object
Sets the working directory for the task.
488 489 490 491 492 493 494 495 496 497 498 499 500 |
# File 'lib/puppet/util/windows/taskscheduler.rb', line 488 def working_directory=(dir) raise Error.new(_('No current task scheduler. ITaskScheduler is NULL.')) if @pITS.nil? raise Error.new(_('No currently active task. ITask is NULL.')) if @pITask.nil? raise TypeError unless dir.is_a?(String) if dir.length > MAX_PATH raise Error.new(_("Working directory has exceeded maximum allowed length %{max}") % { max: MAX_PATH }) end @pITask.SetWorkingDirectory(wide_string(dir)) dir end |