2012-03-19 6 views
5

Sto provando a creare un programma molto semplice che eseguirà Blocco note dopo due minuti (questi sono tutti semplificati per fare una domanda più chiara). Ho provato a unire un po 'di MSDN's examples e con mia sorpresa tutto è stato compilato correttamente, quando si esegue il programma viene creata un'attività .job in C:\Windows\Tasks. Non vedo la nuova attività nel programma della GUI "Utilità di pianificazione" e presumo che ciò sia dovuto al fatto che "Utilità di pianificazione" mostra solo le attività dell'Utilità di pianificazione 2.0, ma non ne sono sicuro. Il problema è che l'attività non viene eseguita. Vi allego il codice, è un po 'lungo ma ben documentato.Provare a creare un'operazione pianificata da eseguire una volta utilizzando C++, Utilità di pianificazione 1.0 su win7

Qualcuno può aiutare a capirlo? Se un'attività ha ricevuto un errore durante l'esecuzione, dove viene registrato?

Nota 1: so che il modo in cui sto calcolando l'ora di inizio non è l'ideale (e fornirà risultati errati nei momenti in cui i minuti sono >57). Come ho detto prima il codice sotto è una versione semplificata.

Nota 2: lo sto eseguendo su win7 e presumo sia compatibile con l'API di Utilità di pianificazione 1.0. Questo codice dovrebbe essere eseguito su entrambe le macchine XP e Win7 (e spero che vinca 8 in futuro)

Nota 3: per chiunque abbia il coraggio di provarlo, se ottieni l'errore 0x80070050 significa che un'attività con quel nome già esiste, eliminare il file .job o modificare il nome.

#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:

ho aggiunto quanto segue:

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

    pITask->SetFlags(TASK_FLAG_RUN_ONLY_IF_LOGGED_ON); 

e:

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

Ora il compito è sempre visualizzato nella task scheduler e che viene eseguito sotto SISTEMA account (Notepad.exe non viene visualizzato poiché l'account SYSTEM non è interattivo con desktop o qualcosa del genere). Se lo cambio su hr = pITask->SetAccountInformation(L"MyUserName", NULL);, viene visualizzato Blocco note. Problema risolto :).

risposta

3

Set Flags:

pITask->SetFlags(TASK_FLAG_RUN_ONLY_IF_LOGGED_ON); 

Impostazione informazioni sull'account:

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

E il gioco è fatto