Windows计划任务介绍
1、含义:
简单点就是定时执行任务。
在许多场景下,我们定时执行一些任务。比如:定时拉取、备份文件,更新代码等等操作。
Win+R
打开运行框,输入:control schedtasks
,就会打开计划任务的UI。
2、代码介绍
虽然windows提供了schtasks
程序可以创建计划任务,但是自定义程度还不是很高。
#ifndef win7taskscheduler_h
#define win7taskscheduler_h#include <vector>
#include <utility>
#include <string>#include <assert.h>#include <comdef.h>
#include <taskschd.h>#pragma comment(lib, "taskschd.lib")using std::pair;
using std::vector;
using std::wstring;
using std::to_wstring;namespace XIBAO {class Win7TaskScheduler{public:enum TaskMode:int {Normal = 1, // 普通模式,用户只有登录进去才会触发LOGON_PASSWD, // 输入用户名和密码的模式,这种模式不用登录也能触发SYSTEM // system权限登录};public:Win7TaskScheduler() {}~Win7TaskScheduler() {}private:
class ITaskServiceHelper
{
public:ITaskServiceHelper() { p = NULL; }~ITaskServiceHelper() { if ( p ) p->Release(); }ITaskService * p;
};class ITaskFolderHelper
{
public:ITaskFolderHelper() { p = NULL; }~ITaskFolderHelper() { if ( p ) p->Release(); }ITaskFolder * p;
};class ITaskDefinitionHelper
{
public:ITaskDefinitionHelper() { p = NULL; }~ITaskDefinitionHelper() { if ( p ) p->Release(); }ITaskDefinition * p;
};class IRegistrationInfoHelper
{
public:IRegistrationInfoHelper() { p = NULL; }~IRegistrationInfoHelper() { if ( p ) p->Release(); }IRegistrationInfo * p;
};class IPrincipalHelper
{
public:IPrincipalHelper() { p = NULL; }~IPrincipalHelper() { if ( p ) p->Release(); }IPrincipal * p;
};class ITaskSettingsHelper
{
public:ITaskSettingsHelper() { p = NULL; }~ITaskSettingsHelper() { if ( p ) p->Release(); }ITaskSettings * p;
};class ITriggerCollectionHelper
{
public:ITriggerCollectionHelper() { p = NULL; }~ITriggerCollectionHelper() { if ( p ) p->Release(); }ITriggerCollection * p;
};class ITriggerHelper
{
public:ITriggerHelper() { p = NULL; }~ITriggerHelper() { if ( p ) p->Release(); }ITrigger * p;
};class IDailyTriggerHelper
{
public:IDailyTriggerHelper() { p = NULL; }~IDailyTriggerHelper() { if ( p ) p->Release(); }IDailyTrigger * p;
};class IRegistrationTriggerHelper
{
public:IRegistrationTriggerHelper(){ p = NULL; }~IRegistrationTriggerHelper(){ if ( p ) p->Release(); }IRegistrationTrigger * p;
};class IActionCollectionHelper
{
public:IActionCollectionHelper() { p = NULL; }~IActionCollectionHelper() { if ( p ) p->Release(); }IActionCollection * p;
};class IActionHelper
{
public:IActionHelper() { p = NULL; }~IActionHelper() { if ( p ) p->Release(); }IAction * p;
};class IExecActionHelper
{
public:IExecActionHelper() { p = NULL; }~IExecActionHelper() { if ( p ) p->Release(); }IExecAction * p;
};class IRegisteredTaskHelper
{
public:IRegisteredTaskHelper() { p = NULL; }~IRegisteredTaskHelper() { if ( p ) p->Release(); }IRegisteredTask * p;
};#define DO( action ) \if( FAILED( action ) ) \
{ \assert( FALSE ); \return FALSE; \
}public:
static HRESULT Create2MoreWin7(const wstring &appPath,const wstring &taskName,const wstring &taskDescription,const wstring &appWorkDir,const wstring ¶meter,const vector<pair<int, int>> &vecTime,const wstring &userName,const wstring &passwd,int mode)
{CoInitialize(NULL);HRESULT hr = 0;ITaskServiceHelper iService;hr = CoCreateInstance( CLSID_TaskScheduler,NULL,CLSCTX_INPROC_SERVER,IID_ITaskService,(void**)&iService.p);// Connect to the task service.DO( iService.p->Connect( _variant_t(), _variant_t(), _variant_t(), _variant_t()) )// Get the pointer to the root task folder. This folder will hold the// new task that is registered.ITaskFolderHelper iRootFolder;DO( iService.p->GetFolder( _bstr_t( L"\\") , &iRootFolder.p ) )ITaskFolderHelper iNewFolder;IRegisteredTaskHelper iRegisteredTask;ITaskDefinitionHelper iTask;BOOL bTmp = FALSE;DO( iService.p->NewTask( 0, &iTask.p ) )// DO( iService->NewTask( 0, &iTask.p ) )IRegistrationInfoHelper info;DO(iTask.p->get_RegistrationInfo(&(info.p)))if (nullptr != info.p) { (info.p)->put_Description(_bstr_t(taskDescription.c_str())); }IActionCollectionHelper iActionCollection;DO( iTask.p->get_Actions( &iActionCollection.p ) )IActionHelper iAction;DO( iActionCollection.p->Create( TASK_ACTION_EXEC, &iAction.p ) )IExecActionHelper iExecAction;// QI for the executable task pointer.DO( iAction.p->QueryInterface( IID_IExecAction, (void**) &iExecAction.p ) )// Set the path of the executable to notepad.exe.DO( iExecAction.p->put_Path( _bstr_t( appPath.c_str() ) ) )if(! parameter.empty()){DO( iExecAction.p->put_Arguments(_bstr_t(parameter.c_str())))}if(! appWorkDir.empty()){DO( iExecAction.p->put_WorkingDirectory(_bstr_t(appWorkDir.c_str())))}ITriggerCollectionHelper iTriggerCollection;DO( iTask.p->get_Triggers( &iTriggerCollection.p ) )ITaskSettingsHelper iTaskSettings; DO( iTask.p->get_Settings(&iTaskSettings.p) )iTaskSettings.p->put_DisallowStartIfOnBatteries(VARIANT_BOOL(FALSE));iTaskSettings.p->put_StopIfGoingOnBatteries(VARIANT_BOOL(FALSE));{for (int i = 0; i < vecTime.size(); ++i) {ITriggerHelper iTrigger;DO( iTriggerCollection.p->Create( TASK_TRIGGER_DAILY,&iTrigger.p ) )IDailyTrigger *dailyTriger = nullptr;iTrigger.p->QueryInterface(IID_IDailyTrigger, (void **)&dailyTriger); if (nullptr != dailyTriger) {wstring triggerid = taskName + L"_" + to_wstring(i);dailyTriger->put_Id(_bstr_t(triggerid.c_str()));dailyTriger->put_DaysInterval(1);wstring strstarttime = L"2019-01-01T" + to_wstring(vecTime[i].first) + L":" + to_wstring(vecTime[i].second) + L":00";dailyTriger->put_StartBoundary(_bstr_t(strstarttime.c_str()));dailyTriger->put_EndBoundary(_bstr_t(L"2099-12-31T00:00:00"));dailyTriger->put_Enabled(true);}}}IPrincipalHelper iPrincipal;DO( iTask.p->get_Principal( &iPrincipal.p ) )DO(iPrincipal.p->put_RunLevel(TASK_RUNLEVEL_LUA))if (mode == TaskMode::SYSTEM){hr = iRootFolder.p->RegisterTaskDefinition(_bstr_t(taskName.c_str()),iTask.p,TASK_CREATE_OR_UPDATE, _variant_t(L"SYSTEM"),_variant_t(), TASK_LOGON_SERVICE_ACCOUNT,_variant_t(L""),&iRegisteredTask.p);}else if (mode == TaskMode::LOGON_PASSWD){hr = iRootFolder.p->RegisterTaskDefinition(_bstr_t(taskName.c_str()),iTask.p,TASK_CREATE_OR_UPDATE, _variant_t(userName.c_str()),_variant_t(passwd.c_str()),TASK_LOGON_PASSWORD,_variant_t(L""),&iRegisteredTask.p);}else{hr = iRootFolder.p->RegisterTaskDefinition(_bstr_t(taskName.c_str()),iTask.p,TASK_CREATE_OR_UPDATE, _variant_t(L""),_variant_t(L""),TASK_LOGON_INTERACTIVE_TOKEN,_variant_t(L""),&iRegisteredTask.p);}return hr;
}static bool Delete2MoreWin7(const wstring &taskName)
{ITaskServiceHelper iService;HRESULT hr = CoCreateInstance( CLSID_TaskScheduler,NULL,CLSCTX_INPROC_SERVER,IID_ITaskService,(void**)&iService.p );DO( iService.p->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t()))ITaskFolderHelper iRootFolder;DO( iService.p->GetFolder( _bstr_t( L"\\") , &iRootFolder.p ) )IRegisteredTaskHelper iRegisteredTask;ITaskDefinitionHelper iTask;hr = iRootFolder.p->GetTask(_bstr_t(taskName.c_str()),&iRegisteredTask.p);hr = iRootFolder.p->DeleteTask(_bstr_t(taskName.c_str()),0);return true;
}};};#endif // win7taskscheduler_hint main()
{result = Win7TaskScheduler::Create2MoreWin7(mAppPath,mTaskName,mTaskDescription,mAppWorkDir, mParameter, mVecTime,mUserName,mPassword,mode);return result;
}
这里的接口提供了删除、创建的接口。所以用起来还是非常容易上手。
3、注意事项
在执行计划任务的时候,如果你是system权限一定要注意权限的问题。很多软件在system下时获取的环境变量和正常用户获取的不一样,导致一些出乎意料的bug。