c#.net向windows添加计划任务(task schduler)项

来源:互联网 发布:win7apache mysql php 编辑:程序博客网 时间:2024/06/05 16:16

Win7的task schduler功能比windows XP要强,添加的任务类别也比windows XP的多。在Win7里添加的计划任务都以XML格式的文件保存在C:\Windows\System32\Tasks目录下。在Win7里添加一个任务,并为该任务添加一个RunOnce类型的Trigger(TimeTrigger),可以设置该Trigger的repeat的duration为indefinitely,如下图:
该Trigger会repeat到永远,Tasks目录下的该任务对应的XML文件中不会有Duration项。而XP系统里不可以设置repeat到永远(本人试了下,最大值设置到0x196e6a分钟)。



要在程序中通过代码添加计划任务,需要使用com接口进行实现,而Windows的.net类库没有提供对该功能的包装。在网上搜了下,有两个现成包装:
http://www.codeproject.com/KB/cs/tsnewlib.aspx
http://taskscheduler.codeplex.com/
本人使用了codeproject里的代码,支持XP和win7系统,因为使用的com接口是旧的接口。当然也就无法设置RunOnce trigger repeat's duration to indefinitely。


下面是添加一个拥有RunOnce trigger的task。

            //Get a ScheduledTasks object for the local computer.            ScheduledTasks st = new ScheduledTasks();            // Create a task            Task t;            try            {                st.DeleteTask("Editer");                t = st.CreateTask("Editer");            }            catch (ArgumentException e)            {                Console.WriteLine("Task name already exists");                return;            }            // Fill in the program info            t.ApplicationName = @"C:\Windows\system32\notepad.exe";            t.Comment = "Open notepad to do some editing.";                        // Declare that the task runs only for the user who created it.            // And will run even if the system goes to sleep mode.            t.Flags = TaskFlags.RunOnlyIfLoggedOn | TaskFlags.SystemRequired;            // Set the account under which the task should run.            t.SetAccountInformation(Environment.UserName, (string)null);            // Declare that the system must have been idle for ten minutes before             // the task will start            t.IdleWaitMinutes = 10;            // Allow the task to run permanently.            t.MaxRunTimeLimited = false;            // Set priority to only run when system is idle.            t.Priority = System.Diagnostics.ProcessPriorityClass.Idle;            // Create a repeated RunOnce trigger with duration 0x196e6a minutes and interval 1 minute.            // 0x196e6a is the maximum minutes we can set because XP dose not support indefinitely setting.            RunOnceTrigger runOnceTrigger = new RunOnceTrigger(DateTime.Now);            runOnceTrigger.DurationMinutes = 0x196e6a;            runOnceTrigger.IntervalMinutes = 1;            //t.Triggers.Add(new DailyTrigger(17, minute));            t.Triggers.Add(runOnceTrigger);            // Save the changes that have been made.            t.Save();            // Close the task to release its COM resources.            t.Close();            // Dispose the ScheduledTasks to release its COM resources.            st.Dispose();

下面是c/c++代码的实现:

HRESULT hr = S_OK;ITaskScheduler *pITS= NULL;ITask *pITask= NULL;ITaskTrigger *pITaskTrigger = NULL;IPersistFile *pIPersistFile = NULL;LPCWSTR lpcwszTaskName = L"Editer";WORD WNewTrigger = 0;DWORD dwLenUserName = MAX_PATH;WCHAR szUserName[MAX_PATH] = { 0 };WCHAR szFullName[MAX_PATH] = { 0 };// Call CoInitialize to initialize the COM library and thenhr = CoInitialize(NULL);// call CoCreateInstance to get the Task Scheduler object.if (SUCCEEDED(hr)){hr = CoCreateInstance(CLSID_CTaskScheduler,NULL,CLSCTX_INPROC_SERVER,IID_ITaskScheduler,(void **) &pITS);}// Delete the old task and create new one.if (SUCCEEDED(hr)){hr = pITS->Delete(lpcwszTaskName);hr = pITS->NewWorkItem(lpcwszTaskName, // Name of taskCLSID_CTask,          // Class identifier IID_ITask,            // Interface identifier(IUnknown**)&pITask); // Address of task pITS->Release();  // Release object}// Set the a program for the task. if (SUCCEEDED(hr)){// Set flag.IScheduledWorkItem *pWorkItem = NULL;hr = pITask->QueryInterface(IID_IScheduledWorkItem, (void **)&pWorkItem);if (SUCCEEDED(hr)){DWORD dwFlag = 0;hr = pWorkItem->GetFlags(&dwFlag);hr = pWorkItem->SetFlags(dwFlag | TASK_FLAG_RUN_ONLY_IF_LOGGED_ON);hr = pWorkItem->Release();}// Set application to run.if (SUCCEEDED(hr)){::GetModuleFileName(NULL, szFullName, MAX_PATH);::PathRemoveFileSpec(szFullName);hr = pITask->SetWorkingDirectory(szFullName);hr = pITask->SetApplicationName(_T("C:\\Windows\\system32\\notepad.exe"));::GetUserName(szUserName, &dwLenUserName);hr = pITask->SetAccountInformation(szUserName, NULL);}}// Create new trigger.if (SUCCEEDED(hr)){hr = pITask->CreateTrigger(&WNewTrigger, &pITaskTrigger);if (FAILED(hr)){pITask->Release();}}    // Get current time.time_t t = time(0);struct tm *tmNow = localtime(&t);// Define TASK_TRIGGER structure. Note that wBeginDay,// wBeginMonth, and wBeginYear must be set to a valid // day, month, and year respectively.TASK_TRIGGER pTrigger;ZeroMemory(&pTrigger, sizeof (TASK_TRIGGER));#if 0 // Daily trigger.// Add code to set trigger structure.pTrigger.wBeginDay = tmNow->tm_mday;                  // RequiredpTrigger.wBeginMonth = tmNow->tm_mon + 1;                // RequiredpTrigger.wBeginYear = tmNow->tm_year + 1900;              // RequiredpTrigger.cbTriggerSize = sizeof (TASK_TRIGGER); pTrigger.wStartHour = 16;pTrigger.TriggerType = TASK_TIME_TRIGGER_DAILY;pTrigger.Type.Daily.DaysInterval = 1;#else // RunOnce trigger.pTrigger.cbTriggerSize = sizeof(TASK_TRIGGER);pTrigger.wBeginDay = tmNow->tm_mday;                  // RequiredpTrigger.wBeginMonth = tmNow->tm_mon + 1;                // RequiredpTrigger.wBeginYear = tmNow->tm_year + 1900;              // RequiredpTrigger.wStartHour = tmNow->tm_hour;pTrigger.wStartMinute = tmNow->tm_min;pTrigger.MinutesDuration = 100;pTrigger.MinutesInterval = 1;pTrigger.TriggerType = TASK_TIME_TRIGGER_ONCE;#endif    // Call ITaskTrigger::SetTrigger to set trigger criteria.  if (SUCCEEDED(hr)){hr = pITaskTrigger->SetTrigger (&pTrigger);if (FAILED(hr)){pITask->Release();pITaskTrigger->Release();}}// Call IUnknown::QueryInterface to get a pointer to IPersistFile if (SUCCEEDED(hr)){hr = pITask->QueryInterface(IID_IPersistFile, (void **)&pIPersistFile);  pITask->Release();}// Call IPersistFile::Save to save the new task to disk.if (SUCCEEDED(hr)){hr = pIPersistFile->Save(NULL, TRUE);pIPersistFile->Release();}CoUninitialize();



原创粉丝点击