Help with windows scheduled task

Just starting out? Need help? Post your questions and find answers here.
xakep
User
User
Posts: 40
Joined: Fri Mar 25, 2016 2:02 pm
Location: Europe

Help with windows scheduled task

Post by xakep »

C++ code

For now, I have this code: (Credits to Fred)

Code: Select all

EnableExplicit

#CLSCTX_INPROC_SERVER = 1
#TASK_FLAG_SYSTEM_REQUIRED = $1000
#TASK_FLAG_RUN_ONLY_IF_LOGGED_ON = $2000
#TASK_FLAG_HIDDEN = $200
#TASK_FLAG_SYSTEM_REQUIRED = $1000
#TASK_FLAG_RUN_IF_CONNECTED_TO_INTERNET = $400

Interface ITaskTrigger Extends IUnknown
  
  GetTrigger(pTrigger.l)
  GetTriggerString(ppwszTrigger.l)
  SetTrigger(pTrigger.l)
EndInterface

; IEnumWorkItems interface definition
;
Interface IEnumWorkItems Extends IUnknown
  Next(a.l, b.l, c.l)
  Skip(a.l)
  Reset()
  Clone(a.l)
EndInterface

; ITaskScheduler interface definition
;
Interface ITaskScheduler Extends IUnknown
  SetTargetComputer(a.l)
  GetTargetComputer(a.l)
  Enum(a.l)
  Activate(a.l, b.l, c.l)
  Delete(a.l)
  NewWorkItem(a.l, b.l, c.l, d.l)
  AddWorkItem(a.l, b.l)
  IsOfType(a.l, b.l)
EndInterface

; ITask interface definition
;
Interface ITask Extends IUnknown
  CreateTrigger(a.l, b.l)
  DeleteTrigger(a.l)
  GetTriggerCount(a.l)
  GetTrigger(a.l, b.l)
  GetTriggerString(a.l, b.l)
  GetRunTimes(a.l, b.l, c.l, d.l)
  GetNextRunTime(a.l)
  SetIdleWait(a.l, b.l)
  GetIdleWait(a.l, b.l)
  Run()
  Terminate()
  EditWorkItem(a.l, b.l)
  GetMostRecentRunTime(a.l)
  GetStatus(a.l)
  GetExitCode(a.l)
  SetComment(a.l)
  GetComment(a.l)
  SetCreator(a.l)
  GetCreator(a.l)
  SetWorkItemData(a.l, b.l)
  GetWorkItemData(a.l, b.l)
  SetErrorRetryCount(a.l)
  GetErrorRetryCount(a.l)
  SetErrorRetryInterval(a.l)
  GetErrorRetryInterval(a.l)
  SetFlags(a.l)
  GetFlags(a.l)
  SetAccountInformation(a.l, b.l)
  GetAccountInformation(a.l)
  SetApplicationName(a.l)
  GetApplicationName(a.l)
  SetParameters(a.l)
  GetParameters(a.l)
  SetWorkingDirectory(a.l)
  GetWorkingDirectory(a.l)
  SetPriority(a.l)
  GetPriority(a.l)
  SetTaskFlags(a.l)
  GetTaskFlags(a.l)
  SetMaxRunTime(a.l)
  GetMaxRunTime(a.l)
EndInterface

Enumeration 0 ; TriggerType
  #TASK_TIME_TRIGGER_ONCE            = 0
  #TASK_TIME_TRIGGER_DAILY           = 1
  #TASK_TIME_TRIGGER_WEEKLY          = 2
  #TASK_TIME_TRIGGER_MONTHLYDATE     = 3
  #TASK_TIME_TRIGGER_MONTHLYDOW      = 4
  #TASK_EVENT_TRIGGER_ON_IDLE        = 5
  #TASK_EVENT_TRIGGER_AT_SYSTEMSTART = 6
  #TASK_EVENT_TRIGGER_AT_LOGON       = 7
EndEnumeration

Structure DAILY
  DaysInterval.w
EndStructure
Structure WEEKLY
  WeeksInterval.w
  rgfDaysOfTheWeek.w
EndStructure
Structure MONTHLYDATE
  rgfDays.l
  rgfMonths.w
EndStructure

Structure MONTHLYDOW
  wWhichWeek.w
  rgfDaysOfTheWeek.w
  rgfMonths.w
EndStructure

Structure TRIGGER_TYPE_UNION
  StructureUnion
    Daily.DAILY
    Weekly.WEEKLY
    MonthlyDate.MONTHLYDATE
    MonthlyDOW.MONTHLYDOW
  EndStructureUnion
EndStructure

Structure TASK_TRIGGER
  cbTriggerSize.w
  Reserved1.w
  wBeginYear.w
  wBeginMonth.w
  wBeginDay.w
  wEndYear.w
  wEndMonth.w
  wEndDay.w
  wStartHour.w
  wStartMinute.w
  MinutesDuration.l
  MinutesInterval.l
  rgFlags.l
  TriggerType.l ; TASK_TRIGGER_TYPE = Byte (0->7)
  Type.TRIGGER_TYPE_UNION
  Reserved2.w
  wRandomMinutesInterval.w
EndStructure

Procedure AddTask(sFile.s, TaskName.s)
  Define TaskScheduler.ITaskScheduler, *lpName.LONG, length.l, Filename.s, AppName.l, Task2.ITask, pIPersistFile.IPersistFile, pITaskTrigger.ITaskTrigger, Trigger.TASK_TRIGGER
  Define *TaskName, hr .l, *Target, tLen.l, piNewTrigger.w
  
  If CoInitialize_(0) = #S_OK
    If CoCreateInstance_(?CLSID_CTaskScheduler, 0, #CLSCTX_INPROC_SERVER, ?IID_ITaskScheduler, @TaskScheduler) = #S_OK
      
      tLen = Len(TaskName)
 
      *TaskName = AllocateMemory((Len(TaskName) * 2) + SizeOf(Character))
      *Target = AllocateMemory((Len(sFile) * 2) + SizeOf(Character))
      
      If *TaskName And *Target
        PokeS(*TaskName, TaskName)
        PokeS(*Target, sFile)
        
        ;hr = TaskScheduler\Activate(*TaskName, ?IID_ITask, @Task2)
        
        hr = TaskScheduler\NewWorkItem(*TaskName, ?CLSID_CTask, ?IID_ITask, @Task2)
  
        Debug "hr1:" + hr
        
        If hr <> #S_OK
          CoUninitialize_()
          ProcedureReturn #False  
        EndIf
        
        If hr = #S_OK
          hr = Task2\SetApplicationName(*Target)
          Debug "hr2:" + hr
   
          If hr <> #S_OK
            Task2\Release()
            TaskScheduler\Release()
            CoUninitialize_()
            ProcedureReturn #False
          EndIf
          
          If hr = #S_OK
            hr = Task2\SetFlags(#TASK_FLAG_RUN_ONLY_IF_LOGGED_ON|#TASK_FLAG_RUN_IF_CONNECTED_TO_INTERNET)
            
            If hr <> #S_OK
              Task2\Release()
            EndIf
            
            Debug "hr3:" + hr
            
            If hr = #S_OK
              
              hr = Task2\SetAccountInformation(@"", 0)
              
              Debug "hr4:" + hr
              
              If hr <> #S_OK
                Task2\Release()
              EndIf
              
              If hr = #S_OK
                  hr = Task2\CreateTrigger(@piNewTrigger, @pITaskTrigger)
  
                  Debug "hr5:" + hr
                  
                  If hr = #S_OK
                    ZeroMemory_(@Trigger, SizeOf(TASK_TRIGGER))
                    
                    Trigger\wBeginDay = 1
                    Trigger\wBeginMonth = 1
                    Trigger\wBeginYear = 1999
                    Trigger\cbTriggerSize = SizeOf(TASK_TRIGGER)
                    Trigger\TriggerType = #TASK_EVENT_TRIGGER_AT_LOGON ;9
                    
                    hr = pITaskTrigger\SetTrigger(@Trigger)
  
                    Debug "hr6:" + hr
                   
                    
                    If hr = #S_OK
                      hr = Task2\QueryInterface(?IID_IPersistFile, @pIPersistFile)
                      
                      Debug "hr7:" + hr
                      
                      If hr = #S_OK
                        hr = pIPersistFile\Save(#Null$, 1)
                        
                        Debug "hr8:" + hr
                        
                        pIPersistFile\Release()
                      EndIf
                    EndIf
                    
                    pITaskTrigger\Release()
                  EndIf
                EndIf
              
              Task2\Release()
            EndIf
          EndIf
          TaskScheduler\Release()
        EndIf
        FreeMemory(*TaskName)
        FreeMemory(*Target)
      EndIf
    EndIf
    
    CoUninitialize_()
  EndIf
EndProcedure

AddTask("C:\Windows\notepad.exee", "hi6")

DataSection
  IID_IPersistFile: ; [0000010b-0000-0000-C000-000000000046]
    Data.l $0000010B
    Data.w $0000, $0000
    Data.b $C0, $00, $00, $00, $00, $00, $00, $46
    
  CLSID_CTask: ; {148BD520-A2AB-11CE-B11F-00AA00530503}
    Data.l $148BD520
    Data.w $A2AB, $11CE
    Data.b $B1, $1F, $00, $AA, $00, $53, $05, $03
    
  IID_ITaskScheduler:  ; {148BD527-A2AB-11CE-B11F-00AA00530503}
    Data.l $148BD527
    Data.w $A2AB, $11CE
    Data.b $B1, $1F, $00, $AA, $00, $53, $05, $03

  CLSID_CTaskScheduler: ;  {148BD52A-A2AB-11CE-B11F-00AA00530503}
    Data.l $148BD52A
    Data.w $A2AB, $11CE
    Data.b $B1, $1F, $00, $AA, $00, $53, $05, $03
   
  IID_ITask:  ; {148BD524-A2AB-11CE-B11F-00AA00530503}
    Data.l $148BD524
    Data.w $A2AB, $11CE
    Data.b $B1, $1F, $00, $AA, $00, $53, $05, $03   

EndDataSection
The task is added, i can see it in task scheduler manager, but the trigger is not set right, it allways sets the trigger at the time task was added.
I want to do it so the task start at system startup, and i don't see what's wrong with my code.

Thanks for your time )
Axolotl
Enthusiast
Enthusiast
Posts: 450
Joined: Wed Dec 31, 2008 3:36 pm

Re: Help with windows scheduled task

Post by Axolotl »

hi,
sorry, I have not tested your code. I'm just wondering about this line:

Code: Select all

AddTask("C:\Windows\notepad.exee", "hi6")
Why do you use the additional e at 'exee' ???
Take care.
Andreas
Mostly running PureBasic <latest stable version and current alpha/beta> (x64) on Windows 11 Home
xakep
User
User
Posts: 40
Joined: Fri Mar 25, 2016 2:02 pm
Location: Europe

Re: Help with windows scheduled task

Post by xakep »

Yep, that's an mistake.
But the task is added even if Path doesn't exist, i had run the code with the correct Path and still the same in windows XP and 7.
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: Help with windows scheduled task

Post by Thunder93 »

That makes two of us. The code looks good, but the end result. Specifying trigger typed, is futile. It is persistent to use daily type regardless.

Almost looking like data overlapping issue. I'm on Windows 10, perhaps this is simply because this using older task scheduler Interfaces?
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: Help with windows scheduled task

Post by Thunder93 »

I've made some alterations to your code for conveniences. It still with the issue you experiencing.

One of the problems I've noticed, with setting of the flags #TASK_FLAG_RUN_ONLY_IF_* isn't enough without additional information. In the case with #TASK_FLAG_RUN_ONLY_IF_LOGGED_ON, you needed to supply the username in SetAccountInformation().

Code: Select all

EnableExplicit

#CLSCTX_INPROC_SERVER = 1
#TASK_FLAG_SYSTEM_REQUIRED = $1000
#TASK_FLAG_RUN_ONLY_IF_LOGGED_ON = $2000
#TASK_FLAG_HIDDEN = $200
#TASK_FLAG_SYSTEM_REQUIRED = $1000
#TASK_FLAG_RUN_IF_CONNECTED_TO_INTERNET = $400

Interface ITaskTrigger Extends IUnknown  
  GetTrigger(pTrigger.l)
  GetTriggerString(ppwszTrigger.l)
  SetTrigger(pTrigger.l)
EndInterface

; IEnumWorkItems interface definition
;
Interface IEnumWorkItems Extends IUnknown
Next(a.l, b.l, c.l)
Skip(a.l)
Reset()
Clone(a.l)
EndInterface

; ITaskScheduler interface definition
;
Interface ITaskScheduler Extends IUnknown
  SetTargetComputer(a.l)
  GetTargetComputer(a.l)
  Enum(a.l)
  Activate(a.l, b.l, c.l)
  Delete(a.l)
  NewWorkItem(a.l, b.l, c.l, d.l)
  AddWorkItem(a.l, b.l)
  IsOfType(a.l, b.l)
EndInterface

; ITask interface definition
;
Interface ITask Extends IUnknown
  CreateTrigger(a.l, b.l)
  DeleteTrigger(a.l)
  GetTriggerCount(a.l)
  GetTrigger(a.l, b.l)
  GetTriggerString(a.l, b.l)
  GetRunTimes(a.l, b.l, c.l, d.l)
  GetNextRunTime(a.l)
  SetIdleWait(a.l, b.l)
  GetIdleWait(a.l, b.l)
  Run()
  Terminate()
  EditWorkItem(a.l, b.l)
  GetMostRecentRunTime(a.l)
  GetStatus(a.l)
  GetExitCode(a.l)
  SetComment(a.l)
  GetComment(a.l)
  SetCreator(a.l)
  GetCreator(a.l)
  SetWorkItemData(a.l, b.l)
  GetWorkItemData(a.l, b.l)
  SetErrorRetryCount(a.l)
  GetErrorRetryCount(a.l)
  SetErrorRetryInterval(a.l)
  GetErrorRetryInterval(a.l)
  SetFlags(a.l)
  GetFlags(a.l)
  SetAccountInformation(a.l, b.l)
  GetAccountInformation(a.l)
  SetApplicationName(a.l)
  GetApplicationName(a.l)
  SetParameters(a.l)
  GetParameters(a.l)
  SetWorkingDirectory(a.l)
  GetWorkingDirectory(a.l)
  SetPriority(a.l)
  GetPriority(a.l)
  SetTaskFlags(a.l)
  GetTaskFlags(a.l)
  SetMaxRunTime(a.l)
  GetMaxRunTime(a.l)
EndInterface

Enumeration 0 ; TriggerType
  #TASK_TIME_TRIGGER_ONCE            = 0
  #TASK_TIME_TRIGGER_DAILY           = 1
  #TASK_TIME_TRIGGER_WEEKLY          = 2
  #TASK_TIME_TRIGGER_MONTHLYDATE     = 3
  #TASK_TIME_TRIGGER_MONTHLYDOW      = 4
  #TASK_EVENT_TRIGGER_ON_IDLE        = 5
  #TASK_EVENT_TRIGGER_AT_SYSTEMSTART = 6
  #TASK_EVENT_TRIGGER_AT_LOGON       = 7
EndEnumeration

Structure DAILY
  DaysInterval.w
EndStructure
Structure WEEKLY
  WeeksInterval.w
  rgfDaysOfTheWeek.w
EndStructure
Structure MONTHLYDATE
  rgfDays.l
  rgfMonths.w
EndStructure

Structure MONTHLYDOW
  wWhichWeek.w
  rgfDaysOfTheWeek.w
  rgfMonths.w
EndStructure

Structure TRIGGER_TYPE_UNION
  StructureUnion
    Daily.DAILY
    Weekly.WEEKLY
    MonthlyDate.MONTHLYDATE
    MonthlyDOW.MONTHLYDOW
  EndStructureUnion
EndStructure

Structure TASK_TRIGGER
  cbTriggerSize.w
  Reserved1.w
  wBeginYear.w
  wBeginMonth.w
  wBeginDay.w
  wEndYear.w
  wEndMonth.w
  wEndDay.w
  wStartHour.w
  wStartMinute.w
  MinutesDuration.l
  MinutesInterval.l
  rgFlags.l
  TriggerType.l ; TASK_TRIGGER_TYPE = Byte (0->7)
  Type.TRIGGER_TYPE_UNION
  Reserved2.w
  wRandomMinutesInterval.w
EndStructure

Procedure AddTask(sFile.s, TaskName.s)
  Protected TaskScheduler.ITaskScheduler, *lpName.LONG, AppName.l
  Protected Task2.ITask, pIPersistFile.IPersistFile, pITaskTrigger.ITaskTrigger, Trigger.TASK_TRIGGER
  Protected hr.l, piNewTrigger.w
  
  If Not Bool(sFile) And Not Bool(TaskName)
    ProcedureReturn 0
  EndIf
  
  
  If CoInitialize_(0) = #S_OK
    If CoCreateInstance_(?CLSID_CTaskScheduler, 0, #CLSCTX_INPROC_SERVER, ?IID_ITaskScheduler, @TaskScheduler) = #S_OK
      
      ;hr = TaskScheduler\Activate(*TaskName, ?IID_ITask, @Task2)
      
      hr = TaskScheduler\NewWorkItem(@TaskName, ?CLSID_CTask, ?IID_ITask, @Task2)
      
      Debug "hr1:" + hr
      
      If hr <> #S_OK
        CoUninitialize_()
        ProcedureReturn #False  
      EndIf
      
      If hr = #S_OK
        hr = Task2\SetApplicationName(@sFile)
        Debug "hr2:" + hr
        
        If hr <> #S_OK
          Task2\Release()
          TaskScheduler\Release()
          CoUninitialize_()
          ProcedureReturn #False
        EndIf
        
        If hr = #S_OK
          hr = Task2\SetFlags(#TASK_FLAG_RUN_ONLY_IF_LOGGED_ON|#TASK_FLAG_RUN_IF_CONNECTED_TO_INTERNET)
          
          If hr <> #S_OK
            Task2\Release()
          EndIf
          
          Debug "hr3:" + hr
          
          If hr = #S_OK
            
            Protected TaskUser.s = UserName()
            hr = Task2\SetAccountInformation(@TaskUser, 0)
            
            Debug "hr4:" + hr
            
            If hr <> #S_OK
              Task2\Release()
            EndIf
            
            If hr = #S_OK
              hr = Task2\CreateTrigger(@piNewTrigger, @pITaskTrigger)
              
              Debug "hr5:" + hr
              
              If hr = #S_OK
                ZeroMemory_(@Trigger, SizeOf(TASK_TRIGGER))
                
                Trigger\wBeginDay = 1
                Trigger\wBeginMonth = 1
                Trigger\wBeginYear = 1999
                Trigger\cbTriggerSize = SizeOf(TASK_TRIGGER)
                Trigger\TriggerType = #TASK_EVENT_TRIGGER_AT_LOGON ;9
                
                hr = pITaskTrigger\SetTrigger(@Trigger)
                
                Debug "hr6:" + hr
                
                
                If hr = #S_OK
                  hr = Task2\QueryInterface(?IID_IPersistFile, @pIPersistFile)
                  
                  Debug "hr7:" + hr
                  
                  If hr = #S_OK
                    hr = pIPersistFile\Save(#Null$, 1)
                    
                    Debug "hr8:" + hr
                    
                    pIPersistFile\Release()
                  EndIf
                EndIf
                
                pITaskTrigger\Release()
              EndIf
            EndIf
            
            Task2\Release()
          EndIf
        EndIf
        TaskScheduler\Release()
      EndIf
    EndIf
    
    CoUninitialize_()
  EndIf
EndProcedure

AddTask("C:\Windows\notepad.exe", "hi6")

DataSection
  IID_IPersistFile: ; [0000010b-0000-0000-C000-000000000046]
  Data.l $0000010B
  Data.w $0000, $0000
  Data.b $C0, $00, $00, $00, $00, $00, $00, $46
  
  CLSID_CTask: ; {148BD520-A2AB-11CE-B11F-00AA00530503}
  Data.l $148BD520
  Data.w $A2AB, $11CE
  Data.b $B1, $1F, $00, $AA, $00, $53, $05, $03
  
  IID_ITaskScheduler:  ; {148BD527-A2AB-11CE-B11F-00AA00530503}
  Data.l $148BD527
  Data.w $A2AB, $11CE
  Data.b $B1, $1F, $00, $AA, $00, $53, $05, $03
  
  CLSID_CTaskScheduler: ;  {148BD52A-A2AB-11CE-B11F-00AA00530503}
  Data.l $148BD52A
  Data.w $A2AB, $11CE
  Data.b $B1, $1F, $00, $AA, $00, $53, $05, $03
  
  IID_ITask:  ; {148BD524-A2AB-11CE-B11F-00AA00530503}
  Data.l $148BD524
  Data.w $A2AB, $11CE
  Data.b $B1, $1F, $00, $AA, $00, $53, $05, $03   
  
EndDataSection
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
xakep
User
User
Posts: 40
Joined: Fri Mar 25, 2016 2:02 pm
Location: Europe

Re: Help with windows scheduled task

Post by xakep »

Thunder93 wrote:That makes two of us. The code looks good, but the end result. Specifying trigger typed, is futile. It is persistent to use daily type regardless.

Almost looking like data overlapping issue. I'm on Windows 10, perhaps this is simply because this using older task scheduler Interfaces?
Seems like that's the issue, XP+ use version 2.0.
Will try to convert this c++ code.
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: Help with windows scheduled task

Post by Thunder93 »

A structure needing padding.

TRIGGER_TYPE_UNION

Just supply #PB_Structure_AlignC flag on the structure to fix. The problem still exists however. :lol:
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
Post Reply