2012-03-19 25 views
5

Estoy tratando de crear un programa muy simple que ejecutará el Bloc de notas después de dos minutos (todo se simplifica para hacer una pregunta más clara). Traté de fusionar algunos de MSDN's examples y para mi sorpresa todo compilado con éxito, cuando se ejecuta el programa se crea una tarea .job en C:\Windows\Tasks. No veo la nueva tarea en el programa de GUI "Programador de tareas" y asumo que esto se debe a que "Programador de tareas" solo muestra las tareas de Task Scheduler 2.0, pero no estoy seguro. El problema es que la tarea no se está ejecutando. Adjunto el código, es un poco largo pero está bien documentado.Intentando crear una tarea programada para ejecutar una vez usando C++, Programador de tareas 1.0 en win7

¿Alguien puede ayudar a resolver esto? Si una tarea tiene un error al ejecutar donde se registra?

Nota 1: Sé que la forma en que estoy calculando la hora de inicio no es ideal (y dará resultados erróneos en los momentos en que los minutos son >57). Como dije antes, el código a continuación es una versión simplificada.

Nota 2: Lo estoy ejecutando en win7 y supongo que es compatible con la API de Task Scheduler 1.0. Este código debe ejecutarse tanto en XP como en máquinas win7 (y con suerte en win 8 en el futuro)

Nota 3: Para cualquier persona que sea lo suficientemente valiente como para intentarlo, si obtiene el error 0x80070050 significa que ya existe una tarea con ese nombre existe, elimine el archivo .job o cambie el nombre.

#include <windows.h> 
#include <initguid.h> 
#include <ole2.h> 
#include <mstask.h> 
#include <msterr.h> 
#include <objidl.h> 
#include <wchar.h> 
#include <stdio.h> 


int main(int argc, char **argv) 
{ 
    HRESULT hr = S_OK; 
    ITaskScheduler *pITS; 


    ///////////////////////////////////////////////////////////////// 
    // Call CoInitialize to initialize the COM library and then 
    // call CoCreateInstance to get the Task Scheduler object. 
    ///////////////////////////////////////////////////////////////// 
    hr = CoInitialize(NULL); 
    if (SUCCEEDED(hr)) 
    { 
    hr = CoCreateInstance(CLSID_CTaskScheduler, 
          NULL, 
          CLSCTX_INPROC_SERVER, 
          IID_ITaskScheduler, 
          (void **) &pITS); 
    if (FAILED(hr)) 
    { 
     CoUninitialize(); 
     return 1; 
    } 
    } 
    else 
    { 
    return 1; 
    } 


    ///////////////////////////////////////////////////////////////// 
    // Call ITaskScheduler::NewWorkItem to create new task. 
    ///////////////////////////////////////////////////////////////// 
    LPCWSTR pwszTaskName; 
    ITask *pITask; 
    IPersistFile *pIPersistFile; 
    pwszTaskName = L"Test Task"; 

    hr = pITS->NewWorkItem(pwszTaskName,   // Name of task 
         CLSID_CTask,   // Class identifier 
         IID_ITask,   // Interface identifier 
         (IUnknown**)&pITask); // Address of task 
                                                  // interface 


    pITS->Release();        // Release object 
    if (FAILED(hr)) 
    { 
    CoUninitialize(); 
    fprintf(stderr, "Failed calling NewWorkItem, error = 0x%x\n",hr); 
    return 1; 
    } 

    ///////////////////////////////////////////////////////////////// 
    //Set Comment, Name, Working dir, Params 
    ///////////////////////////////////////////////////////////////// 
    pITask->SetComment(L"This is a comment"); 
    pITask->SetApplicationName(L"C:\\Windows\\System32\\notepad.exe"); 
    pITask->SetWorkingDirectory(L"C:\\Windows\\System32"); 
    pITask->SetParameters(L""); 

    /////////////////////////////////////////////////////////////////// 
    // Call ITask::CreateTrigger to create new trigger. 
    /////////////////////////////////////////////////////////////////// 

    ITaskTrigger *pITaskTrigger; 
    WORD piNewTrigger; 
    hr = pITask->CreateTrigger(&piNewTrigger, 
          &pITaskTrigger); 
    if (FAILED(hr)) 
    { 
    wprintf(L"Failed calling ITask::CreatTrigger: "); 
    wprintf(L"error = 0x%x\n",hr); 
    pITask->Release(); 
    CoUninitialize(); 
    return 1; 
    } 

////////////////////////////////////////////////////// 
    // 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)); 

    LPSYSTEMTIME lpSystemTime; 
    GetLocalTime(lpSystemTime); 


    // Add code to set trigger structure? 
    pTrigger.wBeginDay = lpSystemTime->wDay;     // Required 
    pTrigger.wBeginMonth = lpSystemTime->wMonth;    // Required 
    pTrigger.wBeginYear =lpSystemTime->wYear;    // Required 
    pTrigger.cbTriggerSize = sizeof (TASK_TRIGGER); 
    pTrigger.wStartHour = lpSystemTime->wHour; 
    pTrigger.wStartMinute = lpSystemTime->wMinute + 2; 
    pTrigger.TriggerType = TASK_TIME_TRIGGER_DAILY; 
    pTrigger.Type.Daily.DaysInterval = 1; 


    /////////////////////////////////////////////////////////////////// 
    // Call ITaskTrigger::SetTrigger to set trigger criteria. 
    /////////////////////////////////////////////////////////////////// 

    hr = pITaskTrigger->SetTrigger (&pTrigger); 
    if (FAILED(hr)) 
    { 
    wprintf(L"Failed calling ITaskTrigger::SetTrigger: "); 
    wprintf(L"error = 0x%x\n",hr); 
    pITask->Release(); 
    pITaskTrigger->Release(); 
    CoUninitialize(); 
    return 1; 
    } 




    ///////////////////////////////////////////////////////////////// 
    // Call IUnknown::QueryInterface to get a pointer to 
    // IPersistFile and IPersistFile::Save to save 
    // the new task to disk. 
    ///////////////////////////////////////////////////////////////// 

    hr = pITask->QueryInterface(IID_IPersistFile, 
           (void **)&pIPersistFile); 

    pITask->Release(); 
    if (FAILED(hr)) 
    { 
    CoUninitialize(); 
    fprintf(stderr, "Failed calling QueryInterface, error = 0x%x\n",hr); 
    return 1; 
    } 


    hr = pIPersistFile->Save(NULL, 
          TRUE); 
    pIPersistFile->Release(); 
    if (FAILED(hr)) 
    { 
    CoUninitialize(); 
    fprintf(stderr, "Failed calling Save, error = 0x%x\n",hr); 
    return 1; 
    } 


    CoUninitialize(); 
    printf("Created task.\n"); 
    return 0; 
} 

EDIT:

que añade lo siguiente:

///////////////////////////////////////////////////////////////// 
    //Set Flags 
    ///////////////////////////////////////////////////////////////// 

    pITask->SetFlags(TASK_FLAG_RUN_ONLY_IF_LOGGED_ON); 

y:

/////////////////////////////////////////////////////////////////// 
    // Call ITask::SetAccountInformation to specify the account name 
    // and the account password for Test Task. 
    /////////////////////////////////////////////////////////////////// 
    hr = pITask->SetAccountInformation(L"", 
      NULL); 


    if (FAILED(hr)) 
    { 
    wprintf(L"Failed calling ITask::SetAccountInformation: "); 
    wprintf(L"error = 0x%x\n",hr); 
    pITask->Release(); 
    CoUninitialize(); 
    return 1; 
    } 

Ahora la tarea es conseguir visualiza en el programador de tareas y se está ejecutando bajo el sistema cuenta (Notepad.exe no se muestra porque la cuenta de SYSTEM no es interactiva con el escritorio o algo así). Si lo cambio a hr = pITask->SetAccountInformation(L"MyUserName", NULL);, se muestra el Bloc de notas. Problema resuelto :).

Respuesta

3

Fije los indicadores:

pITask->SetFlags(TASK_FLAG_RUN_ONLY_IF_LOGGED_ON); 

Establecer información de cuenta:

hr = pITask->SetAccountInformation(L"Username", 
      NULL); 

Y Bob es tu tío

Cuestiones relacionadas