试图创建一个计划任务运行一次使用C + +,任务计划1.0在WIN7

问题描述:

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

有人可以帮助解决这个问题吗? 如果某个任务在运行时记录了错误,那么该任务出现错误?注意1:我知道我计算开始时间的方式并不理想(并且在分钟为>57时,会给出错误结果)。正如我之前所说的,以下代码是一个简化版本。

注2:我在win7上运行它,我认为它与Task Scheduler 1.0 API兼容。此代码应该在XP和win7机器上运行(并且希望将来会赢得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; 
    } 

现在的任务是越来越显示在任务调度和正在被系统下执行帐户(Notepad.exe不显示,因为SYSTEM帐户不与桌面或某物交互)。如果我将其更改为hr = pITask->SetAccountInformation(L"MyUserName", NULL);,则显示记事本。问题解决了 :)。

设置标志:

pITask->SetFlags(TASK_FLAG_RUN_ONLY_IF_LOGGED_ON); 

设置帐户信息:

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

而完事大吉