任务计划程序API错误80041318

时间:2017-02-17 21:43:34

标签: c++ qt scheduled-tasks

您好我的QT C ++程序中的Task Scheduler API存在问题。我使用示例代码进行登录触发器here

我收到的第一个错误是 CoInitializeSecurity失败:RPC_E_TOO_LATE ,这意味着 根据{{​​3}},已经调用了 CoInitializeSecurity。。所以我评论了关于初始化安全性的电话,并确定了这一点。

但是现在我在尝试执行最后一个 RegisterTaskDefinition 步骤时遇到80041318错误。我读here这意味着格式错误或超出范围,也可能是 pLogonTrigger 的错误参数。我试着注释掉pLogonTrigger的起始边界和结束边界代码,但没有帮助。我还将pLogonTrigger UserId和userId参数更改为 RegisterTaskDefinition 功能更改为我的帐户 L“Josh”。剩下的pLogonTrigger的唯一参数是通过 put_Id put_UserId 指定的。

如果有帮助,我是否应该包含任何代码?如果是,那么代码是什么?代码与示例代码几乎完全相同,除了pLogonTrigger修改,userId mods以及从硬件安全性中注释掉。

*已编辑的代码已添加

void Replicator::taskCreate()
{
    /*QProcess *taskProcess = new QProcess(this);
    QString program = "schtasks.exe";
    QStringList arguments;
    arguments << "/create" << "/XML" << "rep.xml" << "/tn" << "task";
    taskProcess->start(program, arguments);*/

    //  ------------------------------------------------------
    //  Initialize COM.
    QString code;
    HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
    if( FAILED(hr) )
    {
        //updateStatus("\nCoInitializeEx failed: " + QString("%1").arg(hr,8,16,QLatin1Char('0')));
        switch (hr)
        {
        case S_OK:
            code = "S_OK";
            break;
        case S_FALSE:
            code = "S_FALSE";
            break;
        case RPC_E_CHANGED_MODE:
            code = "RPC_E_CHANGED_MODE";
            break;
        }

        updateStatus("CoInitializeEx failed: " + QString("%1").arg(hr,8,16,QLatin1Char('0')) + code);
        return;
    }

    //  Set general COM security levels.
/*    hr = CoInitializeSecurity(
                NULL,
                -1,
                NULL,
                NULL,
                RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
                RPC_C_IMP_LEVEL_IMPERSONATE,
                NULL,
                0,
                NULL);

    if( FAILED(hr) )
    {
        switch (hr)
        {
        case S_OK:
            code = "S_OK";
            break;
        case RPC_E_TOO_LATE:
            code = "RPC_E_TOO_LATE";
            break;
        case RPC_E_NO_GOOD_SECURITY_PACKAGES:
            code = "RPC_E_NO_GOOD_SECURITY_PACKAGES";
            break;
        //case E_OUTOFMEMORY:
        //    code = "E_OUTOFMEMORY";
        //    break;
        }

        updateStatus("CoInitializeSecurity failed: " + code);
        CoUninitialize();
        return;
    }*/

    //  ------------------------------------------------------
    //  Create a name for the task.
    LPCWSTR wszTaskName = L"Jerp";

    //  Get the windows directory and set the path to notepad.exe.
    wstring wstrExecutablePath = _wgetenv( L"WINDIR");
    wstrExecutablePath += L"\\SYSTEM32\\NOTEPAD.EXE";


    //  ------------------------------------------------------
    //  Create an instance of the Task Service.
    ITaskService *pService = NULL;
    hr = CoCreateInstance( CLSID_TaskScheduler,
                           NULL,
                           CLSCTX_INPROC_SERVER,
                           IID_ITaskService,
                           (void**)&pService );
    if (FAILED(hr))
    {
        updateStatus("Failed to create an instance of ITaskService: " + QString("%1").arg(hr,8,16,QLatin1Char('0')));
        CoUninitialize();
        return;
    }

    //  Connect to the task service.
    hr = pService->Connect(_variant_t(), _variant_t(),
                           _variant_t(), _variant_t());
    if( FAILED(hr) )
    {
        updateStatus("ITaskService::Connect failed: " + QString("%1").arg(hr,8,16,QLatin1Char('0')));
        pService->Release();
        CoUninitialize();
        return;
    }

    //  ------------------------------------------------------
    //  Get the pointer to the root task folder.  This folder will hold the
    //  new task that is registered.
    ITaskFolder *pRootFolder = NULL;
    hr = pService->GetFolder( _bstr_t( L"\\") , &pRootFolder );
    if( FAILED(hr) )
    {
        updateStatus("Cannot get Root Folder pointer: " + QString("%1").arg(hr,8,16,QLatin1Char('0')));
        pService->Release();
        CoUninitialize();
        return;
    }

    //  If the same task exists, remove it.
    pRootFolder->DeleteTask( _bstr_t( wszTaskName), 0  );

    //  Create the task builder object to create the task.
    ITaskDefinition *pTask = NULL;
    hr = pService->NewTask( 0, &pTask );

    pService->Release();  // COM clean up.  Pointer is no longer used.
    if (FAILED(hr))
    {
        updateStatus("Failed to create a task definition: " + QString("%1").arg(hr,8,16,QLatin1Char('0')));
        pRootFolder->Release();
        CoUninitialize();
        return;
    }

    //  ------------------------------------------------------
    //  Get the registration info for setting the identification.
    IRegistrationInfo *pRegInfo= NULL;
    hr = pTask->get_RegistrationInfo( &pRegInfo );
    if( FAILED(hr) )
    {
        updateStatus("Cannot get identification pointer: " + QString("%1").arg(hr,8,16,QLatin1Char('0')));
        pRootFolder->Release();
        pTask->Release();
        CoUninitialize();
        return;
    }

    //hr = pRegInfo->put_Author(L"Author Name");
    BSTR authorName = SysAllocString(L"Josh");
    hr = pRegInfo->put_Author(authorName);
    pRegInfo->Release();
    if( FAILED(hr) )
    {
        updateStatus("Cannot put identification info: " + QString("%1").arg(hr,8,16,QLatin1Char('0')));
        pRootFolder->Release();
        pTask->Release();
        CoUninitialize();
        return;
    }

    //  ------------------------------------------------------
    //  Create the settings for the task
    /*ITaskSettings *pSettings = NULL;
    hr = pTask->get_Settings( &pSettings );
    if( FAILED(hr) )
    {
        updateStatus("Cannot get settings pointer: " + QString("%1").arg(hr,8,16,QLatin1Char('0')));
        pRootFolder->Release();
        pTask->Release();
        CoUninitialize();
        return;
    }

    //  Set setting values for the task.
    hr = pSettings->put_StartWhenAvailable(VARIANT_TRUE);
    pSettings->Release();
    if( FAILED(hr) )
    {
        updateStatus("Cannot put setting info: " + QString("%1").arg(hr,8,16,QLatin1Char('0')));
        pRootFolder->Release();
        pTask->Release();
        CoUninitialize();
        return;
    }*/

    //  ------------------------------------------------------
    //  Get the trigger collection to insert the logon trigger.
    ITriggerCollection *pTriggerCollection = NULL;
    hr = pTask->get_Triggers( &pTriggerCollection );
    if( FAILED(hr) )
    {
        updateStatus("Cannot get trigger collection: " + QString("%1").arg(hr,8,16,QLatin1Char('0')));
        pRootFolder->Release();
        pTask->Release();
        CoUninitialize();
        return;
    }

    //  Add the logon trigger to the task.
    ITrigger *pTrigger = NULL;
    hr = pTriggerCollection->Create( TASK_TRIGGER_LOGON, &pTrigger );
    pTriggerCollection->Release();
    if( FAILED(hr) )
    {
        updateStatus("Cannot create the trigger: " + QString("%1").arg(hr,8,16,QLatin1Char('0')));
        pRootFolder->Release();
        pTask->Release();
        CoUninitialize();
        return;
    }

    ILogonTrigger *pLogonTrigger = NULL;
    hr = pTrigger->QueryInterface(
                IID_ILogonTrigger, (void**) &pLogonTrigger );
    pTrigger->Release();
    if( FAILED(hr) )
    {
        updateStatus("QueryInterface call failed for ILogonTrigger: " + QString("%1").arg(hr,8,16,QLatin1Char('0')));
        pRootFolder->Release();
        pTask->Release();
        CoUninitialize();
        return;
    }

    hr = pLogonTrigger->put_Id( _bstr_t( L"Trigger1" ) );
    if( FAILED(hr) )
        updateStatus("Cannot put the trigger ID: " + QString("%1").arg(hr,8,16,QLatin1Char('0')));

    //  Set the task to start at a certain time. The time
    //  format should be YYYY-MM-DDTHH:MM:SS(+-)(timezone).
    //  For example, the start boundary below
    //  is January 1st 2005 at 12:05
    /*hr = pLogonTrigger->put_StartBoundary( _bstr_t(L"2005-01-01T12:05:00") );
    if( FAILED(hr) )
        updateStatus("Cannot put the start boundary: " + QString("%1").arg(hr,8,16,QLatin1Char('0')));

    hr = pLogonTrigger->put_EndBoundary( _bstr_t(L"2025-05-02T08:00:00") );
    if( FAILED(hr) )
        updateStatus("Cannot put the end boundary: " + QString("%1").arg(hr,8,16,QLatin1Char('0')));*/

    //  Define the user.  The task will execute when the user logs on.
    //  The specified user must be a user on this computer.
    //hr = pLogonTrigger->put_UserId( _bstr_t( L"DOMAIN\\UserName" ) );
    //hr = pLogonTrigger->put_UserId( _bstr_t( L"JOSHDESKTOP10\\Josh" ) );
    hr = pLogonTrigger->put_UserId( _bstr_t( L"Josh" ) );
    pLogonTrigger->Release();
    if( FAILED(hr) )
    {
        updateStatus("Cannot add user ID to logon trigger: " + QString("%1").arg(hr,8,16,QLatin1Char('0')));
        pRootFolder->Release();
        pTask->Release();
        CoUninitialize();
        return;
    }

    //  ------------------------------------------------------
    //  Add an Action to the task. This task will execute notepad.exe.
    IActionCollection *pActionCollection = NULL;

    //  Get the task action collection pointer.
    hr = pTask->get_Actions( &pActionCollection );
    if( FAILED(hr) )
    {
        updateStatus("Cannot get Task collection pointer: " + QString("%1").arg(hr,8,16,QLatin1Char('0')));
        pRootFolder->Release();
        pTask->Release();
        CoUninitialize();
        return;
    }

    //  Create the action, specifying that it is an executable action.
    IAction *pAction = NULL;
    hr = pActionCollection->Create( TASK_ACTION_EXEC, &pAction );
    pActionCollection->Release();
    if( FAILED(hr) )
    {
        updateStatus("Cannot create the action: " + QString("%1").arg(hr,8,16,QLatin1Char('0')));
        pRootFolder->Release();
        pTask->Release();
        CoUninitialize();
        return;
    }

    IExecAction *pExecAction = NULL;
    //  QI for the executable task pointer.
    hr = pAction->QueryInterface(
                IID_IExecAction, (void**) &pExecAction );
    pAction->Release();
    if( FAILED(hr) )
    {
        updateStatus("QueryInterface call failed for IExecAction: " + QString("%1").arg(hr,8,16,QLatin1Char('0')));
        pRootFolder->Release();
        pTask->Release();
        CoUninitialize();
        return;
    }

    //  Set the path of the executable to notepad.exe.
    hr = pExecAction->put_Path( _bstr_t( wstrExecutablePath.c_str() ) );
    pExecAction->Release();
    if( FAILED(hr) )
    {
        updateStatus("Cannot set path of executable: " + QString("%1").arg(hr,8,16,QLatin1Char('0')));
        pRootFolder->Release();
        pTask->Release();
        CoUninitialize();
        return;
    }

    //  ------------------------------------------------------
    //  Save the task in the root folder.
    IRegisteredTask *pRegisteredTask = NULL;

    /*hr = pRootFolder->RegisterTaskDefinition(
                _bstr_t( wszTaskName ),
                pTask,
                TASK_CREATE_OR_UPDATE,
                //_variant_t(L"Builtin\\Administrators"),
                _variant_t(L"Josh"),
                _variant_t(),
                TASK_LOGON_PASSWORD,
                _variant_t(L""),
                &pRegisteredTask);*/

    hr = pRootFolder->RegisterTaskDefinition(
                _bstr_t( wszTaskName ),
                pTask,
                TASK_CREATE_OR_UPDATE,
                //_variant_t(L"Builtin\\Administrators"),
                _variant_t(),
                _variant_t(),
                TASK_LOGON_GROUP,
                _variant_t(L""),
                &pRegisteredTask);

    if( FAILED(hr) )
    {
        switch (hr)
        {
        case E_ACCESSDENIED:
            code = "E_ACCESSDENIED";
            break;
        case E_OUTOFMEMORY:
            code = "E_OUTOFMEMORY";
            break;
        case SCHED_S_BATCH_LOGON_PROBLEM:
            code = "SCHED_S_BATCH_LOGON_PROBLEM";
            break;
        case SCHED_S_SOME_TRIGGERS_FAILED:
            code = "SCHED_S_SOME_TRIGGERS_FAILED";
            break;
        }

        updateStatus("Error saving the Task : " + QString("%1").arg(hr,8,16,QLatin1Char('0')) + code);
        pRootFolder->Release();
        pTask->Release();
        CoUninitialize();
        return;
    }

    updateStatus(" Success! Task successfully registered. " );

    // Clean up
    pRootFolder->Release();
    pTask->Release();
    pRegisteredTask->Release();
    CoUninitialize();
}

1 个答案:

答案 0 :(得分:0)

经过大量的故障排除后,最终解决了这个问题...答案很简单:将 UserId 设置为适当的用户,在我的情况下为“Josh”,您可以使用Win32 API getusername 功能,如果您需要

hr = pLogonTrigger->put_UserId( _bstr_t( L"Josh" ) );

然后对于 RegisterTaskDefinition 执行此操作:

VARIANT varPassword;
varPassword.vt = VT_EMPTY;
hr = pRootFolder->RegisterTaskDefinition(
            _bstr_t( wszTaskName ),
            pTask,
            TASK_CREATE_OR_UPDATE,
            _variant_t(L"Builtin\\Administrators"),
            varPassword,
            TASK_LOGON_GROUP,
            _variant_t(L""),
            &pRegisteredTask);

RegisterTaskDefinition userID 参数必须为 _variant_t(L“Builtin \ Administrators”) logonType 需要 TASK_LOGON_GROUP

所以主要的一点是两个UserId值不一定相同。