Task Scheduler
I have a problem using the task scheduler from an application in Vista(RC1). I'm able to get the task scheduler object but when I try to activate the specific task I get 0x80070005 (access violation) the code to where the application fails is included below.
Does anyone have any idea why this doesn't work in Vista? (Works just fine on 2000/XP)
Also note!
This application is complied ti a Control Panel applet (cpl-file)
Code extract:
HRESULT hr = ERROR_SUCCESS;
boolbReturn =false;
HRESULT phrStatus;
ITask *pITask;
LPCWSTR lpcwszTaskName;
// Initialize the COM library.
ITaskScheduler *pITS;
hr = CoInitialize(NULL);
if(SUCCEEDED(hr))
{
// Get the Task Scheduler object.
hr = CoCreateInstance(CLSID_CTaskScheduler,
NULL,
CLSCTX_INPROC_SERVER,
IID_ITaskScheduler,
(void**) &pITS);
if(FAILED(hr))
{
AfxMessageBox("Unable to get task scheduler.");
CoUninitialize();
returnbReturn;
}
}
else
{
AfxMessageBox("Unable to initialize the COM library");
returnbReturn;
}
// Get the Task object.
lpcwszTaskName = L"Hernis WatchDog";
hr = pITS->Activate(lpcwszTaskName,
IID_ITask,
(IUnknown**) &pITask);
// Release ITaskScheduler interface.
pITS->Release();
// Could not find task.
if(FAILED(hr))
{
// Some output for debugging purposes.
charszDebug[256];
if(0x80070002 == hr)
sprintf(szDebug, "File not found");
else if(0x80070005 == hr)
sprintf(szDebug, "Access denied.");
else if(E_INVALIDARG == hr)
sprintf(szDebug, "The pwszName parameter is not valid.");
else if(E_OUTOFMEMORY == hr)
sprintf(szDebug, "A memory allocation failed.");
else if(SCHED_E_UNKNOWN_OBJECT_VERSION == hr)
sprintf(szDebug, "The task object version is either unsupported or invalid.");
else
sprintf(szDebug, "Error = 0x%x", hr);
AfxMessageBox(szDebug);
CoUninitialize();
returnbReturn;
}
// Rest of code will not get executed since we cannot get an task object.
[3221 byte] By [
CarlAre] at [2007-12-25]
I am facing same problem in my task scheduling code in VISTA build 5744. ITaskScheduler->Activate returns
E_ACCESSDENIED in Vista. It works just fine in
XP/2000. I really understand that it is regarding the tightened security in Vista. I made some trials using CoInitializeSecurity().
But it doesn't made any changes.
Did you solved it? If so could you please post the way to solve it?
Which context is the task created? If the task is created with elevated admin privileges, you will need admin privileges to access it. If the task is created with non-elevated privileges, you should be able to access it. To examine who can access the task, go to C:\Windows\Tasks. Right click on the task file. Select Properties. Select Security tab.
If you schedule a task in a process that is run with elevated admin rights and you want to access it from a non-elevated process, you will need to change ACL of the job file that is corresponding to the tasks. Let me know if you need the code that set ACL for a file.
When we run the application from an admin user on Vista
everything works including the Activate() method. When we run
from a standard user the Activate() method fails. We don't do any
context switching before opening the Interface.
Thanks !!! The issue is solved by changing ACL of the job file after saving it.
As we discussed, tasks are saved in C:\Windows\Tasks folder. If the task is created as administrator user, standard users will not have permission to access it. If it is created in a standard user environment, other standard users will not have permission to access it.
ITaskScheduler->Activate(..) works fine if the task with given name doesn't exists.
If the task with given name exists and user doesn't have access permisions to the job, Activate(..) call returns E_ACCESSDENIED. So the user cannot reschedule or delete it.
By changing the ACL of the file, granted “full permission” for “everyone” on the job file when the job is created ( After IPersistFile->Save call). IPersistFile->GetCurFile(..) method returns the absolute path of the job file.
We are having similar problems, but not quite sure if they warranted a separate post, so I've included it below. The problem is that when we use the Task Scheduler 2.0 dispatch interfaces to enumerate the various tasks on the machine (of which there is just 1), it works fine. But when we use the Task Scheduler 1.0 COM interfaces, the pIEnum->Next() function does not return any, and the return code is a "no more items".
I would prefer to use the Task Scheduler 1.0 interfaces since that is already coded in our app, but can't get the pIEnum->Next() to return the items. Do I need to manually modify the ACL of the task before it will appear in the 1.0 interfaces? Seems like that couldn't be the solution since I am not getting any security related error mesages.
Any thoughts?
Thanks,
Mark
-- the following code works, but the pIEnum->Next() does not return any rows
HRESULT hr = ERROR_SUCCESS;
ITaskScheduler *pITS; /////////////////////////////////////////////////////////////////
// Call CoInitialize to initialize the COM library and
// then CoCreateInstance to get the Task Scheduler object.
/////////////////////////////////////////////////////////////////
hr = CoInitialize(NULL);
if (SUCCEEDED(hr))
{
hr = CoCreateInstance(CLSID_CTaskScheduler,
NULL,
CLSCTX_INPROC_SERVER,
IID_ITaskScheduler,
(void **) &pITS);
if (FAILED(hr))
{
CoUninitialize();
return hr;
}
}
else
{
return hr;
} /////////////////////////////////////////////////////////////////
// Call ITaskScheduler::Enum to get an enumeration object.
/////////////////////////////////////////////////////////////////
IEnumWorkItems *pIEnum;
hr = pITS->Enum(&pIEnum);
if (FAILED(hr))
{
pITS->Release();
CoUninitialize();
return hr;
}
/////////////////////////////////////////////////////////////////
// Call IEnumWorkItems::Next to retrieve tasks. Note that
// this example tries to retrieve five tasks for each call.
/////////////////////////////////////////////////////////////////
LPWSTR *lpwszNames;
DWORD dwFetchedTasks = 0;
while (SUCCEEDED(pIEnum->Next(1,&lpwszNames,&dwFetchedTasks)) //only fetch 1 at a time
&& (dwFetchedTasks != 0))
{
// No items are returned here, the GetLastError() reports "no more items"
}