Essayer de créer une tâche programmée à exécuter une fois en utilisant C++, tâche Scheduler 1.0 sur win7

j'essaie de créer un programme très simple qui lancera Notepad après deux minutes (tout est simplifié pour rendre la question plus claire). J'ai essayé de fusionner quelques exemples de MSDN et à ma surprise tout compilé avec succès, lors de l'exécution du programme une tâche .job est créé dans C:WindowsTasks . Je ne vois pas la nouvelle tâche dans le programme GUI "Task Scheduler" et je suppose que c'est parce que "Task Scheduler" montre seulement les tâches Task Scheduler 2.0, mais je ne suis pas sûr. Le problème est que la tâche n'est pas exécutée. Je joins le code, il est un peu long mais bien documenté.

est-ce que quelqu'un peut aider à comprendre cela? Si une tâche a une erreur lors de l'exécution, où est-elle enregistrée?

Note 1: Je sais que la façon dont je calcule l'Heure de départ n'est pas idéale (et donnera des résultats erronés sur les temps où minutes est >57 ). Comme je l'ai dit avant le code ci-dessous est une version simplifiée.

Note 2: Je l'exécute sur win7 et je suppose qu'il est compatible avec L'API Task Scheduler 1.0. Ce code devrait s'exécuter sur les machines XP et win7 (et avec un peu de chance sur win 8 dans le futur)

Note 3: à quiconque est assez courageux pour l'essayer, si vous obtenez l'erreur 0x80070050 cela signifie qu'une tâche avec ce nom existe déjà, supprimez le fichier .job ou changez le nom.

#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%xn",hr);
     return 1;
  }

  /////////////////////////////////////////////////////////////////
  //Set Comment, Name, Working dir, Params
  /////////////////////////////////////////////////////////////////
  pITask->SetComment(L"This is a comment");
  pITask->SetApplicationName(L"C:WindowsSystem32notepad.exe");
  pITask->SetWorkingDirectory(L"C:WindowsSystem32");
  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%xn",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%xn",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%xn",hr);
     return 1;
  }


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


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

EDIT:

j'ai ajouté le

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

  pITask->SetFlags(TASK_FLAG_RUN_ONLY_IF_LOGGED_ON);

et:

///////////////////////////////////////////////////////////////////
  // 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%xn",hr);
    pITask->Release();
    CoUninitialize();
    return 1;
  }

maintenant la tâche s'affiche dans le planificateur de tâches et est exécutée sous compte système (Notepad.exe n'est pas affiché puisque le compte du système n'est pas interactif avec le bureau ou quelque chose). Si je le change en hr = pITask->SetAccountInformation(L"MyUserName", NULL); alors Notepad est affiché. Problème résolu :).

7
demandé sur zenpoy 2012-03-19 21:12:39

1 réponses

Flags:

pITask->SetFlags(TASK_FLAG_RUN_ONLY_IF_LOGGED_ON);

renseignements sur le compte de Set:

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

Et Bob's your uncle

5
répondu zenpoy 2012-03-20 07:36:53