delphitaskwindows-task-schedulercreation

Why is ITaskFolder.RegisterTaskDefinition not working?


I'm trying to programmatically create a task in Windows Task Scheduler using Delphi. Here's the code.

procedure TForm1.Button1Click(Sender: TObject);
var
  ts: ITaskService;
  tf: ITaskFolder;
  tf2: ITaskFolder;
  td: ITaskDefinition;
  tr: ITrigger;
  tt: ITimeTrigger;
  at: IAction;
  ae: IExecAction;
  rt: IRegisteredTask;
begin
  CoInitializeEx(nil, COINIT_MULTITHREADED);      
  CoCreateInstance(CLSID_TaskScheduler,nil,CLSCTX_INPROC_SERVER,IID_ITaskService,ts);
  ts.Connect(unassigned, unassigned, unassigned, unassigned);
  try
    tf := ts.GetFolder('\MyFolder');
    tf2 := tf;
  except
    tf := ts.GetFolder('\');
    tf2 := tf.CreateFolder('\MyFolder', unassigned);
  end;
  tf._Release;
  td := ts.NewTask(0);
  td.RegistrationInfo.Author := 'TheAuthor';
  tr := td.Triggers.Create(ttTime);
  tr.QueryInterface(IID_ITimeTrigger, tt);
  tr._Release;
  tt.Id := 'Trigger1';
  tt.StartBoundary := '2017-07-28T01:20:00';
  tt.EndBoundary := '2027-07-28T01:20:00';
  tt._Release;
  at := td.Actions.Create(taExec);
  at.QueryInterface(IID_IExecAction, ae);
  at._Release;
  ae.Path := 'C:\Windows\System32\Notepad.exe';
  ae.WorkingDirectory := 'C:\Windows\System32';
  ae.Arguments := '--help';
  ae._Release;
  rt := nil;
  rt := tf2.RegisterTaskDefinition('MyTestTask', td, 1, unassigned, unassigned, tlInteractiveToken, '');
  rt._Release;
  td._Release;
  tf2._Release;
  CoUninitialize;
end;

It works fine until RegisterTaskDefinition method. It returns nil and I think it's an error cause no task is created in my directory in C:\Windows\System32\Tasks. The directory MyFolder is creating properly.

But I can't even define error type cause there is no error codes returning in Delphi version of TaskScheduler api 2.0. It seems that all parameters of the function are correct but it continues to return nil instead of IRegisteredTask object.

Maybe I forgot something, or am doing something wrong?

I work on Windows 7 and Delphi XE 10.2. UAC is turned off.


Solution

  • You are calling the RegisterTaskDefinition method with TASK_VALIDATE_ONLY flag. That flag is described like:

    TASK_VALIDATE_ONLY

    Task Scheduler verifies the syntax of the XML that describes the task, but does not register the task. This constant cannot be combined with the TASK_CREATE, TASK_UPDATE, or TASK_CREATE_OR_UPDATE values.

    So the call returns NULL pointer in the ppTask parameter because no task has been registered. If you weren't using magic constants and use proper defined constants like TASK_CREATE instead of 2 (or TASK_VALIDATE_ONLY instead of 1), you would find the problem pretty simply.