buildTaskXml function

String buildTaskXml(
  1. ServiceDescriptor d, {
  2. required String logPath,
  3. String? currentUser,
})

Builds the Task Scheduler definition XML for d.

System scope runs at boot as LocalSystem (S-1-5-18) with elevation; user scope runs at logon for currentUser with an S4U token ("run whether the user is logged on or not") so the daemon runs in a non-interactive session — it shows no console window and keeps running after logoff. The action is wrapped in cmd.exe /c so OMNYSHELL_HOME can be set inline (Task Scheduler has no per-task environment) and stdout/stderr can be appended to logPath. The task has no execution time limit (so the daemon is not killed after the default 72 h) and restarts on failure.

Implementation

String buildTaskXml(
  svc.ServiceDescriptor d, {
  required String logPath,
  String? currentUser,
}) {
  final system = d.scope == svc.ServiceScope.system;
  final args = _commandLine(d, logPath);

  final triggers = system
      ? '<BootTrigger><Enabled>true</Enabled></BootTrigger>'
      : '<LogonTrigger><Enabled>true</Enabled>'
            '${currentUser == null ? '' : '<UserId>${_xml(currentUser)}</UserId>'}'
            '</LogonTrigger>';

  final principal = system
      ? '<UserId>S-1-5-18</UserId>'
            '<RunLevel>HighestAvailable</RunLevel>'
      : '${currentUser == null ? '' : '<UserId>${_xml(currentUser)}</UserId>'}'
            '<LogonType>S4U</LogonType>'
            '<RunLevel>LeastPrivilege</RunLevel>';

  return '''
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
  <RegistrationInfo>
    <Description>${_xml(d.description)}</Description>
  </RegistrationInfo>
  <Triggers>
    $triggers
  </Triggers>
  <Principals>
    <Principal id="Author">
      $principal
    </Principal>
  </Principals>
  <Settings>
    <AllowStartOnDemand>true</AllowStartOnDemand>
    <RestartOnFailure>
      <Interval>PT1M</Interval>
      <Count>9999</Count>
    </RestartOnFailure>
    <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
    <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
    <StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
    <AllowHardTerminate>true</AllowHardTerminate>
    <StartWhenAvailable>true</StartWhenAvailable>
    <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
    <ExecutionTimeLimit>PT0S</ExecutionTimeLimit>
    <Priority>7</Priority>
    <Enabled>true</Enabled>
  </Settings>
  <Actions Context="Author">
    <Exec>
      <Command>cmd.exe</Command>
      <Arguments>${_xml(args)}</Arguments>
    </Exec>
  </Actions>
</Task>
''';
}