1
0
mirror of https://github.com/Ylianst/MeshAgent synced 2025-12-10 13:23:41 +00:00
Files
MeshAgent/modules/win-tasks.js
2022-10-05 00:03:07 -07:00

936 lines
30 KiB
JavaScript

/*
Copyright 2021 Intel Corporation
@author Bryan Roe
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const CUSTOM_HANDLER = 0x80000000;
const GM = require('_GenericMarshal');
const CLSID_TaskScheduler = '{0f87369f-a4e5-4cfc-bd3e-73e6154572dd}';
const IID_TimeTrigger = '{b45747e0-eba7-4276-9f29-85c5bb300006}';
const IID_ExecAction = '{4c3d624d-fd6b-49a3-b9b7-09cb3cd3f047}';
const VT_EMPTY = 0;
const VT_NULL = 1;
const VT_SAFEARRAY = 27;
const VT_BSTR = 8;
const VT_ARRAY = 0x2000;
const TASK_LOGON_NONE = 0;
const TASK_LOGON_PASSWORD = 1;
const TASK_LOGON_S4U = 2;
const TASK_LOGON_INTERACTIVE_TOKEN = 3;
const TASK_LOGON_GROUP = 4;
const TASK_LOGON_SERVICE_ACCOUNT = 5;
const TASK_LOGON_INTERACTIVE_TOKEN_OR_PASSWORD = 6;
const TASK_TRIGGER_EVENT = 0;
const TASK_TRIGGER_TIME = 1;
const TASK_TRIGGER_DAILY = 2;
const TASK_TRIGGER_WEEKLY = 3;
const TASK_TRIGGER_MONTHLY = 4;
const TASK_TRIGGER_MONTHLYDOW = 5;
const TASK_TRIGGER_IDLE = 6;
const TASK_TRIGGER_REGISTRATION = 7;
const TASK_TRIGGER_BOOT = 8;
const TASK_TRIGGER_LOGON = 9;
const TASK_TRIGGER_SESSION_STATE_CHANGE = 11;
const TASK_TRIGGER_CUSTOM_TRIGGER_01 = 12;
const TASK_ACTION_EXEC = 0;
const TASK_ACTION_COM_HANDLER = 5;
const TASK_ACTION_SEND_EMAIL = 6;
const TASK_ACTION_SHOW_MESSAGE = 7;
const TASK_VALIDATE_ONLY = 0x1;
const TASK_CREATE = 0x2;
const TASK_UPDATE = 0x4;
const TASK_CREATE_OR_UPDATE = (TASK_CREATE | TASK_UPDATE);
const TASK_DISABLE = 0x8;
const TASK_DONT_ADD_PRINCIPAL_ACE = 0x10;
const TASK_IGNORE_REGISTRATION_TRIGGERS = 0x20;
var OleAut32 = GM.CreateNativeProxy('OleAut32.dll');
OleAut32.CreateMethod('SafeArrayAccessData'); // https://learn.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-safearrayaccessdata
OleAut32.CreateMethod('SafeArrayCreate'); // https://learn.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-safearraycreate
OleAut32.CreateMethod('SafeArrayCreateVector'); // https://learn.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-safearraycreatevector
OleAut32.CreateMethod('SafeArrayPutElement'); // https://learn.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-safearrayputelement
OleAut32.CreateMethod('SafeArrayDestroy'); // https://learn.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-safearraydestroy
OleAut32.CreateMethod('VariantClear'); // https://learn.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-variantclear
OleAut32.CreateMethod('VariantInit'); // https://learn.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-variantinit
OleAut32.CreateMethod('SysAllocString'); // https://learn.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-sysallocstring
//
// This function converts an array of strings, to a variant array of BSTR
//
function ConvertStringArray(strarr)
{
if (!strarr || !Array.isArray(strarr)) { return (GM.CreateVariable(24)); }
var i, tmp;
var v = GM.CreateVariable(24);
v._tmp = [];
var ix = GM.CreateVariable(4);
console.info1('strarr.length=' + strarr.length);
var safe = OleAut32.SafeArrayCreateVector(VT_BSTR, 0, strarr.length);
if(safe.Val == 0)
{
throw('Error creating SafeArray');
}
for(i=0;i<strarr.length;++i)
{
ix.toBuffer().writeUInt32LE(i);
tmp = GM.CreateVariable(strarr[i], { wide: true });
v._tmp.push(tmp);
var ss = OleAut32.SysAllocString(tmp);
console.info1('SafeArrayPutElement: ' + OleAut32.SafeArrayPutElement(safe, ix, ss).Val);
}
OleAut32.VariantClear(v);
v.toBuffer().writeUInt16LE(VT_ARRAY | VT_BSTR);
safe.pointerBuffer().copy(v.toBuffer(), 8);
//v._debug();
return (v);
}
const UnknownFunctions =
[
'QueryInterface',
'AddRef',
'Release'
];
//
// Reference for ITaskService interface can be found at:
// https://learn.microsoft.com/en-us/windows/win32/api/taskschd/nn-taskschd-itaskservice
//
const TaskServiceFunctions =
[
'QueryInterface',
'AddRef',
'Release',
'GetTypeInfoCount',
'GetTypeInfo',
'GetIDsOfNames',
'Invoke',
'GetFolder',
'GetRunningTasks',
'NewTask',
'Connect',
'get_Connected',
'get_TargetServer',
'get_ConnectedUser',
'get_ConnectedDomain',
'get_HighestVersion'
];
//
// Reference for ITaskFolder interface can be found at:
// https://learn.microsoft.com/en-us/windows/win32/api/taskschd/nn-taskschd-itaskfolder
//
const TaskFolderFunctions =
[
'QueryInterface',
'AddRef',
'Release',
'GetTypeInfoCount',
'GetTypeInfo',
'GetIDsOfNames',
'Invoke',
'get_Name',
'get_Path',
'GetFolder',
'GetFolders',
'CreateFolder',
'DeleteFolder',
'GetTask',
'GetTasks',
'DeleteTask',
'RegisterTask',
'RegisterTaskDefinition',
'GetSecurityDescriptor',
'SetSecurityDescriptor'
];
//
// Reference for IRegistrationInfo interface can be found at:
// https://learn.microsoft.com/en-us/windows/win32/api/taskschd/nn-taskschd-iregistrationinfo
//
const RegistrationInfoFunctions =
[
'QueryInterface',
'AddRef',
'Release',
'GetTypeInfoCount',
'GetTypeInfo',
'GetIDsOfNames',
'Invoke',
'get_Description',
'put_Description',
'get_Author',
'put_Author',
'get_Version',
'put_Version',
'get_Date',
'put_Date',
'get_Documentation',
'put_Documentation',
'get_XmlText',
'put_XmlText',
'get_URI',
'put_URI',
'get_SecurityDescriptor',
'put_SecurityDescriptor',
'get_Source',
'put_Source'
];
//
// Reference for ITaskDefinition interface can be found at:
// https://learn.microsoft.com/en-us/windows/win32/api/taskschd/nn-taskschd-itaskdefinition
//
const TaskDefinitionFunctions =
[
'QueryInterface',
'AddRef',
'Release',
'GetTypeInfoCount',
'GetTypeInfo',
'GetIDsOfNames',
'Invoke',
'get_RegistrationInfo',
'put_RegistrationInfo',
'get_Triggers',
'put_Triggers',
'get_Settings',
'put_Settings',
'get_Data',
'put_Data',
'get_Principal',
'put_Principal',
'get_Actions',
'put_Actions',
'get_XmlText',
'put_XmlText'
];
//
// Reference for IPrincipal interface can be found at:
// https://learn.microsoft.com/en-us/windows/win32/api/taskschd/nn-taskschd-iprincipal
//
const PrincipalFunctions =
[
'QueryInterface',
'AddRef',
'Release',
'GetTypeInfoCount',
'GetTypeInfo',
'GetIDsOfNames',
'Invoke',
'get_Id',
'put_Id',
'get_DisplayName',
'put_DisplayName',
'get_UserId',
'put_UserId',
'get_LogonType',
'put_LogonType',
'get_GroupId',
'put_GroupId',
'get_RunLevel',
'put_RunLevel'
];
//
// Reference for ITaskSettings interface can be found at:
// https://learn.microsoft.com/en-us/windows/win32/api/taskschd/nn-taskschd-itasksettings
//
const TaskSettingsFunctions =
[
'QueryInterface',
'AddRef',
'Release',
'GetTypeInfoCount',
'GetTypeInfo',
'GetIDsOfNames',
'Invoke',
'get_AllowDemandStart',
'put_AllowDemandStart',
'get_RestartInterval',
'put_RestartInterval',
'get_RestartCount',
'put_RestartCount',
'get_MultipleInstances',
'put_MultipleInstances',
'get_StopIfGoingOnBatteries',
'put_StopIfGoingOnBatteries',
'get_DisallowStartIfOnBatteries',
'put_DisallowStartIfOnBatteries',
'get_AllowHardTerminate',
'put_AllowHardTerminate',
'get_StartWhenAvailable',
'put_StartWhenAvailable',
'get_XmlText',
'put_XmlText',
'get_RunOnlyIfNetworkAvailable',
'put_RunOnlyIfNetworkAvailable',
'get_ExecutionTimeLimit',
'put_ExecutionTimeLimit',
'get_Enabled',
'put_Enabled',
'get_DeleteExpiredTaskAfter',
'put_DeleteExpiredTaskAfter',
'get_Priority',
'put_Priority',
'get_Compatibility',
'put_Compatibility',
'get_Hidden',
'put_Hidden',
'get_IdleSettings',
'put_IdleSettings',
'get_RunOnlyIfIdle',
'put_RunOnlyIfIdle',
'get_WakeToRun',
'put_WakeToRun',
'get_NetworkSettings',
'put_NetworkSettings'
];
//
// Reference for IIdleSettings interface can be found at:
// https://learn.microsoft.com/en-us/windows/win32/api/taskschd/nn-taskschd-iidlesettings
//
const IdleSettingsFunctions =
[
'QueryInterface',
'AddRef',
'Release',
'GetTypeInfoCount',
'GetTypeInfo',
'GetIDsOfNames',
'Invoke',
'get_IdleDuration',
'put_IdleDuration',
'get_WaitTimeout',
'put_WaitTimeout',
'get_StopOnIdleEnd',
'put_StopOnIdleEnd',
'get_RestartOnIdle',
'put_RestartOnIdle'
];
//
// Reference for ITriggerCollection interface can be found at:
// https://learn.microsoft.com/en-us/windows/win32/api/taskschd/nn-taskschd-itriggercollection
//
const TriggerCollectionFunctions =
[
'QueryInterface',
'AddRef',
'Release',
'GetTypeInfoCount',
'GetTypeInfo',
'GetIDsOfNames',
'Invoke',
'get_Count',
'get_Item',
'get__NewEnum',
'Create',
'Remove',
'Clear'
];
//
// Reference for ITrigger interface can be found at:
// https://learn.microsoft.com/en-us/windows/win32/api/taskschd/nn-taskschd-itrigger
//
const TriggerFunctions =
[
'QueryInterface',
'AddRef',
'Release',
'GetTypeInfoCount',
'GetTypeInfo',
'GetIDsOfNames',
'Invoke',
'get_Type',
'get_Id',
'put_Id',
'get_Repetition',
'put_Repetition',
'get_ExecutionTimeLimit',
'put_ExecutionTimeLimit',
'get_StartBoundary',
'put_StartBoundary',
'get_EndBoundary',
'put_EndBoundary',
'get_Enabled',
'put_Enabled'
];
//
// Reference for ITimeTrigger interface can be found at:
// https://learn.microsoft.com/en-us/windows/win32/api/taskschd/nn-taskschd-itimetrigger
//
const TimeTriggerFunctions =
[
'QueryInterface',
'AddRef',
'Release',
'GetTypeInfoCount',
'GetTypeInfo',
'GetIDsOfNames',
'Invoke',
'get_Type',
'get_Id',
'put_Id',
'get_Repetition',
'put_Repetition',
'get_ExecutionTimeLimit',
'put_ExecutionTimeLimit',
'get_StartBoundary',
'put_StartBoundary',
'get_EndBoundary',
'put_EndBoundary',
'get_Enabled',
'put_Enabled',
'get_RandomDelay',
'put_RandomDelay'
];
//
// Reference for IActionCollection interface can be found at:
// https://learn.microsoft.com/en-us/windows/win32/api/taskschd/nn-taskschd-iactioncollection
//
const ActionCollectionFunctions =
[
'QueryInterface',
'AddRef',
'Release',
'GetTypeInfoCount',
'GetTypeInfo',
'GetIDsOfNames',
'Invoke',
'get_Count',
'get_Item',
'get__NewEnum',
'get_XmlText',
'put_XmlText',
'Create',
'Remove',
'Clear',
'get_Context',
'put_Context'
];
//
// Reference for IAction interface can be found at:
// https://learn.microsoft.com/en-us/windows/win32/api/taskschd/nn-taskschd-iaction
//
const ActionFunctions =
[
'QueryInterface',
'AddRef',
'Release',
'GetTypeInfoCount',
'GetTypeInfo',
'GetIDsOfNames',
'Invoke',
'get_Id',
'put_Id',
'get_Type'
];
//
// Reference for IExecAction interface can be found at:
// https://learn.microsoft.com/en-us/windows/win32/api/taskschd/nn-taskschd-iexecaction
//
const ExecActionFunctions =
[
'QueryInterface',
'AddRef',
'Release',
'GetTypeInfoCount',
'GetTypeInfo',
'GetIDsOfNames',
'Invoke',
'get_Id',
'put_Id',
'get_Type',
'get_Path',
'put_Path',
'get_Arguments',
'put_Arguments',
'get_WorkingDirectory',
'put_WorkingDirectory'
];
//
// Reference for IRegisteredTask interface can be found at:
// https://learn.microsoft.com/en-us/windows/win32/api/taskschd/nn-taskschd-iregisteredtask
//
const RegisteredTaskFunctions =
[
'QueryInterface',
'AddRef',
'Release',
'GetTypeInfoCount',
'GetTypeInfo',
'GetIDsOfNames',
'Invoke',
'get_Name',
'get_Path',
'get_State',
'get_Enabled',
'put_Enabled',
'Run',
'RunEx',
'GetInstances',
'get_LastRunTime',
'get_LastTaskResult',
'get_NumberOfMissedRuns',
'get_NextRunTime',
'get_Definition',
'get_Xml',
'GetSecurityDescriptor',
'SetSecurityDescriptor',
'Stop',
'GetRunTimes'
];
//
// JavaScript abstraction for Task. This constructor adds the "Run" function, and
// adds a finalizer to handle cleanup and unregistration
//
function taskObject(j)
{
this._task = j;
this.run = function run(arr)
{
var val = ConvertStringArray(arr);
var running = GM.CreatePointer();
this._task.funcs.Run(this._task.Deref(), val, running);
};
require('events').EventEmitter.call(this);
this.once('~', function ()
{
this._task._rf.funcs.Release(this._task._rf.Deref());
this._task._ts.funcs.Release(this._task._ts);
this._task._rf = null;
this._task._ts = null;
this._task = null;
console.info1('taskObject Finalized');
})
}
//
// Finds and returns the specified Task
//
function getTask(options)
{
var hr;
var serverName = GM.CreateVariable(24);
var user = GM.CreateVariable(24);
var domain = GM.CreateVariable(24);
var password = GM.CreateVariable(24);
var rootFolder = GM.CreatePointer();
var task = GM.CreatePointer();
// Connect to the TaskScheduler COM object
var taskService = require('win-com').createInstance(require('win-com').CLSIDFromString(CLSID_TaskScheduler), require('win-com').IID_IUnknown);
taskService.funcs = require('win-com').marshalFunctions(taskService, TaskServiceFunctions);
taskService.funcs.Connect._callType = 1;
hr = taskService.funcs.Connect(taskService, serverName, user, domain, password);
if (hr.Val != 0)
{
taskService.funcs.Release(taskService);
throw ('ITaskService::Connect failed ' + hr.Val);
}
// Get the folder object
hr = taskService.funcs.GetFolder(taskService, GM.CreateVariable('\\', { wide: true }), rootFolder);
if (hr.Val != 0)
{
taskService.funcs.Release(taskService);
throw ('ITaskService failed to get Root folder ' + hr.Val);
}
rootFolder.funcs = require('win-com').marshalFunctions(rootFolder.Deref(), TaskFolderFunctions);
// Get the tasks for that folder object
hr = rootFolder.funcs.GetTask(rootFolder.Deref(), GM.CreateVariable(options.name, { wide: true }), task);
if (hr.Val != 0)
{
rootFolder.funcs.Release(rootFolder.Deref());
taskService.funcs.Release(taskService);
throw ('Failed to get Task: ' + options.name + ' [' + hr.Val + ']');
}
task.funcs = require('win-com').marshalFunctions(task.Deref(), RegisteredTaskFunctions);
task.funcs.Run._callType = CUSTOM_HANDLER | 2; // This must be declared like this, so that VARIANT can be marshaled correctly
task._rf = rootFolder;
task._ts = taskService;
return (new taskObject(task));
}
//
// Delete a scheduled task
//
function deleteTask(options)
{
if (typeof (options) == 'string') { options = { name: options } }
var hr;
var serverName = GM.CreateVariable(24);
var user = GM.CreateVariable(24);
var domain = GM.CreateVariable(24);
var password = GM.CreateVariable(24);
var rootFolder = GM.CreatePointer();
// Instantiate and connect to the Window Task Scheduler service
var taskService = require('win-com').createInstance(require('win-com').CLSIDFromString(CLSID_TaskScheduler), require('win-com').IID_IUnknown);
taskService.funcs = require('win-com').marshalFunctions(taskService, TaskServiceFunctions);
hr = taskService.funcs.Connect._callType = 1;
hr = taskService.funcs.Connect(taskService, serverName, user, domain, password);
if (hr.Val != 0)
{
taskService.funcs.Release(taskService);
throw ('ITaskService::Connect failed ' + hr.Val);
}
// Get the root folder
hr = taskService.funcs.GetFolder(taskService, GM.CreateVariable('\\', { wide: true }), rootFolder);
if (hr.Val != 0)
{
taskService.funcs.Release(taskService);
throw ('ITaskService failed to get Root folder ' + hr.Val);
}
console.info1('Deleting Task: ' + options.name);
rootFolder.funcs = require('win-com').marshalFunctions(rootFolder.Deref(), TaskFolderFunctions);
// Delete the specified task
hr = rootFolder.funcs.DeleteTask(rootFolder.Deref(), GM.CreateVariable(options.name, { wide: true }), 0);
if (hr.Val != 0)
{
rootFolder.funcs.Release(rootFolder.Deref());
taskService.funcs.Release(taskService);
throw ('Could not delete Task: ' + options.name);
}
rootFolder.funcs.Release(rootFolder.Deref());
taskService.funcs.Release(taskService);
}
//
// Add a new task to the Windows Task Scheduler
//
function addTask(options)
{
// Set some defaults if they are not specified
if (!options) { throw ('Need to specify options object'); }
if (!options.author) { options.author = 'win-task'; }
if (!options.id) { options.id = 'win-task'; }
if (!options.startTime) { options.startTime = '2021-01-01T00:00'; }
if (!options.endTime) { options.endTime = '2021-01-01T00:30'; }
// Instantiate the Windows Task Scheduler service
var taskService = require('win-com').createInstance(require('win-com').CLSIDFromString(CLSID_TaskScheduler), require('win-com').IID_IUnknown);
taskService.funcs = require('win-com').marshalFunctions(taskService, TaskServiceFunctions);
var hr;
var serverName = GM.CreateVariable(24);
var user = GM.CreateVariable(24);
var domain = GM.CreateVariable(24);
var password = GM.CreateVariable(24);
var rootFolder = GM.CreatePointer();
var task = GM.CreatePointer();
var regInfo = GM.CreatePointer();
var principal = GM.CreatePointer();
var taskSettings = GM.CreatePointer();
var triggerCollection = GM.CreatePointer();
var unknownTrigger = GM.CreatePointer();
var timeTrigger = GM.CreatePointer();
var actionCollection = GM.CreatePointer();
var taskAction = GM.CreatePointer();
var execAction = GM.CreatePointer();
var registeredTask = GM.CreatePointer();
// Connect to the Task Scheduler
taskService.funcs.Connect._callType = 1;
hr = taskService.funcs.Connect(taskService, serverName, user, domain, password);
if (hr.Val != 0)
{
taskService.funcs.Release(taskService);
throw ('ITaskService::Connect failed ' + hr.Val);
}
hr = taskService.funcs.GetFolder(taskService, GM.CreateVariable('\\', { wide: true }), rootFolder);
if (hr.Val != 0)
{
taskService.funcs.Release(taskService);
throw ('ITaskService failed to get Root folder ' + hr.Val);
}
rootFolder.funcs = require('win-com').marshalFunctions(rootFolder.Deref(), TaskFolderFunctions);
// Create an empty task
hr = taskService.funcs.NewTask(taskService, 0, task);
taskService.funcs.Release(taskService); // No longer needed going forward
if (hr.Val != 0)
{
rootFolder.funcs.Release(rootFolder.Deref());
throw ('ITaskService failed to create new task ' + hr.Val);
}
// Fetch the registration data for the ampty task
task.funcs = require('win-com').marshalFunctions(task.Deref(), TaskDefinitionFunctions);
hr = task.funcs.get_RegistrationInfo(task.Deref(), regInfo);
if (hr.Val != 0)
{
rootFolder.funcs.Release(rootFolder.Deref());
task.funcs.Release(task.Deref());
throw ('ITaskService failed to get RegistrationInfo ' + hr.Val);
}
regInfo.funcs = require('win-com').marshalFunctions(regInfo.Deref(), RegistrationInfoFunctions);
regInfo.funcs.Release(regInfo.Deref()); // Not needed going forward
hr = regInfo.funcs.put_Author(regInfo.Deref(), GM.CreateVariable(options.author, {wide: true}));
if (hr.Val != 0)
{
rootFolder.funcs.Release(rootFolder.Deref());
task.funcs.Release(task.Deref());
throw ('ITaskService failed to put Author ' + hr.Val);
}
if (options.userID != null || options.user)
{
if (options.user == 'SYSTEM') { options.userID = 'S-1-5-18'; } // If the task is to run as SYSTEM, set the security descriptor for SYSTEM
hr = task.funcs.get_Principal(task.Deref(), principal);
if (hr.Val != 0)
{
rootFolder.funcs.Release(rootFolder.Deref());
task.funcs.Release(task.Deref());
throw ('ITaskService failed to get Principal ' + hr.Val);
}
principal.funcs = require('win-com').marshalFunctions(principal.Deref(), PrincipalFunctions);
if (!options.userID && options.user && options.user != 'SYSTEM')
{
try
{
// If the task is to run as user, we need to fetch the Windows Security Descriptor for that user
options.userID = require('win-registry').usernameToUserKey({ user: options.user, domain: options.domain });
}
catch (z)
{
principal.funcs.Release(principal.Deref()); // No longer needed
rootFolder.funcs.Release(rootFolder.Deref());
task.funcs.Release(task.Deref());
throw ('ITaskService failed to resolve username: ' + options.user + ' ' + hr.Val);
}
}
hr = principal.funcs.put_LogonType(principal.Deref(), (options.user == 'SYSTEM' ? TASK_LOGON_SERVICE_ACCOUNT : TASK_LOGON_INTERACTIVE_TOKEN));
if (hr.Val != 0)
{
principal.funcs.Release(principal.Deref()); // No longer needed
rootFolder.funcs.Release(rootFolder.Deref());
task.funcs.Release(task.Deref());
throw ('ITaskService failed to put logonType ' + hr.Val);
}
if (options.userID)
{
// Set the security descriptor for the task
hr = principal.funcs.put_UserId(principal.Deref(), GM.CreateVariable(options.userID, { wide: true }));
if (hr.Val != 0)
{
principal.funcs.Release(principal.Deref()); // No longer needed
rootFolder.funcs.Release(rootFolder.Deref());
task.funcs.Release(task.Deref());
throw ('ITaskService failed to put user id ' + hr.Val);
}
}
principal.funcs.Release(principal.Deref()); // No longer needed
}
hr = task.funcs.get_Settings(task.Deref(), taskSettings);
if (hr.Val != 0)
{
rootFolder.funcs.Release(rootFolder.Deref());
task.funcs.Release(task.Deref());
throw ('ITaskService failed to get settings ' + hr.Val);
}
taskSettings.funcs = require('win-com').marshalFunctions(taskSettings.Deref(), TaskSettingsFunctions);
// Set some atrtibutes, so that the task will run, regardless of AC power state and network state
if(taskSettings.funcs.put_StopIfGoingOnBatteries(taskSettings.Deref(), 0).Val != 0 ||
taskSettings.funcs.put_DisallowStartIfOnBatteries(taskSettings.Deref(), 0).Val != 0 ||
taskSettings.funcs.put_RunOnlyIfNetworkAvailable(taskSettings.Deref(), 0).Val != 0)
{
rootFolder.funcs.Release(rootFolder.Deref());
task.funcs.Release(task.Deref());
throw ('ITaskService failed to set attributes ' + hr.Val);
}
hr = task.funcs.get_Triggers(task.Deref(), triggerCollection);
if (hr.Val != 0)
{
rootFolder.funcs.Release(rootFolder.Deref());
task.funcs.Release(task.Deref());
throw ('ITaskService failed to get Triggers ' + hr.Val);
}
triggerCollection.funcs = require('win-com').marshalFunctions(triggerCollection.Deref(), TriggerCollectionFunctions);
// Create the trigger
hr = triggerCollection.funcs.Create(triggerCollection.Deref(), TASK_TRIGGER_TIME, unknownTrigger);
if (hr.Val != 0)
{
rootFolder.funcs.Release(rootFolder.Deref());
task.funcs.Release(task.Deref());
throw ('ITaskService failed to get create trigger ' + hr.Val);
}
unknownTrigger.funcs = require('win-com').marshalFunctions(unknownTrigger.Deref(), UnknownFunctions);
hr = unknownTrigger.funcs.QueryInterface(unknownTrigger.Deref(), require('win-com').IIDFromString(IID_TimeTrigger), timeTrigger);
if (hr.Val != 0)
{
rootFolder.funcs.Release(rootFolder.Deref());
task.funcs.Release(task.Deref());
throw ('QueryInterface failed for IID_TimeTrigger ' + hr.Val);
}
timeTrigger.funcs = require('win-com').marshalFunctions(unknownTrigger.Deref(), TimeTriggerFunctions);
hr = timeTrigger.funcs.put_Id(timeTrigger.Deref(), GM.CreateVariable(options.id, { wide: true }));
if (hr.Val != 0)
{
rootFolder.funcs.Release(rootFolder.Deref());
task.funcs.Release(task.Deref());
throw ('ITaskService failed to get put TriggerID ' + hr.Val);
}
// Set the start time
hr = timeTrigger.funcs.put_StartBoundary(timeTrigger.Deref(), GM.CreateVariable(options.startTime, { wide: true }));
if (hr.Val != 0)
{
rootFolder.funcs.Release(rootFolder.Deref());
task.funcs.Release(task.Deref());
throw ('ITaskService failed to set StartBoundary ' + hr.Val);
}
// Set the end time, if specified
if (options.endTime)
{
hr = timeTrigger.funcs.put_EndBoundary(timeTrigger.Deref(), GM.CreateVariable(options.endTime, { wide: true }));
if(hr.Val!=0)
{
rootFolder.funcs.Release(rootFolder.Deref());
task.funcs.Release(task.Deref());
throw ('ITaskService failed to set EndBoundary ' + hr.Val);
}
}
// Fetch the ActionCollection
hr = task.funcs.get_Actions(task.Deref(), actionCollection);
if (hr.Val != 0)
{
rootFolder.funcs.Release(rootFolder.Deref());
task.funcs.Release(task.Deref());
throw ('ITaskService failed to get Actions ' + hr.Val);
}
actionCollection.funcs = require('win-com').marshalFunctions(actionCollection.Deref(), ActionCollectionFunctions);
// Now we're going to create an ExecAction
hr = actionCollection.funcs.Create(actionCollection.Deref(), TASK_ACTION_EXEC, taskAction);
if (hr.Val != 0)
{
rootFolder.funcs.Release(rootFolder.Deref());
task.funcs.Release(task.Deref());
throw ('ITaskService failed to create Task ' + hr.Val);
}
taskAction.funcs = require('win-com').marshalFunctions(taskAction.Deref(), ActionFunctions);
hr = taskAction.funcs.QueryInterface(taskAction.Deref(), require('win-com').IIDFromString(IID_ExecAction), execAction);
if (hr.Val != 0)
{
rootFolder.funcs.Release(rootFolder.Deref());
task.funcs.Release(task.Deref());
throw ('QueryInterface failed for IID_ExecAction ' + hr.Val);
}
execAction.funcs = require('win-com').marshalFunctions(execAction.Deref(), ExecActionFunctions);
hr = execAction.funcs.put_Path(execAction.Deref(), GM.CreateVariable(options.execPath, { wide: true }));
if (hr.Val != 0)
{
rootFolder.funcs.Release(rootFolder.Deref());
task.funcs.Release(task.Deref());
throw ('ITaskService failed to put action path ' + hr.Val);
}
// Set the exec arguments if specified
if (options.arguments && Array.isArray(options.arguments))
{
hr = execAction.funcs.put_Arguments(execAction.Deref(), GM.CreateVariable(options.arguments.join(' '), { wide: true }));
if (hr.Val != 0)
{
rootFolder.funcs.Release(rootFolder.Deref());
task.funcs.Release(task.Deref());
throw ('ITaskService failed to put action arguments ' + hr.Val);
}
}
// Set the working path if specified
if (options.workingDirectory)
{
hr = execAction.funcs.put_WorkingDirectory(execAction.Deref(), GM.CreateVariable(options.workingDirectory, { wide: true }));
if (hr.Val != 0)
{
rootFolder.funcs.Release(rootFolder.Deref());
task.funcs.Release(task.Deref());
throw ('ITaskService failed to put working directory ' + hr.Val);
}
}
// Register the new task
var vvar = GM.CreateVariable(GM.PointerSize == 8 ? 24 : 16);
rootFolder.funcs.RegisterTaskDefinition._callType = 1 | CUSTOM_HANDLER;
hr = rootFolder.funcs.RegisterTaskDefinition(
rootFolder.Deref(),
GM.CreateVariable(options.name, { wide: true }),
task.Deref(),
TASK_CREATE_OR_UPDATE,
vvar,
vvar,
TASK_LOGON_INTERACTIVE_TOKEN,
GM.CreateVariable('', { wide: true }),
registeredTask);
rootFolder.funcs.Release(rootFolder.Deref());
task.funcs.Release(task.Deref());
if(hr.Val!=0)
{
throw ('ITaskService failed to register action ' + hr.Val);
}
}
module.exports =
{
addTask: addTask,
deleteTask: deleteTask,
getTask: getTask,
convert: ConvertStringArray
};