Automatizar la Programación de Tareas de Windows en .NET
Windows ofrece un servicio muy útil que permite ejecutar tareas programadas por fechas (
Task Scheduler), este un gran complemento para ejecutar aplicaciones de consola como por ejemplo para actualización de aplicaciones y/o archivos, envío de notificaciones y/o mensajes de correos, backups, etc.
Requerimiento
Se desea crear una aplicación que permita automatizar la programación de tareas para no hacerla manualmente a través de la aplicación de consola
taskschd.msc. Sino tener una aplicación personalizada que permita listar las tareas, crear una nueva tarea y eliminar una tarea existente.
Solución
Crearemos una aplicación Windows Forms .NET en C# que use la clase
TaskService de la librería manejada
Microsoft.Win32.TaskScheduler.dll que la podemos descargar libremente de la siguiente dirección:
Task Scheduler Managed Wrapper
Crear una Aplicación Windows Forms en C#
Abrir Visual Studio y crear una aplicación Windows Forms en C# llamada "ProgramacionTareas", cambiarle de nombre al formulario por "frmListaTareas" y realizar el diseño similar a la figura mostrada:
Nota: En el diseño hay un ListView llamado "lvwTarea", un menú contextual llamado "mnuTarea" con 2 opciones: mnuNuevaTarea y mnuEliminarTarea.
Hacer una referencia a la librería: "Microsoft.Win32.TaskScheduler.dll" y escribir el siguiente código en el formulario "frmListaTareas":
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using net=System.Threading.Tasks;
using Microsoft.Win32.TaskScheduler; //TaskService
namespace ProgramacionTareas
{
public partial class frmListaTareas : Form
{
public frmListaTareas()
{
InitializeComponent();
}
private void configurarListView()
{
lvwTarea.Columns.Add("Nombre de la Tarea", 400);
lvwTarea.Columns.Add("Folder", 300);
lvwTarea.Columns.Add("Status", 100);
lvwTarea.View = View.Details;
lvwTarea.MultiSelect = false;
lvwTarea.GridLines = true;
lvwTarea.FullRowSelect = true;
lvwTarea.HotTracking = true;
}
private void listarTareas(object sender, EventArgs e)
{
configurarListView();
IEnumerable<Task> tareas = null;
net.TaskScheduler ui =
net.TaskScheduler.FromCurrentSynchronizationContext();
System.Threading.Tasks.Task.Run(() =>
{
TaskService prog = new TaskService();
tareas = prog.AllTasks;
}).ContinueWith(x => mostrarTareas(tareas),ui);
}
private void seleccionarTareas(ListViewItem fila,Task tarea,string estado)
{
if (estado.Equals("Running"))
{
fila.ForeColor = Color.White;
fila.BackColor = Color.Red;
}
if (tarea.Folder.Name.Equals("DSOFT"))
{
fila.ForeColor = Color.Yellow;
fila.BackColor = Color.Green;
}
}
private void mostrarTareas(IEnumerable<Task> tareas)
{
ListViewItem fila;
string estado;
foreach (Task tarea in tareas)
{
estado = tarea.State.ToString();
fila = lvwTarea.Items.Add(tarea.Name);
fila.SubItems.Add(tarea.Folder.Name);
fila.SubItems.Add(estado);
seleccionarTareas(fila, tarea, estado);
}
}
private void crearNuevaTarea(object sender, EventArgs e)
{
frmNuevaTarea frm = new frmNuevaTarea();
if (frm.ShowDialog().Equals(DialogResult.OK))
{
TaskService programador = new TaskService();
Trigger evento = Trigger.CreateTrigger(TaskTriggerType.Daily);
evento.StartBoundary = frm.dtpFechaInicio.Value.AddMinutes(1);
evento.EndBoundary = frm.dtpFechaFin.Value;
ExecAction accion = new ExecAction();
accion.Path = frm.txtPrograma.Text;
Task tarea = programador.AddTask
(@"\DSOFT\" + frm.txtNombre.Text, evento, accion);
if (tarea != null)
{
string estado = tarea.State.ToString();
ListViewItem fila = lvwTarea.Items.Add(tarea.Name);
fila.SubItems.Add(tarea.Folder.Name);
fila.SubItems.Add(estado);
seleccionarTareas(fila, tarea, estado);
}
}
}
private void eliminarTarea(object sender, EventArgs e)
{
if (lvwTarea.SelectedItems != null && lvwTarea.SelectedItems.Count > 0)
{
ListViewItem fila =lvwTarea.SelectedItems[0];
string nombreCarpeta = fila.SubItems[1].Text;
TaskService programador = new TaskService();
TaskFolder carpeta = programador.GetFolder(nombreCarpeta);
if (carpeta != null)
{
string nombreTarea = fila.SubItems[0].Text;
Task tarea = programador.GetTask
(String.Format(@"\{0}\{1}", nombreCarpeta, nombreTarea));
if (tarea != null)
{
if (tarea.State.Equals(TaskState.Running)) tarea.Stop();
try
{
carpeta.DeleteTask(nombreTarea, true);
fila.Remove();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "No se pudo eliminar la tarea");
}
}
}
}
}
}
}
Nota: Para el ejemplo, se ha creado en el Task Scheduler de Windows una carpeta llamada "DSOFT"
Agregar otro formulario al proyecto y ponerle como nombre "frmNuevaTarea" y diseñarlo similar a como se ve en la siguiente figura:
Nota: En el diseño hay 2 TextBoxs llamados txtNombre y txtPrograma, además 2 DateTimePicker llamados: dtpFechaInicio y dtpFechaFin, finalmente 3 botones: "btnAbrirPrograma", "btnAceptar" y "btnCancelar". El botón "btnAceptar" tiene configurado la propiedad DialogResult en OK y el botón "btnCancelar" tiene configurado la propiedad DialogResult en Cancel.
Escribir el siguiente código en el formulario "frmNuevaTarea":
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ProgramacionTareas
{
public partial class frmNuevaTarea : Form
{
public frmNuevaTarea()
{
InitializeComponent();
}
private void mostrarDialogoAbrirPrograma(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Title = "Selecciona el Programa a Abrir";
ofd.Filter = "Archivos de programas|*.exe";
if (ofd.ShowDialog().Equals(DialogResult.OK))
{
txtPrograma.Text = ofd.FileName;
}
}
}
}
Ejecutar y Probar la Aplicación Windows Forms
Antes de ejecutar la aplicación, para poder comprobar el listado de tareas, la creación de una nueva tarea y la eliminación de una tarea existente hay que abrir el Task Scheduler, para esto pulsar Ctrl + R y escribir el siguiente comando: taskschd.msc
Se mostrará la consola del Task Scheduler similar al mostrado en la siguiente figura:
Nota: Crear una carpeta personalizada para guardar nuestras tareas programadas llamada "DSOFT" y crear un par de tareas básicas dentro de esta carpeta.
Grabar la aplicación y pulsar F5 para ejecutarla, inmediatamente se listaran las tareas programadas similar a la siguiente figura:
En la ventana las tareas de la carpeta personalizada creada "DSOFT" se mostrarán con fondo verde y color amarillo y las tareas que están ejecutándose se mostrarán con fondo rojo y color blanco.
Dar clic derecho sobre la lista (ListView) y aparecerá un menú contextual con 2 opciones, seleccionar la primera opción: "Nueva Tarea" y aparecerá el siguiente cuadro de diálogo:
Llenar los datos de la nueva tarea: nombre, fecha de inicio, fecha de fin y seleccionar el programa a ejecutar, clic al botón "Aceptar" y la tarea se agregará al final de la lista, similar a la siguiente figura:
Comprobar que la tarea aparece en la consola del Task Scheduler de Windows (clic derecho y refrescar), además se ha programado para que después de un minuto del "Aceptar" se ejecute.
Clic derecho a la tarea creada recientemente y seleccionar la opción: "Eliminar Tarea", e inmediatamente se eliminará la tarea, también comprobarlo en la consola del Task Scheduler de Windows (clic derecho y refrescar).
Comentario
En este post hemos aprendido como crear nuestro propio Administrador de Tareas Programadas usando la clase TaskService de la librería manejada: Microsoft.Win32.TaskScheduler.dll.
Esto es de mucha utilidad cuando a veces nos restringen el acceso a las Herramientas de Windows y necesitamos crear una Nueva Tarea para ejecutar una aplicación, sobre todo para programas en Batch.
Descarga del Código
DemoDia_ProgramacionTareas