一个windows计划任务库demo

后面想法是要做成类似sql的可以增删改查的语法。

```rust

extern crate taskschd;

use std::ffi::{OsStr, OsString}; use std::path::Path;

use taskschd::taskschd::{hrisnotfound, TaskService}; use taskschd::tryto_bstring;

[test]

fn register() -> Result<(), failure::Error>{

let task_name = try_to_bstring!("name")?;
let task_folder = try_to_bstring!("\\")?;
let task_exe = Path::new("C:\\Windows\\System32\\cmd.exe");
let task_args = vec![OsString::from("/c ping 127.0.0.1 -t")];

let mut service = TaskService::connect_local()?;

// Get or create the folder
let mut folder = service.get_folder(&task_folder).or_else(|e| {
    if hr_is_not_found(&e) {
        service
            .get_root_folder()
            .and_then(|mut root| root.create_folder(&task_folder))
    } else {
        Err(e)
    }
})?;


let start_time = folder
        .get_task(&task_name)
        .ok()
        .and_then(|mut task| task.get_definition().ok())
        .and_then(|mut def| def.get_daily_triggers().ok())
        .and_then(|mut triggers| {
            // Currently we are only using 1 daily trigger.
            triggers
                .get_mut(0)
                .and_then(|trigger| trigger.get_StartBoundary().ok())
        });

let _ = folder.delete_task(&task_name);

let mut task_def = service.new_task_definition()?;

{


    let mut action = task_def.add_exec_action()?;
    action.put_Path(task_exe)?;
    //action.put_Arguments(task_args.as_slice())?;
    // TODO working directory?
}

{
    let mut settings = task_def.get_settings()?;
    settings.put_DisallowStartIfOnBatteries(false)?;
    settings.put_StopIfGoingOnBatteries(false)?;
    settings.put_StartWhenAvailable(true)?;
    settings.put_ExecutionTimeLimit(chrono::Duration::minutes(5))?;
}

{
    let mut info = task_def.get_registration_info()?;
    info.put_Author(&try_to_bstring!("author")?)?;
    info.put_Description(&try_to_bstring!("task test")?)?;
}

// A daily trigger starting 5 minutes ago.
{
    let mut daily_trigger = task_def.add_daily_trigger()?;
    if let Some(ref start_time) = start_time {
        daily_trigger.put_StartBoundary_BString(start_time)?;
    } else {
        daily_trigger.put_StartBoundary(chrono::Utc::now() - chrono::Duration::minutes(5))?;
    }
    daily_trigger.put_DaysInterval(1)?;
    // TODO: 12-hourly trigger? logon trigger?
}

let service_account = Some(try_to_bstring!("NT AUTHORITY\\LocalService")?);

let mut registered_task = task_def.create(&mut folder, &task_name, service_account.as_ref())?;

let sddl = try_to_bstring!(concat!(
        "D:(",   // DACL
        "A;",    // ace_type = Allow
        ";",     // ace_flags = none
        "GRGX;", // rights = Generic Read, Generic Execute
        ";;",    // object_guid, inherit_object_guid = none
        "BU)"    // account_sid = Built-in users
    ))?;

registered_task.set_sd(&sddl)?;

Ok(())

}

[test]

fn unregister() -> Result<(), failure::Error> { let taskname = trytobstring!("name")?; let taskfolder = trytobstring!("\")?;

let mut service = TaskService::connect_local()?;
let maybe_folder = service.get_folder(&task_folder);
let mut folder = match maybe_folder {
    Err(e) => {
        if hr_is_not_found(&e) {
            return Ok(());
        } else {
            return Err(e.into());
        }
    }
    Ok(folder) => folder,
};

folder.delete_task(&task_name).or_else(|e| {
    if hr_is_not_found(&e) {
        Ok(())
    } else {
        // Other errors are fatal.
        Err(e)
    }
})?;

let count = folder.get_task_count(true).unwrap_or_else(|e| {
    1
});

if count == 0 {
    let result = service
        .get_root_folder()
        .and_then(|mut root| root.delete_folder(&task_folder));
}

Ok(())

}

[test]

fn runondemand() -> Result<(), failure::Error> { let taskname = trytobstring!("name")?; let taskfolder = trytobstring!("\")?;

let mut service = TaskService::connect_local()?;
let task = service.get_folder(&task_folder)?.get_task(&task_name)?;

task.run()?;

Ok(())

}

```