Click here to Skip to main content
15,917,642 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
When creating a new scheduled task, using CreateProcess with at.exe command, I get files in the scheduled tasks folder named at1.job, at2.job, at3.job, etc.

I want to delete some of them, using c++ programming.
I want to search all the at files, look for a specific command in their command line, and delete those at files contain this command.

How can I do it?

Updated 27-Mar-11 5:48am
Dalek Dave 27-Mar-11 11:48am    
Edited for Readability.

To search the files you could use FindFirstFile[^] and FindNextFile[^]. When you found matches you could use CFile.

Here's one good link:[^]
Share this answer
user_code 27-Mar-11 8:53am    
Hi, thanks.
I don't want to search for a file name. There are a lot of "at" files, and i want to know which of those files contanst a specific string (specific command line).
The big prblem is that I don't know exactly what is the structure of those at files and how to search inside them, because they are in the "control panel\scheduled tasks" folder.
Dalek Dave 27-Mar-11 11:49am    
Wendelius 27-Mar-11 11:51am    
Thanks :)
Have you ever tried this:
C:\WINDOWS>cd Tasks
C:\WINDOWS\Tasks>dir /a/s/b

To delete this *.job files Just execute the following statement:
system("del /a /f C:\WINDOWS\Tasks\*.job");

Note: Please specify you OS dir. It is not always C:\windows.
Share this answer
Andrew Brock 27-Mar-11 9:36am    
system("del /a /f %WINDIR%\Tasks\*.job");
That will always find the active windows directory.
Also, this will delete all jobs, not just the ones created by his program. 4.
Аslam Iqbal 27-Mar-11 9:45am    
You are right.
If OP konws that why he is asking how to delete. I think he/she has the basic idea about filesystem. So it is very simple to change this: system("del /a /f C:\WINDOWS\Tasks\*.job"); to this: system("del /a /f C:\WINDOWS\Tasks\jobNametodelete.job"); by OP.If he/she can't do that then again downvote me. thanks......
Andrew Brock 27-Mar-11 13:12pm    
Good point. Updated to a 5, but there is an API function DeleteFile that would do the same thing.
Аslam Iqbal 27-Mar-11 13:22pm    
Actually I always choose to do something in shortcut. I Know its not always good. Thanks.
Dalek Dave 27-Mar-11 11:49am    
Good Answer.
erez_l wrote:
The big prblem is that I don't know exactly what is the structure of those at files and how to search inside them, because they are in the "control panel\scheduled tasks" folder.

You can easily dissect these files, MSDN has documentation on the file format.
See 2.4.1 FIXDLEN_DATA[^] and 2.4.2 Variable-Length Data Section[^]

You can probably skip the section 2.4.1 because it is fixed length and doesn't contain anything you are interested in.

What you might come up with is this.
It is the full code to a console application that will print the command line of every .job file.
#include <windows.h>
#include <stdio.h>
//Makes sure there is no padding added in by the compiler
#pragma pack(push)
#pragma pack(1)
//This struct is irrelevant for your task
typedef struct {
	WORD nProductVersion;
	WORD nFileVersion;
	WORD nAppNameLenOffset;
	WORD nTriggerOffset;
	WORD nErrorRetryCount;
	WORD nErrorRetryInterval;
	WORD nIdleDeadline;
	WORD nIdleWait;
	DWORD nPriority;
	DWORD nMaximumRunTime;
	DWORD nExitCode;
	DWORD nStatus;
	DWORD nFlags;
	WORD nYear;
	WORD nMonth;
	WORD nWeekday;
	WORD nDay;
	WORD nHour;
	WORD nMinute;
	WORD nSecond;
	WORD nMilliSeconds;
} FixedLenData;
typedef struct {
	WORD nLength;
	wchar_t szString[]; //0 sized array warning can be ignored
} UnicodeString;
typedef struct {
	FixedLenData *pHeader;
	union {
		struct {
			UnicodeString *pApplicationName; //The .exe name
			UnicodeString *pParameters; //The additional command line args
			UnicodeString *pRunningInstanceCount;
			UnicodeString *pWorkingDirectory;
			UnicodeString *pAuthor;
			UnicodeString *pComment;
			UnicodeString *pUserData;
			UnicodeString *pReservedData;
			UnicodeString *pTriggers;
			UnicodeString *pJobSignature;
		UnicodeString *pStrings[10];
} ATJobFile;
#pragma pack(pop)
ATJobFile *ReadJob(LPCSTR szFileName) {
		return NULL;
	DWORD nFileSize = SetFilePointer(hFile, 0, NULL, FILE_END); //Get file size
	SetFilePointer(hFile, 0, NULL, FILE_BEGIN); //Reset file pointer
	BYTE *pData = new BYTE[nFileSize];
	ATJobFile *pJob = new ATJobFile();
	ReadFile(hFile, pData, nFileSize, &nFileSize, NULL);
	pJob->pHeader = (FixedLenData *)pData; //This points to the start of the file
	pData += sizeof(FixedLenData);
	for (int nString = 0; nString < 10; ++nString) {
		pJob->pStrings[nString] = (UnicodeString *)pData;
		pData += pJob->pStrings[nString]->nLength * sizeof(wchar_t) + sizeof(WORD);
	return pJob;
void DestroyJob(ATJobFile *pJob) {
	delete []pJob->pHeader;
	delete pJob;
int main() {
	WIN32_FIND_DATA fdSearch;
	char szWinDir[MAX_PATH];
	ExpandEnvironmentStrings("%WINDIR%\\Tasks", szWinDir, sizeof(szWinDir)); //Find the Windows directory
	SetCurrentDirectory(szWinDir); //This just saves us putting "C:\\Windows\\Tasks\\" infront of everything
	HANDLE hFind = FindFirstFile("*.job", &fdSearch);
		do {
			ATJobFile *pJob = ReadJob(fdSearch.cFileName);
			printf("Job %s\n", fdSearch.cFileName);
			if (pJob->pParameters->nLength == NULL) {
				wprintf(L"%s\n\n", pJob->pApplicationName->szString);
			} else {
				wprintf(L"%s %s\n\n", pJob->pApplicationName->szString, pJob->pParameters->szString);
		} while (FindNextFile(hFind, &fdSearch));
	return 0;
Share this answer
Dalek Dave 27-Mar-11 11:50am    
Very Comprehensive! 5.
Wendelius 27-Mar-11 11:51am    
Wow, well explained, my 5.
user_code 28-Mar-11 3:41am    
thanks a lot, very good answer! 5
Schtasks.exe is a more recent tool than at.exe. With it you can create, query, run and delete tasks.

C:\Documents and Settings\dev\desktop>schtasks /query /fo LIST /v

HostName:                             GIRAFFE
TaskName:                             BCTEST
Next Run Time:                        Never
Last Run Time:                        20:39:00, 28/05/2009
Last Result:                          0
Creator:                              dev
Schedule:                             At 00:02 every day, starting 16/12/2009
Task To Run:                          E:\cmd\BCScript\RunBCScript.cmd
Start In:                             e:\cmd\bcscript
Comment:                              N/A
Scheduled Task State:                 Disabled
Scheduled Type:                       Daily
Start Time:                           00:02:00
Start Date:                           16/12/2009
End Date:                             N/A
Days:                                 Everyday
Months:                               N/A
Run As User:                          Could not be retrieved from the task scheduler database
Delete Task If Not Rescheduled:       Disabled
Stop Task If Runs X Hours and X Mins: 72:0
Repeat: Every:                        Disabled
Repeat: Until: Time:                  Disabled
Repeat: Until: Duration:              Disabled
Repeat: Stop If Still Running:        Disabled
Idle Time:                            Disabled
Power Management:                     No Start On Batteries, Stop On Battery Mode

Taskname is the name of the .job file minus the extension, in this example BCTEST and Task To Run is the command line "E:\cmd\BCScript\RunBCScript.cmd"

It would be a fairly simple operation to capture and parse the output to find the task(s) you want to delete.

Deletion is achieved using the command
C:\WINDOWS\Tasks>schtasks /delete /tn BCTEST /f
SUCCESS: The scheduled task "BCTEST" was successfully deleted.

Share this answer
Dalek Dave 27-Mar-11 11:50am    
Great Answer, gets a 5.
user_code 28-Mar-11 3:42am    
thanks a lot, very helpful. 5
user_code 28-Mar-11 5:17am    
how can i run schtasks.exe in interactive mode?
like "at.... /interactive"?

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900