Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Task Scheduler API? 1

Status
Not open for further replies.

vbtutor

Programmer
Sep 9, 2002
7
0
0
US
I need to either find the path and file structure/format information that Windows Task Scheduler uses to run Scheduled Tasks so that I can create a file that the Task Scheduler will automatically read and process. Or have an API call to the scheduler from within Visual Basic 6.0 so that automated processes I am creating in an application will get run.

Any suggestions?

Thanks,

David
 
Hi

You can use the Win32's NetScheduleJobAdd().

Taken from the Win32 documentation:
The NetScheduleJobAdd function submits a job to run at a specified future time and date. This function requires that the schedule service be started at the computer to which the job is submitted.

 
That's not exactly what I'm looking for, but thanks.. I looked up the NetScheduleJobAdd() function at msdn, and it appears to be a C++ function. I am using VB 6.0.

I think I did find what I'm looking for though.

Thanks again.
 
vbtutor

can you post whatr you found? Attitude is Everything
 
I found a VB example at planet source code. Here's what I found:

Option Explicit
' Schedule api's
Declare Function NetScheduleJobAdd Lib "netapi32.dll" _
(ByVal Servername As String, Buffer As Any, Jobid As Long) As Long

' Schedule structure
Type AT_INFO
JobTime As Long
DaysOfMonth As Long
DaysOfWeek As Byte
Flags As Byte
dummy As Integer
Command As String
End Type

' Schedule constants
Const JOB_RUN_PERIODICALLY = &H1
Const JOB_NONINTERACTIVE = &H10
Const NERR_Success = 0

Private Sub Command1_Click()
Dim lngWin32apiResultCode As Long
Dim strComputerName As String
Dim lngJobID As Long
Dim udtAtInfo As AT_INFO

' Convert the computer name to unicode
strComputerName = StrConv(Text1.Text, vbUnicode)

' Setup the tasks parameters
SetStructValue udtAtInfo

' Schedule the task
lngWin32apiResultCode = NetScheduleJobAdd(strComputerName, udtAtInfo, lngJobID)

' Check if the task was scheduled
If lngWin32apiResultCode = NERR_Success Then
MsgBox "Task" & lngJobID & " has been scheduled."
End If

End Sub
Private Sub SetStructValue(udtAtInfo As AT_INFO)
Dim strTime As String
Dim strDate() As String
Dim vntWeek() As Variant
Dim intCounter As Integer
Dim intWeekCounter As Integer

vntWeek = Array("M", "T", "W", "TH", "F", "S", "SU")

With udtAtInfo

' Change the format of the time
strTime = Format(Text2.Text, "hh:mm")

' Change the time to one used by the api
.JobTime = (Hour(strTime) * 3600 + Minute(strTime) * 60) * 1000

' Set the Date parameters
If Val(Text3.Text) > 0 Then

' Set the task to run on specific days of the month i.e. 9th & 22nd of the month
strDate = Split(Text3.Text, ",")
For intCounter = 0 To UBound(strDate)
.DaysOfMonth = .DaysOfMonth + 2 ^ (strDate(intCounter) - 1)
Next

Else

' Set the task to run on sepecific days of the week i.e. Monday & Thursday
strDate = Split(Text3.Text, ",")
For intCounter = 0 To UBound(strDate)
For intWeekCounter = 0 To UBound(vntWeek)
If UCase(strDate(intCounter)) = vntWeek(intWeekCounter) Then
.DaysOfWeek = .DaysOfWeek + 2 ^ intWeekCounter
Exit For
End If
Next
Next
End If

' Set the interactive property
If Check1.Value = vbUnchecked Then
.Flags = .Flags Or JOB_NONINTERACTIVE
End If

' Set to run periodically
If Option2.Value = True Then
.Flags = .Flags Or JOB_RUN_PERIODICALLY
End If

' Set the command to run
.Command = StrConv(Text4.Text, vbUnicode)
End With
End Sub
 
This code example works just fine at creating a scheduled job in Windows Task Scheduler, but one thing it doesn't do is check to see if the job is already scheduled. So if you wanted to have the ability to change your schedule, then you simply create another job with this code, rather than overwriting it.

Any ideas on how to read the current job, and overwrite it, or delete it when creating/changing the schedule?

thanks..
 
In teh dependency list for WinAt are listed

NetScheduleJobAdd
NetScheduleJobDel
NetScheduleJobEnum
NetScheduleJobGetInfo

If you poke about where you found the Add oyu should find the others, with a bit of luck.
 
Hi,
The "NetScheduleJobAdd" does work in winxp with vb6 but
the "NetScheduleJobEnum" api doesn't. What can i do ???
 
What do the textX.text fields refer to in the above code?

Thanks and have a great day!
 
I cleaned up the above code from PSC and made it so you can just paste it into a function, i did have trouble coping and pasting the above code, the vb6 ide made everything error syntax even tho it was correct. I just retyped it letter for letter without a problem

Public Declare Function NetScheduleJobAdd Lib "netapi32.dll" (ByVal Servername As String, Buffer As Any, Jobid As Long) As Long
Public Declare Function NetScheduleJobDel Lib "netapi32.dll" (ByVal Servername As String, minJobId As Long, maxJobId As Long) As Long
Public Declare Function GetComputerName Lib "kernel32" Alias "GetComputerNameA" (ByVal lpBuffer As String, nSize As Long) As Long

' Schedule structure
Private Type AT_INFO
JobTime As Long
DaysOfMonth As Long
DaysOfWeek As Byte
Flags As Byte
dummy As Integer
command As String
End Type

Public Sub Create_Scheduled_Event(t As String, d As String, c As String, Optional i As Boolean = False, Optional p As Boolean = True)
Dim strTime As String
Dim strDate() As String
Dim vntWeek() As Variant
Dim intCounter As Integer
Dim intWeekCounter As Integer
Dim at As AT_INFO
Dim lngJobID As Long
Dim lngWin32apiResultCode As Long
Dim strComputerName As String

strComputerName = StrConv(Get_Computer_Name, vbUnicode)

err.Clear


vntWeek = Array("M", "T", "W", "TH", "F", "S", "SU")

With at
strTime = Format(t, "hh:mm")
.JobTime = (Hour(strTime) * 3600 + Minute(strTime) * 60) * 1000
If Val(d) > 0 Then
strDate = Split(d, ",")
For intCounter = 0 To UBound(strDate)
.DaysOfMonth = .DaysOfMonth + 2 ^ (strDate(intCounter) - 1)
Next
Else
strDate = Split(d, ",")
For intCounter = 0 To UBound(strDate)
For intWeekCounter = 0 To UBound(vntWeek)
If UCase(strDate(intCounter)) = vntWeek(intWeekCounter) Then
.DaysOfWeek = .DaysOfWeek + 2 ^ intWeekCounter
End If
Next
Next
End If

If i = False Then .Flags = .Flags Or JOB_NONINTERACTIVE

If p = True Then .Flags = .Flags Or JOB_RUN_PERIODICALLY

.command = StrConv(c, vbUnicode)
End With

lngWin32apiResultCode = NetScheduleJobAdd(strComputerName, at, lngJobID)


If lngWin32apiResultCode = NERR_Success Then MsgBox "Task " & lngJobID & " has been scheduled."
End Sub

Public Function Get_Computer_Name() As String
Dim pc_name As String
pc_name = String(50, Chr(0))
GetComputerName pc_name, 50 'gets the comp. name
Get_Computer_Name = "\\" & Trim(pc_name)
End Function

i was having trouble with NetScheduleJobDel it returns error code 3806 and on the system error code page that error number isn't listed.

-Xodus

ps. hope i didn't forget anything
 
I wrote the code on planet source to use NetScheduleJobAdd that vbtutor (Programmer) printed, if you want help on it just mail me and I will show you how to use it.

 
It's nice to see that this thread is still alive and active. Thanks Xodus for cleaning up the code a bit, and thanks to Giddo for offering to help.

I also found some references that allow you to access the task scheduler API through a command shell interface using the AT command. This is only valid for Windows NT/2k/XP, just as the NetScheduleJob* functions are. Sorry I don't have a good example handy. The references I found are actually in a PHP book, and I can't seem to find anything on MSDN about this.

The big question though, is where to find an API reference on how to create scheduled tasks on Windows 9.x/Me. I know it's possible, because Symantec does this for NAV on the Win 9.x/Me platform for their Live Update application, but I've not seen anything on how to achieve this.

Any suggestions?

Thanks,

David
 
Hi all

Is this what I've been looking for? I really need a solid scheduler I can install as a service - the requirements for the use of it, is as follows:

- 2 different Executables to be run.
- one every 10 minutes
- and one every hour

I admit at once... I'm the worlds greates newbie in this VB show, and would appreciate some code examples - and some how to do's...

;o)
Regards
Flemming
 
C'd someone pl. post how to declare and call the following netschedule related functions.

GetNetScheduleAccountInformation
SetScheduleAccountInformation
NetScheduleJobEnum

Thanks
-deepika
 
Hi Giddo

Can u please tell me how to schedule a task daily & set its advanced properties like setting repeat task details?
Code sample in VB will be highly appreciated..

Thanks..
eCGSoft
 
I got the roots of the following code from a co-worker so I can't take credit. It uses the WMI interface to the scheduler service. It can be used to schedule a task at a predefined interval. The following code is dependent on a predifined global date which is used to hold the time of day for the task to be run. I use this to run a task every 15 minutes.

Usage:

1) Schedule your program to run "on startup" in the task sceduler via the GUI interface. Assign an admin, or other appropriate user context for it to run under.

2) In your program, (MyApp.exe)

...do something
' Set the start time to 15 minutes from now
gdtProcessTime = DateAdd("n",15,Now())
...do something
' Have the program reschedule itself for 15 minutes later
NTTaskDelete App.Path & "\MyApp.exe"
NTTaskCreate App.Path & "\MyApp.exe"
...
End

This sequence starts the app under the user account that is specified by the "startup" event. Since the program is using this account when it runs the new event that is "re-scheduled" uses the same user acount(default) to run under.

The "Exists" function at the end is not used in this sample but is useful sometimes.

Hope this is useful.
'--------------------------------



Public dtProcessTime as date

Private Sub NTTaskDelete(strCmdLine As String)

' this connects to the NT Task Scheduler via WMI to determine if the desired NT Scheduled Task Exists
' if found, it deletes it

Dim objTasks As Object
Dim objTask As Object
Dim strErr As String

On Error Resume Next
' now connect to NT Task Scheduler to determine if the script is scheduled
' create and schedule it if necessary
Set objTasks = GetObject("winmgmts:{impersonationLevel=impersonate}").InstancesOf("Win32_ScheduledJob")
If Err Then
strErr = ": " & Err.Number & " " & Err.Source & " " & Err.Description
App.LogEvent "NTTaskDelete: Could not delete the NT Task for " & strCmdLine & " due to error connecting to WMI: " & strErr, vbLogEventTypeWarning
Err.Clear
Exit Sub
End If


For Each objTask In objTasks
If UCase(objTask.Command) = UCase(strCmdLine) Then
' but if trap error if trying to delete
Err.Clear
objTask.Delete
If Err Then
strErr = ": " & Err.Number & " " & Err.Source & " " & Err.Description
App.LogEvent "NTTaskDelete: Could not delete the NT Task for " & strCmdLine & " due to error during delete: " & strErr, vbLogEventTypeWarning
Err.Clear
End If
Exit For
End If
Next

End Sub

Private Sub NTTaskCreate(strCmdLine As String)

Dim objList As Object
Dim objTask As Object
Dim strTime As String
Dim ret As Long
Dim strResult As String
Dim intJobID As Integer
Dim intNextHour As Integer
Dim intNextMinute As Integer
Dim strTimeOffset As String

' gdtProcessTime has already been incremented to the next start time
' determine which is the next hour for task to execute
intNextHour = DatePart("h", gdtProcessTime)
intNextMinute = DatePart("n", gdtProcessTime)
' example
' strTime = "********123000.000000-420"
' set it for real
' determine UCT Offset for this computer (Universal Coordinated Time)
' Note that there's always only 1 Win32_ComputerSystem obj, but have to use for-next anyway
Set objList = GetObject("winmgmts:{impersonationLevel=impersonate}").InstancesOf("Win32_ComputerSystem")
For Each objTask In objList
strTimeOffset = Trim$(objTask.CurrentTimeZone)
Exit For
Next
Set objTask = Nothing
Set objList = Nothing

strTime = "********" & Format$(intNextHour, "00") & Format$(intNextMinute, "00") & "00" & ".000000" & strTimeOffset ' -300"
Set objTask = GetObject("winmgmts:{impersonationLevel=impersonate}!Win32_ScheduledJob")

ret = objTask.Create(strCmdLine, strTime, False, , , False, intJobID)

Select Case ret
Case 0
strResult = "The request is accepted."
Case 1
strResult = "The request is not supported."
Case 2
strResult = "The user does not have the necessary access."
Case 8
strResult = "Interactive Process."
Case 9
strResult = "The directory path to the service executable file cannot be found."
Case 21
strResult = "Invalid parameters have been passed to the service."
Case 22
strResult = "The account that this service runs under is invalid or lacks the permissions to run the service."
End Select
If ret > 0 Then
' create failed, write event log entry
App.LogEvent "NTTaskCreate: Win32_ScheduledJob.Create Failed. :" & strResult, vbLogEventTypeError
End If
Set objTask = Nothing

End Sub


Public Function NTTaskExists(strCmdLine As String) As Boolean
' this connects to the NT Task Scheduler via WMI to determine if the desired NT Scheduled Task Exists
Dim objTasks As Object
Dim objTask As Object

NTTaskExists = False
' now connect to NT Task Scheduler to determine if the script is scheduled
' create and schedule it if necessary
Set objTasks = GetObject("winmgmts:{impersonationLevel=impersonate}").InstancesOf("Win32_ScheduledJob")
For Each objTask In objTasks
If UCase(objTask.Command) = UCase(strCmdLine) Then
NTTaskExists = True
Exit For
End If
Next

End Function


 
Hi again,

Sorry to all those who wanted my help but I was tied up and didn't have any time to spare. Well I have had about 3 to four request for help and updates so heres what I have done, I have added some features to the last program. It now includes adding of jobs, enum (listing) of jobs added and also deleting of jobs.

I will be uploading this code shortly in
If in the mean time you want a copy then feel free to mail me.

Regards

Neil Giddings
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top