C++ Создание задачи автозапуска от имени текущего пользователя
Данный пример создаёт задачу в Планировщике заданий Windows, которая запускает приложение при входе текущего пользователя в систему. Однако RegisterTaskDefinition
возвращает E_ACCESS_DENIED
. При запуске от имени администратора задача создаётся успешно. Обязательно ли нужны права администратора для регистрации задач с триггером TASK_TRIGGER_LOGON
или я что то упускаю? По логике вещей, если задача создаётся от имени текущего пользователя и запускается только при его входе в систему, то зачем тут права администратора?
#define CHECK_HR_EXIT(hr) if (FAILED(hr)) goto Exit;
BOOLEAN CreateStartupTask(LPCTSTR lpszAppPath, LPCTSTR lpszTaskName)
{
BOOLEAN bResult = FALSE;
ITaskService* pTaskService = NULL;
ITaskFolder* pRootTaskFolder = NULL;
ITaskDefinition* pTaskDef = NULL;
ITaskSettings* pTaskSettings = NULL;
ITriggerCollection* pTriggers = NULL;
ITrigger* pTrigger = NULL;
IActionCollection* pActions = NULL;
IAction* pAction = NULL;
IExecAction* pExecAction = NULL;
IRegisteredTask* pRegisteredTask = NULL;
CHECK_HR(CoInitialize(NULL));
TCHAR szWorkingDir[MAX_PATH];
size_t inx;
CHECK_HR_EXIT(StringCchCopy(szWorkingDir, MAX_PATH, lpszAppPath));
inx = wcschr(szWorkingDir, '\\') - szWorkingDir;
if (inx >= 0) szWorkingDir[inx] = 0;
CHECK_HR_EXIT(CoCreateInstance(__uuidof(TaskScheduler),
NULL, CLSCTX_INPROC_SERVER,
__uuidof(ITaskService), (void**)&pTaskService));
// Establish a connection to the task scheduler on the local computer.
CHECK_HR_EXIT(pTaskService->Connect(CComVariant(),
CComVariant(),
CComVariant(),
CComVariant()));
// Create an empty task definition in the root task folder.
CHECK_HR_EXIT(pTaskService->GetFolder(CComBSTR(L"\\"), &pRootTaskFolder));
CHECK_HR_EXIT(pTaskService->NewTask(0, &pTaskDef));
// Set settings for task.
CHECK_HR_EXIT(pTaskDef->get_Settings(&pTaskSettings));
CHECK_HR_EXIT(pTaskSettings->put_DisallowStartIfOnBatteries(VARIANT_FALSE));
CHECK_HR_EXIT(pTaskSettings->put_ExecutionTimeLimit(CComBSTR("PT0S")));
CHECK_HR_EXIT(pTaskSettings->put_AllowDemandStart(VARIANT_FALSE));
CHECK_HR_EXIT(pTaskSettings->put_Hidden(VARIANT_TRUE));
// Create trigger object and configure it so that the task runs when user logs on.
CHECK_HR_EXIT(pTaskDef->get_Triggers(&pTriggers));
CHECK_HR_EXIT(pTriggers->Create(TASK_TRIGGER_LOGON, &pTrigger));
// Create execution action object and configure to run the specified app.
CHECK_HR_EXIT(pTaskDef->get_Actions(&pActions));
CHECK_HR_EXIT(pActions->Create(TASK_ACTION_EXEC, &pAction));
CHECK_HR_EXIT(pAction->QueryInterface(__uuidof(IExecAction), (void**)&pExecAction));
CHECK_HR_EXIT(pExecAction->put_Path(CComBSTR(lpszAppPath)));
CHECK_HR_EXIT(pExecAction->put_WorkingDirectory(CComBSTR(szWorkingDir)));
// Register task. Task will only run given an interactive
// logon session for the current user.
CHECK_HR_EXIT(pRootTaskFolder->RegisterTaskDefinition(CComBSTR(lpszTaskName),
pTaskDef, TASK_CREATE_OR_UPDATE,
CComVariant(),
CComVariant(),
TASK_LOGON_INTERACTIVE_TOKEN,
CComVariant(),
&pRegisteredTask));
bResult = TRUE;
Exit:
if (pTaskService) pTaskService->Release();
if (pRootTaskFolder) pRootTaskFolder->Release();
if (pTaskDef) pTaskDef->Release();
if (pTaskSettings) pTaskSettings->Release();
if (pTriggers) pTriggers->Release();
if (pTrigger) pTrigger->Release();
if (pActions) pActions->Release();
if (pAction) pAction->Release();
if (pExecAction) pExecAction->Release();
if (pRegisteredTask) pRegisteredTask->Release();
CoUninitialize();
return bResult;
}
Источник: Stack Overflow на русском