为什么我在启动任务时得到成功代码,但没有任何反应?
Why do I get a success code when I start a task, but it does nothing?
请帮我解决一个问题。我正在尝试复制系统 RegIdleBackup 任务并启动复制的任务。我使用 ITaskService api 成功复制了任务,并更改了其中的一些设置。毕竟我尝试 运行 这个任务,我得到了 return 代码 S_OK,但是任务计划程序中的任务信息没有改变 window 并且备份文件没有更新。我可以从任务调度器手动 运行 这个任务,我复制的任务运行良好。我的问题是启动方法,但我找不到它。谢谢。
这是我的代码
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;
}
今天早上我尝试 运行 任务替换启动触发器,同时修复了一些任务设置。一切都很好,毕竟我开始在 Win 7 上测试我的程序并且一切都很好,但是在 Win10 上我遇到了一些有趣的问题,任务创建了另一个上次启动时间(在 Win7 字段为空,在 Win 10 消息 - "Task never launched before") 我尝试使用 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;
}
请帮我解决一个问题。我正在尝试复制系统 RegIdleBackup 任务并启动复制的任务。我使用 ITaskService api 成功复制了任务,并更改了其中的一些设置。毕竟我尝试 运行 这个任务,我得到了 return 代码 S_OK,但是任务计划程序中的任务信息没有改变 window 并且备份文件没有更新。我可以从任务调度器手动 运行 这个任务,我复制的任务运行良好。我的问题是启动方法,但我找不到它。谢谢。
这是我的代码
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;
}
今天早上我尝试 运行 任务替换启动触发器,同时修复了一些任务设置。一切都很好,毕竟我开始在 Win 7 上测试我的程序并且一切都很好,但是在 Win10 上我遇到了一些有趣的问题,任务创建了另一个上次启动时间(在 Win7 字段为空,在 Win 10 消息 - "Task never launched before") 我尝试使用 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;
}