/*
NOTICE OF CHANGES:
date of change: 6/12/2007
change: Exposed ITask interface and task name from the ScheduledTasks.cs for easy consumption .
*/
using System;
using System.IO;
using System.Runtime.InteropServices;
using TaskSchedulerInterop;
using SMStrings;
using System.DirectoryServices;
namespace TaskScheduler {
///
/// ScheduledTasks represents the a computer's Scheduled Tasks folder. Using a ScheduledTasks
/// object, you can discover the names of the tasks in the folder and you can open a task
/// to work with it. You can also create or delete tasks.
///
///
/// A ScheduledTasks object holds a COM interface that can be released by calling .
///
public class ScheduledTasks : IDisposable {
///
/// Underlying COM interface.
///
private ITaskScheduler its = null;
private ITask iTask = null;
private string name = null;
// --- Contructors ---
///
/// Constructor to use Scheduled tasks of a remote computer identified by a UNC
/// name. The calling process must have administrative privileges on the remote machine.
/// May throw exception if the computer's task scheduler cannot be reached, and may
/// give strange results if the argument is not in UNC format.
///
/// The remote computer's UNC name, e.g. "\\DALLAS".
/// The Task Scheduler could not be accessed.
public ScheduledTasks(string computer) : this() {
its.SetTargetComputer(computer);
}
///
/// Constructor to use Scheduled Tasks of the local computer.
///
public ScheduledTasks() {
CTaskScheduler cts = new CTaskScheduler();
its = (ITaskScheduler)cts;
}
// --- Methods ---
private string[] GrowStringArray(string[] s, uint n) {
string[] sl = new string[s.Length + n];
for (int i=0; i
/// Return the names of all scheduled tasks. The names returned include the file extension ".job";
/// methods requiring a task name can take the name with or without the extension.
///
/// The names in a string array.
public string[] GetTaskNames() {
const int TASKS_TO_FETCH = 10;
string[] taskNames = {};
int nTaskNames = 0;
IEnumWorkItems ienum;
its.Enum(out ienum);
uint nFetchedTasks;
IntPtr pNames;
//venua: BURT 718868
string sComputer;
its.GetTargetComputer(out sComputer);
sComputer = sComputer.TrimStart('\\');
DirectoryEntry rootDSE = new DirectoryEntry("LDAP://rootDSE");
string configNaming = (string)rootDSE.Properties["configurationNamingContext"].Value;
string rootPath = "LDAP://" + configNaming;
rootDSE.Dispose();
DirectoryEntry root = new DirectoryEntry(rootPath);
DirectorySearcher searcher = new DirectorySearcher(root);
searcher.Filter = "(objectCategory=msExchMDBAvailabilityGroup)";
SearchResultCollection results = searcher.FindAll();
bool bflag = false;
foreach (SearchResult result in results)
{
if (result.Properties.Contains("name"))
{
if (sComputer == (string)result.Properties["name"][0]) //venua: BURT 718868 if the node is dag then skip checking for schedules
{
bflag = true;
break;
}
}
}
//venua: BURT 718868skip get schedules for dag node
//since ienum.Next is returning after 1 min when trying to connect to dag node
if (!bflag)
{
while (ienum.Next(TASKS_TO_FETCH, out pNames, out nFetchedTasks) >= 0 &&
nFetchedTasks > 0)
{
taskNames = GrowStringArray(taskNames, nFetchedTasks);
while (nFetchedTasks > 0)
{
IntPtr name = Marshal.ReadIntPtr(pNames, (int)--nFetchedTasks * IntPtr.Size);
taskNames[nTaskNames++] = Marshal.PtrToStringUni(name);
Marshal.FreeCoTaskMem(name);
}
Marshal.FreeCoTaskMem(pNames);
}
}
root.Dispose();
searcher.Dispose();
return taskNames;
}
// BURT273450: 1-22-2006 4:00pm PST, Crood, detect invalid job name /w msg
class TaskNameInvalidException : Exception
{
// Validate the name
public static bool IsValid(string taskName)
{
return (!string.IsNullOrEmpty(taskName) &&
(-1 == taskName.IndexOfAny(new char[] { '*', '?', '/', '\\', '<', '>', '|' })));
}
// Create a more meaningful message
public TaskNameInvalidException(Exception exInner):
base(string.Format(SMSharedStringTable.GetString("SMSCHEDULER_INVALIDJOBNAME_14"),
System.Runtime.InteropServices.Marshal.GetHRForException(exInner)),
exInner)
{
}
}
///
/// Creates a new task on the system with the given .
///
/// Task names follow normal filename character restrictions. The name
/// will be come the name of the file used to store the task (with .job added).
/// Name for the new task.
/// Instance of new task.
/// There is an existing task with the given name.
public Task CreateTask(string name) {
Task tester = OpenTask(name);
if (tester != null) {
throw new ArgumentException(string.Format(SMSharedStringTable.GetString("SMSCHEDULER_THETASK0ALREAD_1"), name));
}
try
{
this.name = name;
object o;
its.NewWorkItem(name, ref CTaskGuid, ref ITaskGuid, out o);
this.iTask = (ITask)o;
return new Task(this.iTask, this.name);
}
catch (Exception ex)
{
// BURT273450: 1-22-2006 4:00pm PST, Crood, detect invalid job name /w msg
if (!TaskNameInvalidException.IsValid(name))
throw new TaskNameInvalidException(ex);
throw;
}
}
public void SaveTask(Task task)
{
try
{
if (task.Name == this.name)
its.AddWorkItem(this.name, this.iTask);
return;
}
catch(Exception ex)
{
return;
}
}
///
/// Deletes the task of the given .
///
/// If you delete a task that is open, a subsequent save will throw an
/// exception. You can save to a filename, however, to create a new task.
/// Name of task to delete.
/// True if the task was deleted, false if the task wasn't found.
public bool DeleteTask(string name) {
try {
Task tester = OpenTask(name);
if (tester != null)
{
tester.Triggers.Clear();
tester.Close();
its.Delete(name);
}
return true;
}
catch {
return false;
}
}
///
/// Opens the task with the given . An open task holds COM interfaces
/// which are released by the Task's Close() method.
///
/// If the task does not exist, null is returned.
/// Name of task to open.
/// An instance of a Task, or null if the task name couldn't be found.
public Task OpenTask(string name) {
try {
object o;
its.Activate(name, ref ITaskGuid, out o);
ITask iTask = (ITask)o;
return new Task(iTask, name);
}
catch {
return null;
}
}
#region Implementation of IDisposable
///
/// The internal COM interface is released. Further access to the
/// object will throw null reference exceptions.
///
public void Dispose() {
Marshal.ReleaseComObject(its);
its = null;
}
#endregion
// Two Guids for calls to ITaskScheduler methods Activate(), NewWorkItem(), and IsOfType()
internal static Guid ITaskGuid;
internal static Guid CTaskGuid;
static ScheduledTasks() {
ITaskGuid = Marshal.GenerateGuidForType(typeof(ITask));
CTaskGuid = Marshal.GenerateGuidForType(typeof(CTask));
}
}
}