c++ - 尝试创建计划任务以在 win7 上使用 C++、Task Scheduler 1.0 运行一次

标签 c++ windows winapi scheduled-tasks

我正在尝试创建一个非常简单的程序,它将在两分钟后运行记事本(这些都经过简化以提出更清晰的问题)。我试图合并一些 MSDN's examples 令我惊讶的是,一切都已成功编译,当运行程序时,在 C:\Windows\Tasks 中创建了一个 .job 任务。我在“Task Scheduler”GUI 程序中没有看到新任务,我认为这是因为“Task Scheduler”仅显示 Task Scheduler 2.0 任务,但我不确定。问题是任务没有被执行。我附上了代码,它有点长但有据可查。

有人可以帮忙解决这个问题吗? 如果任务在运行时出错,它记录在哪里?

注意 1:我知道我计算开始时间的方式并不理想(并且会在分钟为 >57 的时间给出错误结果)。正如我之前所说,下面的代码是一个简化版本。

注意 2:我在 win7 上运行它,我假设它与 Task Scheduler 1.0 API 兼容。这段代码应该可以在 XP 和 win7 机器上运行(希望将来可以在 win 8 上运行)

注意3:对于任何有勇气尝试的人来说,如果你得到错误0x80070050,这意味着同名的任务已经存在,删除.job文件或更改名称。

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

编辑:

我添加了以下内容:

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

  pITask->SetFlags(TASK_FLAG_RUN_ONLY_IF_LOGGED_ON);

和:

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

现在任务显示在任务计划程序中,并在 SYSTEM 帐户下执行(Notepad.exe 未显示,因为 SYSTEM 帐户未与桌面或其他东西交互)。如果我将其更改为 hr = pITask->SetAccountInformation(L"MyUserName", NULL);,则会显示记事本。问题已解决:)。

最佳答案

设置标志:

pITask->SetFlags(TASK_FLAG_RUN_ONLY_IF_LOGGED_ON);

设置账户信息:

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

鲍勃是你的叔叔

关于c++ - 尝试创建计划任务以在 win7 上使用 C++、Task Scheduler 1.0 运行一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9774644/

相关文章:

c++ - 在定义(.cpp 文件)中初始化 static float constexpr 成员是否可能

c++ - 由于 ADL,对模板函数的调用不明确

c++ - 在C++标准中,格式正确意味着代码可以编译吗?

c++ - 如何访问对象的成员变量解引用值

c++ - LZ函数的用法不清楚

windows - 使用 Desktop Duplication API 捕获登录和锁定屏幕

windows - Win 2008 64 位中的 ServerObject aspImage

Python:获取当前登录的用户及其特殊文件夹

windows - 在键盘上键入ALT + 251和ALT + 0251会产生不同的字符输入

c++ - 如何检测多显示器系统上的最大化事件