【问题标题】:Why do I get a success code when I start a task, but it does nothing?为什么我在开始任务时会收到成功代码,但它什么也没做?
【发布时间】:2020-03-23 03:18:35
【问题描述】:

请帮我解决一个问题。我正在尝试复制系统 RegIdleBackup 任务并启动复制的任务。我使用 ITaskService api 成功复制了任务,并更改了其中的一些设置。毕竟我试图运行这个任务,我得到了返回码S_OK,但是任务计划程序窗口中的任务信息没有改变,备份文件也没有更新。我可以从任务调度程序手动运行此任务,并且我复制的任务运行良好。我的问题是启动方法,但我找不到。谢谢。

这是我的代码

HRESULT GetTask(ITaskService* pService, const std::wstring& fullTaskName, IRegisteredTask** pTask)
{
    ITaskFolder* pFolder = nullptr;
    HRESULT hr = pService->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t());
    if (FAILED(hr))
        return hr;

    const std::wstring taskFolder = fullTaskName.substr(0, fullTaskName.find_last_of(L'\\'));
    const std::wstring taskName = fullTaskName.substr(fullTaskName.find_last_of(L'\\') + 1);
    hr = pService->GetFolder(_bstr_t(taskFolder.c_str()), &pFolder);
    if (FAILED(hr))
        return hr;

    hr = pFolder->GetTask(SysAllocString(L"RegIdleBackup"), pTask);
    pFolder->Release();
    return hr;
}

HRESULT CreateTaskCopy(ITaskService* pService, IRegisteredTask* pTask, const std::wstring& fullTaskName)
{
    ITaskFolder* pFolder = nullptr;
    HRESULT hr = pService->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t());
    if (FAILED(hr))
        return hr;

    const std::wstring taskFolder = fullTaskName.substr(0, fullTaskName.find_last_of(L'\\'));
    const std::wstring taskName = fullTaskName.substr(fullTaskName.find_last_of(L'\\') + 1);
    hr = pService->GetFolder(_bstr_t(taskFolder.c_str()), &pFolder);
    pService->Release();

    if (FAILED(hr))
        return hr;

    ITaskDefinition* pTaskDef = nullptr;
    ITaskSettings* pTaskSettings = nullptr;
    IRegisteredTask* iTask = nullptr;
    hr = pTask->get_Definition(&pTaskDef);
    if (FAILED(hr))
        goto exit;
    hr = pTaskDef->get_Settings(&pTaskSettings);
    if (FAILED(hr))
        goto exit;
    hr = pTaskSettings->put_AllowDemandStart(_variant_t(TRUE));
    if (FAILED(hr))
        goto exit;
    hr = pTaskSettings->put_MultipleInstances(TASK_INSTANCES_PARALLEL);
    if (FAILED(hr))
        goto exit;

    hr = pTaskDef->put_Settings(pTaskSettings);
    if (FAILED(hr))
        goto exit;
    pTaskSettings->Release();
    pTaskSettings = nullptr;

    hr = pFolder->DeleteTask(_bstr_t(taskName.c_str()), 0);
    hr = pFolder->RegisterTaskDefinition(_bstr_t(taskName.c_str()),
        pTaskDef,
        TASK_CREATE_OR_UPDATE,
        _variant_t(),
        _variant_t(),
        TASK_LOGON_SERVICE_ACCOUNT,
        _variant_t(L""),
        &iTask);

exit:
    if (pTaskSettings)
        pTaskSettings->Release();
    if (iTask)
        iTask->Release();
    if (pTaskDef)
        pTaskDef->Release();
    return hr;
}

HRESULT CopyTask(const std::wstring& fullTaskName, const std::wstring& copyName)
{
    ITaskService* pService = nullptr;
    IRegisteredTask* pTask = nullptr;
    HRESULT hr = CoCreateInstance(CLSID_TaskScheduler, nullptr, CLSCTX_INPROC_SERVER, IID_ITaskService, (void**)&pService);
    if (FAILED(hr))
        return hr;

    hr = GetTask(pService, fullTaskName, &pTask);
    if (FAILED(hr))
        goto exit;

    hr = CreateTaskCopy(pService, pTask, copyName);

exit:
    if(pService)
        pService->Release();
    if (pTask)
        pTask->Release();
    return hr;
}

HRESULT StartTask(const std::wstring& fullTaskName)
{
    ITaskService* pService = nullptr;
    HRESULT hr = CoCreateInstance(CLSID_TaskScheduler, nullptr, CLSCTX_INPROC_SERVER, IID_ITaskService, (void**)&pService);
    if (FAILED(hr))
        return hr;

    pService->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t());
    if (FAILED(hr))
    {
        pService->Release();
        return hr;
    }

    const std::wstring taskFolder = fullTaskName.substr(0, fullTaskName.find_last_of(L'\\'));
    const std::wstring taskName = fullTaskName.substr(fullTaskName.find_last_of(L'\\') + 1);
    ITaskFolder* pFolder = nullptr;
    hr = pService->GetFolder(_bstr_t(taskFolder.c_str()), &pFolder);
    pService->Release();
    if (FAILED(hr))
        return hr;

    IRegisteredTask* pTask = nullptr;
    pFolder->GetTask(_bstr_t(taskName.c_str()), &pTask);
    pFolder->Release();

    IRunningTask* pRunningTask = nullptr;
    hr = pTask->RunEx(_variant_t(),0,0, _bstr_t(L"S-1-5-18"), &pRunningTask);
    pTask->Release();

    return hr;
}

int _tmain(int argc, _TCHAR* argv[])
{
    HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
    if (FAILED(hr))
        return hr;

    hr = CoInitializeSecurity(nullptr, -1, nullptr, nullptr, RPC_C_AUTHN_LEVEL_PKT_PRIVACY, RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, 0, nullptr);
    if (FAILED(hr))
        return hr;

    hr = CopyTask(L"\\Microsoft\\Windows\\Registry\\RegIdleBackup", L"\\Microsoft\\Windows\\Registry\\MyTask");
    hr = StartTask(L"\\Microsoft\\Windows\\Registry\\MyTask");

    CoUninitialize();
    return hr;
}

【问题讨论】:

    标签: c++ windows scheduled-tasks taskscheduler


    【解决方案1】:

    今天早上我尝试用替换启动触发器来运行任务,同时修复了一些任务设置。一切都很好,毕竟我开始在 Win 7 上测试我的程序,一切都很好,但是在 Win10 上我遇到了一些有趣的问题,任务创建时使用了另一个上次启动时间(Win7 字段为空,Win 10 消息 - “任务之前从未启动过”),我尝试使用 IRegisteredTask::Run 方法,它成功了!我在其他操作系统上测试并运行方法工作。我粘贴了我的代码示例,也许它对某人有用。

    HRESULT GetTaskDefinition(ITaskService* pService, const std::wstring& fullTaskName, ITaskDefinition** pTask)
    {
        ITaskFolder* pFolder = nullptr;
        IRegisteredTask* pRegTask = nullptr;
        HRESULT hr = pService->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t());
        if (FAILED(hr))
            return hr;
    
        const std::wstring taskFolder = fullTaskName.substr(0, fullTaskName.find_last_of(L'\\'));
        const std::wstring taskName = fullTaskName.substr(fullTaskName.find_last_of(L'\\') + 1);
        hr = pService->GetFolder(_bstr_t(taskFolder.c_str()), &pFolder);
        if (FAILED(hr))
            return hr;
    
        hr = pFolder->GetTask(SysAllocString(L"RegIdleBackup"), &pRegTask);
        pFolder->Release();
        if (FAILED(hr))
            return hr;
    
        hr = pRegTask->get_Definition(pTask);
        return hr;
    }
    
    HRESULT ChangeTaskSettings(ITaskDefinition* pTaskDef)
     {
        ITaskSettings* pTaskSettings = nullptr;
        HRESULT hr = pTaskDef->get_Settings(&pTaskSettings);
        if (FAILED(hr))
            return hr;
        hr = pTaskSettings->put_AllowDemandStart(VARIANT_TRUE);
        hr = pTaskSettings->put_MultipleInstances(TASK_INSTANCES_PARALLEL);
        hr = pTaskSettings->put_RunOnlyIfIdle(VARIANT_FALSE);
        hr = pTaskSettings->put_StartWhenAvailable(VARIANT_TRUE);
        hr = pTaskSettings->put_StopIfGoingOnBatteries(VARIANT_FALSE);
        hr = pTaskSettings->put_Enabled(VARIANT_FALSE);
        hr = pTaskSettings->put_DisallowStartIfOnBatteries(VARIANT_FALSE);
        hr = pTaskDef->put_Settings(pTaskSettings);
        pTaskSettings->Release();
        return hr;
    }
    
    FILETIME AddSecondsToFIleTime(FILETIME ft, unsigned seconds)
    {
        FILETIME res;
    #define _SECONDS ((__int64) 10000000) //100 ns intervals in second
        ULONGLONG tmp = (static_cast<ULONGLONG>(ft.dwHighDateTime) << 32) + ft.dwLowDateTime + seconds*_SECONDS;
        res.dwLowDateTime = static_cast<DWORD>(tmp & 0xFFFFFFFF);
        res.dwHighDateTime = static_cast<DWORD>(tmp >> 32);
        return res;
    }
    
    std::wstring GetTaskLaunchTimeWstring(SYSTEMTIME st, unsigned wait_interval)
    {
        FILETIME ft;
        SystemTimeToFileTime(&st, &ft);
        ft = AddSecondsToFIleTime(ft, wait_interval);
        FileTimeToSystemTime(&ft, &st);
        std::stringstream ss;
        ss << std::setfill('0') << std::setw(2) << st.wYear << "-" << 
            std::setfill('0') << std::setw(2) << st.wMonth << "-" << 
            std::setfill('0') << std::setw(2) << st.wDay << "T" <<
            std::setfill('0') << std::setw(2) << st.wHour << ":" <<
            std::setfill('0') << std::setw(2) << st.wMinute << ":" << 
            std::setfill('0') << std::setw(2) << st.wSecond;
        std::string str = ss.str();
        return std::wstring(str.begin(), str.end());
    }
    
    HRESULT ChangeTaskTriggers(ITaskDefinition* pTaskDef, const std::wstring& LaunchTimeStr)
     {
        ITriggerCollection* pTriggersCollection = nullptr;
        HRESULT hr = pTaskDef->get_Triggers(&pTriggersCollection);
        hr = pTriggersCollection->Clear();
    
        ITrigger* pTrigger = nullptr;
        hr = pTriggersCollection->Create(TASK_TRIGGER_TIME, &pTrigger);
        pTriggersCollection->Release();
        if (FAILED(hr))
            return hr;
    
        ITimeTrigger* pTimeTrigger = nullptr;
        hr = pTrigger->QueryInterface(IID_ITimeTrigger, reinterpret_cast<void**>(&pTimeTrigger));
        pTrigger->Release();
        if (FAILED(hr))
            return hr;
    
        hr = pTimeTrigger->put_Id(_bstr_t(L"Trigger"));
        hr = pTimeTrigger->put_Enabled(VARIANT_TRUE);
        hr = pTimeTrigger->put_StartBoundary(_bstr_t(LaunchTimeStr.c_str()));
        pTimeTrigger->Release();
    
        return hr;
     }
    
    HRESULT RegisterTask(ITaskService* pService, ITaskDefinition* pTaskDef, const std::wstring& fullTaskName)
    {
        ITaskFolder* pFolder = nullptr;
        HRESULT hr = pService->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t());
        if (FAILED(hr))
            return hr;
    
        const std::wstring taskFolder = fullTaskName.substr(0, fullTaskName.find_last_of(L'\\'));
        const std::wstring taskName = fullTaskName.substr(fullTaskName.find_last_of(L'\\') + 1);
    
        hr = pService->GetFolder(_bstr_t(taskFolder.c_str()), &pFolder);
        pService->Release();
        if (FAILED(hr))
            return hr;
    
    
        IRegisteredTask* pRegisteredTAsk = nullptr;
        hr = pFolder->DeleteTask(_bstr_t(taskName.c_str()), 0);
        hr = pFolder->RegisterTaskDefinition(_bstr_t(taskName.c_str()),
            pTaskDef,
            TASK_CREATE_OR_UPDATE,
            _variant_t(),
            _variant_t(),
            TASK_LOGON_SERVICE_ACCOUNT,
            _variant_t(L""),
            &pRegisteredTAsk);
    
        if (SUCCEEDED(hr))
        {
            pRegisteredTAsk->put_Enabled(VARIANT_TRUE);
            pRegisteredTAsk->Release();
        }
    
        return hr;
    }
    
    HRESULT CreateModifiedTaskCopy(const std::wstring& fullTaskName, const std::wstring& copyName, unsigned seconds_to_start)
    {
        ITaskService* pService = nullptr;
        ITaskDefinition* pTaskDef = nullptr;
        HRESULT hr = CoCreateInstance(CLSID_TaskScheduler, nullptr, CLSCTX_INPROC_SERVER, IID_ITaskService, (void**)&pService);
        if (FAILED(hr))
            return hr;
    
        hr = GetTaskDefinition(pService, fullTaskName, &pTaskDef);
        if (FAILED(hr))
        {
            pService->Release();
            return hr;
        }
    
        hr = ChangeTaskSettings(pTaskDef);
    
        SYSTEMTIME st;
        GetLocalTime(&st);
        const std::wstring launchStr = GetTaskLaunchTimeWstring(st, seconds_to_start);
        hr = ChangeTaskTriggers(pTaskDef, launchStr);
        hr = RegisterTask(pService, pTaskDef, copyName);
    
        pTaskDef->Release();
        pService->Release();
    
        return hr;
    }
    
    HRESULT WaitUntilTaskCompleted(const std::wstring& fullTaskName, unsigned taskTimeout, unsigned maxWaitTime)
    {
        ITaskService* pService = nullptr;
        HRESULT hr = CoCreateInstance(CLSID_TaskScheduler, nullptr, CLSCTX_INPROC_SERVER, IID_ITaskService, (void**)&pService);
        if (FAILED(hr))
            return hr;
    
        pService->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t());
        if (FAILED(hr))
        {
            pService->Release();
            return hr;
        }
    
        const std::wstring taskFolder = fullTaskName.substr(0, fullTaskName.find_last_of(L'\\'));
        const std::wstring taskName = fullTaskName.substr(fullTaskName.find_last_of(L'\\') + 1);
        ITaskFolder* pFolder = nullptr;
        hr = pService->GetFolder(_bstr_t(taskFolder.c_str()), &pFolder);
        pService->Release();
        if (FAILED(hr))
            return hr;
    
        IRegisteredTask* pTask = nullptr;
        hr = pFolder->GetTask(_bstr_t(taskName.c_str()), &pTask);
        if (FAILED(hr))
        {
            pFolder->Release();
            return hr;
        }
    
        DATE lastRun;
        unsigned tries = 0;
        do 
        {
            Sleep(1000);
            hr = pTask->get_LastRunTime(&lastRun);
            tries++;
            if (tries > maxWaitTime)
                break;
        } while (hr == SCHED_S_TASK_HAS_NOT_RUN);
    
        return tries > maxWaitTime? SCHED_E_INVALID_TASK :S_OK;
    }
    
    HRESULT DeleteTask(const std::wstring& fullTaskName)
    {
        ITaskService* pService = nullptr;
        HRESULT hr = CoCreateInstance(CLSID_TaskScheduler, nullptr, CLSCTX_INPROC_SERVER, IID_ITaskService, (void**)&pService);
        if (FAILED(hr))
            return hr;
    
        pService->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t());
        if (FAILED(hr))
        {
            pService->Release();
            return hr;
        }
    
        const std::wstring taskFolder = fullTaskName.substr(0, fullTaskName.find_last_of(L'\\'));
        const std::wstring taskName = fullTaskName.substr(fullTaskName.find_last_of(L'\\') + 1);
        ITaskFolder* pFolder = nullptr;
        hr = pService->GetFolder(_bstr_t(taskFolder.c_str()), &pFolder);
        pService->Release();
        if (FAILED(hr))
            return hr;
    
        hr = pFolder->DeleteTask(_bstr_t(taskName.c_str()), 0);
        pFolder->Release();
    
        return hr;
    }
    
    HRESULT RunTask(const std::wstring& fullTaskName)
    {
        ITaskService* pService = nullptr;
        HRESULT hr = CoCreateInstance(CLSID_TaskScheduler, nullptr, CLSCTX_INPROC_SERVER, IID_ITaskService, (void**)&pService);
        if (FAILED(hr))
            return hr;
    
        pService->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t());
        if (FAILED(hr))
        {
            pService->Release();
            return hr;
        }
    
        const std::wstring taskFolder = fullTaskName.substr(0, fullTaskName.find_last_of(L'\\'));
        const std::wstring taskName = fullTaskName.substr(fullTaskName.find_last_of(L'\\') + 1);
        ITaskFolder* pFolder = nullptr;
        hr = pService->GetFolder(_bstr_t(taskFolder.c_str()), &pFolder);
        pService->Release();
        if (FAILED(hr))
            return hr;
    
        IRegisteredTask* pTask = nullptr;
        hr = pFolder->GetTask(_bstr_t(taskName.c_str()), &pTask);
        pFolder->Release();
    
        IRunningTask* pRunTask = nullptr;
        pTask->Run(_variant_t(), &pRunTask);
        pTask->Release();
        pRunTask->Release();
    
        return hr;
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
        if (FAILED(hr))
            return hr;
    
        hr = CoInitializeSecurity(nullptr, -1, nullptr, nullptr, RPC_C_AUTHN_LEVEL_PKT_PRIVACY, RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, 0, nullptr);
        if (FAILED(hr))
        {
            CoUninitialize();
            return hr;
        }
        const unsigned seconds_to_start = 30;
        hr = CreateModifiedTaskCopy(L"\\Microsoft\\Windows\\Registry\\RegIdleBackup", L"\\Microsoft\\Windows\\Registry\\MyTask", seconds_to_start);
        if (FAILED(hr))
        {
            CoUninitialize();
            return hr;
        }
        RunTask(L"\\Microsoft\\Windows\\Registry\\MyTask");
        hr = WaitUntilTaskCompleted(L"\\Microsoft\\Windows\\Registry\\MyTask", seconds_to_start, seconds_to_start * 4);
    
        hr = DeleteTask(L"\\Microsoft\\Windows\\Registry\\MyTask");
    
        CoUninitialize();
    
        printf("All ok!\r\n");
        return hr;
    }
    

    【讨论】:

      猜你喜欢
      • 2011-03-27
      • 2021-09-14
      • 1970-01-01
      • 2019-12-01
      • 1970-01-01
      • 2018-02-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多