2010-11-30 3 views
0

Я создал планировщик на C++. Я установил все параметры, и задача настроена на запуск только тогда, когда пользователь вошел в систему с указанным именем пользователя (Done, установив TASK_FLAG_RUN_ONLY_IF_LOGGED_ON флаг).Планировщик заданий, созданный на C++, не может быть запущен

Когда я пытаюсь выполнить задачу, я получаю статус «Не удалось запустить». Теперь предположим, что я вручную изменяю любое свойство в свойстве задачи и нажимаю OK, задача выполняется нормально.

Примечание. Указанное вручную изменение может быть любым, например, просто добавлением пробела в конце имени excecutable или имени пользователя. В чем может быть проблема?

Ниже приведен код, я использую:

#include <windows.h> 
#include <initguid.h> 
#include <ole2.h> 
#include <mstask.h> 
#include <msterr.h> 
#include <wchar.h> 
#include<stdio.h> 
#include<conio.h> 

#pragma comment(lib, "Mstask.lib") 
#pragma comment(lib, "ole32.lib") 

int main(int argc, char **argv) 
{ 
HRESULT hr = S_OK; 
ITaskScheduler *pITS; 

/////////////////////////////////////////////////////////////////// 
// Call CoInitialize to initialize the COM library and then 
// 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; 
} 

LPCWSTR pwszTaskName; 
ITask *pITask; 
    pwszTaskName = L"TestTask"; 

hr = pITS->NewWorkItem(pwszTaskName, 
    CLSID_CTask, 
    IID_ITask, 
(IUnknown**)&pITask); 

    if (FAILED(hr)) 
{ 
    wprintf(L"Failed calling ITaskScheduler::NewWorkItem: "); 
    wprintf(L"error = 0x%x\n",hr); 
    CoUninitialize(); 
    return 1; 
    } 


    LPCWSTR pwszApplicationName = L"C:\\windows\\notepad.exe"; 

    hr = pITask->SetApplicationName(pwszApplicationName); 

    if (FAILED(hr)) 
{ 
    wprintf(L"Failed calling ITask::SetApplicationName: "); 
    wprintf(L"error = 0x%x\n",hr); 
    pITS->Release(); 
    pITask->Release(); 
    CoUninitialize(); 
    return 1; 
} 

    pITask->SetAccountInformation(L"USERNAME", NULL); 
    pITask->SetFlags(TASK_FLAG_RUN_ONLY_IF_LOGGED_ON); 
    pITask->SetWorkingDirectory(L"C:\\windows"); 


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

    pITS->AddWorkItem(pwszTaskName, pITask); 
    pITS->Release(); // Release sceduler 

    hr = pITask->Run(); 
    if (FAILED(hr)) 
    { 
    wprintf(L"Failed calling ITask::Run, error = 0x%x\n",hr); 
    pITask->Release(); 
    CoUninitialize(); 
    return 1; 
    } 

    pITask->Release();  
    CoUninitialize(); 
    _getch(); 
    return 0; 
} 
+1

Вы вообще не проводили отладки? Кажется, вы сбрасываете много кода, чтобы отлаживать вас. Вы должны начать процесс отладки самостоятельно. Отладка. – abelenky 2010-11-30 18:22:27

+3

Я бы хотел отладить вашу стену кода за 500 долларов за 10 минут. – 2010-11-30 18:24:12

ответ

0

Я думаю, что вы должны проверить все возвращаемые значения, которые могут быть показательными. Я в основном подозрительное:

pITask->SetAccountInformation(L"USERNAME", NULL); 
pITask->SetFlags(TASK_FLAG_RUN_ONLY_IF_LOGGED_ON); 

Readinig http://msdn.microsoft.com/en-us/library/aa381276(VS.85).aspx У меня создалось впечатление, что вам нужно позвонить SetFlags первым, а затем SetAccountInformation.

0

У меня была такая же проблема с XP: статус «Не удалось запустить» и все нормально после ручного редактирования.

  • Перейти к категории Расширенный поиск -> Просмотр журнала. И увидеть причину неудачи.
  • В моем случае была попытка «Извлечь информацию об учетной записи для указанной задачи». Поэтому мне просто нужно было ввести имя пользователя через GetUserName и установить его через SetAccountInformation. Примечание: порядок SetAccountInformation и SetFlags не имеет значения.
  • Посмотрите here по другим причинам.

Возможно, это когда-нибудь поможет кому-нибудь.