Search code examples
c++winapicomobject

Delete a scheduled task using com objects


I tried the following code for deleting a scheduled task:

bool deleteTask(std::wstring taskName)
    {
    if (FAILED(CoInitialize(nullptr))) {
        return false;
    }

    ITaskScheduler *pITS;
    if (FAILED(CoCreateInstance(CLSID_CTaskScheduler, nullptr, CLSCTX_INPROC_SERVER, IID_ITaskScheduler, (void **)&pITS))) {
        CoUninitialize();
        return false;
    }

    HRESULT hr = pITS->Delete(taskName.c_str());
    pITS->Release();
    CoUninitialize();

    if (FAILED(hr)) {
        if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) {
            wprintf(L"ERROR_FILE_NOT_FOUND");
        }
        return false;
    }
    return true;
}

When executing deleteTask(L"exampletask"); The method pITS->Delete returns ERROR_FILE_NOT_FOUND even though executing schtasks.exe /Query /TN exampletask returns an existing task.
I also tried this code with the privileges of admin / system / service, and none succeed at finding and deleting the task.

Is there some missing parameter, or maybe a method that should be called?
Thanks!


Solution

  • As @IInspectable suggested, the solution is to use Task Scheduler 2.0 Interfaces, e.g. ITaskService instead of ITaskScheduler, and ITaskFolder->DeleteTask instead of ITaskScheduler->Delete.

    bool deleteTask(std::wstring taskName)
    {
        if (FAILED(CoInitialize(nullptr))) {
            return false;
        }
    
        ITaskService *pITS;
        if (FAILED(CoCreateInstance(CLSID_TaskScheduler, nullptr, CLSCTX_INPROC_SERVER, IID_ITaskService, (void **)&pITS))) {
            CoUninitialize();
            return false;
        }
    
        if (FAILED(pITS->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t()))) {
            pITS->Release();
            CoUninitialize();
            return false;
        }
    
        ITaskFolder *pITF;
        if (FAILED(pITS->GetFolder(_bstr_t(L"\\"), &pITF))) {
            pITS->Release();
            CoUninitialize();
            return false;
        }
    
        pITS->Release();
    
        if (FAILED(pITF->DeleteTask(_bstr_t(taskName.c_str()), 0))) {
            pITF->Release();
            CoUninitialize();
            return false;
        }
    
        pITF->Release();
    
        CoUninitialize();
    
        return true;
    }