2012-03-19 153 views
5

我想創建一個非常簡單的程序,兩分鐘後將運行記事本(這些都是簡化,使一個更清晰的問題)。我試圖合併一些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);,則顯示記事本。問題解決了 :)。

回答

3

設置標誌:

pITask->SetFlags(TASK_FLAG_RUN_ONLY_IF_LOGGED_ON); 

設置帳戶信息:

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

而完事大吉