Click here to Skip to main content
Licence CPOL
First Posted 7 Jan 2009
Views 11,081
Downloads 85
Bookmarked 17 times

Scheduler.NET for UltraDefrag

By | 7 Jan 2009 | Article
Using PInvoke to add scheduled tasks to Windows

Introduction 

A while ago, I was looking for an open source disk defragmenter for Windows. None of them had the feature I desired, namely a native executable that would run at boot time. However, I was able to get the author of UltraDefrag to implement this feature in exchange for writing the manual. Soon afterwards, I decided to contribute a utility that would configure UltraDefrag to run as a scheduled task. This was a very simple WinForms app that is required to perform two unique tasks. The first was to add a service to the task scheduler service. The second was to get a list of available drives.

How the Code Works 

From a disk drive point of view, I had two concerns: the first was getting a list of drive letters on the machine, and the second was determining which of those drive letters represented hard drives. These were both accomplished via calls to the .NET API as illustrated below: 

DriveInfo[] driveInfo = DriveInfo.GetDrives();
List<string> drives = new List<string>();

foreach (DriveInfo drive in driveInfo) {
    DriveType driveType = Native.GetDriveType(drive.Name);
	if(
		driveType != DriveType.Fixed
		 &&
		driveType != DriveType.Removable
		 &&
		driveType != DriveType.RAMDisk
	) continue;
	if(!is_virtual(drive.Name[0]))
 	drives.Add(drive.Name);
}

cmbDrives.DataSource = drives;

After getting a list of drive letters, one has to make the API call to add the scheduled task. The API call for this is NetScheduleJobAdd. This API call uses a complex data type that is pretty straight forward. I have documented how to use this on the PInvoke.NET page in the preceding link. The application call to NetScheduleJobAdd is illustrated below. Note that the function below is a delegate of the ok button's click event. 

private void cmdOk_Click(object sender, EventArgs e)
{
    IntPtr ptr;
    AT_INFO atInfo = new AT_INFO();
    atInfo.Command = string.Format("udefrag {0}", cmbDrives.SelectedValue);
    atInfo.DaysOfMonth = 0;
    atInfo.DaysOfWeek = 0;
    atInfo.Flags = AT_JobFlags.JOB_RUN_PERIODICALLY | AT_JobFlags.JOB_NONINTERACTIVE;
    atInfo.JobTime = (uint) timePicker.Value.TimeOfDay.TotalMilliseconds;
    int jobId;
     if (radDaily.Checked)
    {
        atInfo.DaysOfWeek = 0x7F;
    }
    else if (radWeekly.Checked)
    {
        if (chkMonday.Checked) atInfo.DaysOfWeek |= 0x1;
        if (chkTuesday.Checked) atInfo.DaysOfWeek |= 0x2;
        if (chkWednesday.Checked) atInfo.DaysOfWeek |= 0x4;
        if (chkThursday.Checked) atInfo.DaysOfWeek |= 0x8;
        if (chkFriday.Checked) atInfo.DaysOfWeek |= 0x10;
        if (chkSaturday.Checked) atInfo.DaysOfWeek |= 0x20;
        if (chkSunday.Checked) atInfo.DaysOfWeek |= 0x40;
    }
     ptr = Marshal.AllocHGlobal(Marshal.SizeOf(atInfo));
    Marshal.StructureToPtr(atInfo, ptr, true);
     Native.NetScheduleJobAdd(null, ptr, out jobId); 
} 

Points of Interest 

Originally, I found the PInvoke code for NetScheduleJobAdd() at http://www.dotnet247.com/247reference/msgs/47/239675.aspx. However, that URL no longer works and the internet wayback machine has no reference to it. I documented the PInvoke calls on PInvoke.NET

Further Development

The program is currently hard coded to work with ultra defrag. However, it would be easy to make it configurable to work with any application that operates on hard drives. It is simply a matter of replacing one hard coded string with a string loaded from a config file to achieve this functionality. Some other configuration options would have to be added to appropriately rebrand the configuration utility for other applications. For example, the title bar would have to change. 

Unfortunately, I don't have the time to make such changes. However, if you think this code would work well with something other than UltraDefrag, I'd be happy to include your changes in the version included with UltraDefrag, pending the approval of Dmitri, UltraDefrag's author.  

Links

History  

  • 7th January, 2009: First version of this article

License

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

About the Author

zippy1981



United States United States

Member



Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
General[My vote of 2] nono Pinmemberpophelix16:45 25 Jan '10  
GeneralA much better article on task scheduler exists PinmemberShaun Wilde2:14 8 Jan '09  
GeneralMissing .ico Pinmemberslearl4:58 7 Jan '09  
FYI, missing .ico.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web04 | 2.5.120529.1 | Last Updated 7 Jan 2009
Article Copyright 2009 by zippy1981
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid