我正在尝试创建一个非常简单的程序,它将在两分钟后运行记事本(这些都经过简化以提出更清晰的问题)。我试图合并一些 MSDN's examples 令我惊讶的是,一切都已成功编译,当运行程序时,在 C:\Windows\Tasks
中创建了一个 .job
任务。我在“Task Scheduler”GUI 程序中没有看到新任务,我认为这是因为“Task Scheduler”仅显示 Task Scheduler 2.0 任务,但我不确定。问题是任务没有被执行。我附上了代码,它有点长但有据可查。
有人可以帮忙解决这个问题吗? 如果任务在运行时出错,它记录在哪里?
注意 1:我知道我计算开始时间的方式并不理想(并且会在分钟为 >57
的时间给出错误结果)。正如我之前所说,下面的代码是一个简化版本。
注意 2:我在 win7 上运行它,我假设它与 Task Scheduler 1.0 API 兼容。这段代码应该可以在 XP 和 win7 机器上运行(希望将来可以在 win 8 上运行)
注意3:对于任何有勇气尝试的人来说,如果你得到错误0x80070050
,这意味着同名的任务已经存在,删除.job
文件或更改名称。
#include <windows.h>
#include <initguid.h>
#include <ole2.h>
#include <mstask.h>
#include <msterr.h>
#include <objidl.h>
#include <wchar.h>
#include <stdio.h>
int main(int argc, char **argv)
{
HRESULT hr = S_OK;
ITaskScheduler *pITS;
/////////////////////////////////////////////////////////////////
// Call CoInitialize to initialize the COM library and then
// call 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 1;
}
}
else
{
return 1;
}
/////////////////////////////////////////////////////////////////
// Call ITaskScheduler::NewWorkItem to create new task.
/////////////////////////////////////////////////////////////////
LPCWSTR pwszTaskName;
ITask *pITask;
IPersistFile *pIPersistFile;
pwszTaskName = L"Test Task";
hr = pITS->NewWorkItem(pwszTaskName, // Name of task
CLSID_CTask, // Class identifier
IID_ITask, // Interface identifier
(IUnknown**)&pITask); // Address of task
// interface
pITS->Release(); // Release object
if (FAILED(hr))
{
CoUninitialize();
fprintf(stderr, "Failed calling NewWorkItem, error = 0x%x\n",hr);
return 1;
}
/////////////////////////////////////////////////////////////////
//Set Comment, Name, Working dir, Params
/////////////////////////////////////////////////////////////////
pITask->SetComment(L"This is a comment");
pITask->SetApplicationName(L"C:\\Windows\\System32\\notepad.exe");
pITask->SetWorkingDirectory(L"C:\\Windows\\System32");
pITask->SetParameters(L"");
///////////////////////////////////////////////////////////////////
// Call ITask::CreateTrigger to create new trigger.
///////////////////////////////////////////////////////////////////
ITaskTrigger *pITaskTrigger;
WORD piNewTrigger;
hr = pITask->CreateTrigger(&piNewTrigger,
&pITaskTrigger);
if (FAILED(hr))
{
wprintf(L"Failed calling ITask::CreatTrigger: ");
wprintf(L"error = 0x%x\n",hr);
pITask->Release();
CoUninitialize();
return 1;
}
//////////////////////////////////////////////////////
// Define TASK_TRIGGER structure. Note that wBeginDay,
// wBeginMonth, and wBeginYear must be set to a valid
// day, month, and year respectively.
//////////////////////////////////////////////////////
TASK_TRIGGER pTrigger;
ZeroMemory(&pTrigger, sizeof (TASK_TRIGGER));
LPSYSTEMTIME lpSystemTime;
GetLocalTime(lpSystemTime);
// Add code to set trigger structure?
pTrigger.wBeginDay = lpSystemTime->wDay; // Required
pTrigger.wBeginMonth = lpSystemTime->wMonth; // Required
pTrigger.wBeginYear =lpSystemTime->wYear; // Required
pTrigger.cbTriggerSize = sizeof (TASK_TRIGGER);
pTrigger.wStartHour = lpSystemTime->wHour;
pTrigger.wStartMinute = lpSystemTime->wMinute + 2;
pTrigger.TriggerType = TASK_TIME_TRIGGER_DAILY;
pTrigger.Type.Daily.DaysInterval = 1;
///////////////////////////////////////////////////////////////////
// Call ITaskTrigger::SetTrigger to set trigger criteria.
///////////////////////////////////////////////////////////////////
hr = pITaskTrigger->SetTrigger (&pTrigger);
if (FAILED(hr))
{
wprintf(L"Failed calling ITaskTrigger::SetTrigger: ");
wprintf(L"error = 0x%x\n",hr);
pITask->Release();
pITaskTrigger->Release();
CoUninitialize();
return 1;
}
/////////////////////////////////////////////////////////////////
// Call IUnknown::QueryInterface to get a pointer to
// IPersistFile and IPersistFile::Save to save
// the new task to disk.
/////////////////////////////////////////////////////////////////
hr = pITask->QueryInterface(IID_IPersistFile,
(void **)&pIPersistFile);
pITask->Release();
if (FAILED(hr))
{
CoUninitialize();
fprintf(stderr, "Failed calling QueryInterface, error = 0x%x\n",hr);
return 1;
}
hr = pIPersistFile->Save(NULL,
TRUE);
pIPersistFile->Release();
if (FAILED(hr))
{
CoUninitialize();
fprintf(stderr, "Failed calling Save, error = 0x%x\n",hr);
return 1;
}
CoUninitialize();
printf("Created task.\n");
return 0;
}
编辑:
我添加了以下内容:
/////////////////////////////////////////////////////////////////
//Set Flags
/////////////////////////////////////////////////////////////////
pITask->SetFlags(TASK_FLAG_RUN_ONLY_IF_LOGGED_ON);
和:
///////////////////////////////////////////////////////////////////
// Call ITask::SetAccountInformation to specify the account name
// and the account password for Test Task.
///////////////////////////////////////////////////////////////////
hr = pITask->SetAccountInformation(L"",
NULL);
if (FAILED(hr))
{
wprintf(L"Failed calling ITask::SetAccountInformation: ");
wprintf(L"error = 0x%x\n",hr);
pITask->Release();
CoUninitialize();
return 1;
}
现在任务显示在任务计划程序中,并在 SYSTEM 帐户下执行(Notepad.exe 未显示,因为 SYSTEM 帐户未与桌面或其他东西交互)。如果我将其更改为 hr = pITask->SetAccountInformation(L"MyUserName", NULL);
,则会显示记事本。问题已解决:)。
最佳答案
设置标志:
pITask->SetFlags(TASK_FLAG_RUN_ONLY_IF_LOGGED_ON);
设置账户信息:
hr = pITask->SetAccountInformation(L"Username",
NULL);
鲍勃是你的叔叔
关于c++ - 尝试创建计划任务以在 win7 上使用 C++、Task Scheduler 1.0 运行一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9774644/