diff --git a/README.md b/README.md index 54fba9a..3f50559 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,319 @@ -# AutoRun_Task_Test +# 创建计划任务实现开机自启动 -创建计划任务实现开机自启动 \ No newline at end of file +# 背景 + +想必实现程序开机自启动,是很常见的功能了。无论是恶意程序,还是正常的应用软件,都会提供这个功能,方便用户的使用。程序开机自启动,顾名思义,就是计算机开机后,不用人为地去运行程序,程序就可以自己运行起来。对于这个功能的,一直都是杀软重点监测的地方。因为,对于病毒来说,重要的不是如何被破坏,而是如何启动。 + +在过去写的大大小小的程序中,我也实现过程序自启动的功能。现在,我把这些自启动功能的实现方式进行下总结。常见的方式有:修改开机自启动注册表、开机自启动目录、创建开机自启计划任务、创建开机自启系统服务等方式。现在对这些技术一一进行分析,并形成文档分享给大家。本文介绍的是创建自启动任务计划实现开机自启动的方式,其它的实现方式可以搜索我写的相关系列的文档。 + +# 实现原理 + +我是使用Windows Shell编程实现创建任务计划,所以会涉及COM组件相关知识。 + +现在,为方便大家的理解,我把整个程序的逻辑概括为 3 各部分,分别是:初始化操作、创建任务计划以及删除任务计划。现在,我们一一对每一个部分进行解析。 + +## 初始化操作 + +初始化操作的目的就是获取 ITaskService 对象以及 ITaskFolder 对象,我们创建任务计划,主要是对这两个指针进行操作。具体流程是: + +- 首先初始化COM接口环境,因为我们接下来会使用到COM组件 + +- 然后,创建 ITaskService 对象,并连接到任务服务上 + +- 接着,从 ITaskService 对象中获取 ITaskFolder 对象 + +这样,初始化操作就完成了,接下来就是直接使用 ITaskService 对象以及 ITaskFolder 对象进行操作了。 + +## 创建任务计划 + +现在,解析下任务计划的具体创建过程: + +- 首先,从 ITaskService 对象中创建一个任务定义对象 ITaskDefinition,用来来创建任务 + +- 接着,就是开始对任务定义对象 ITaskDefinition进行设置: + + - 设置注册信息,包括设置作者的信息 + + - 设置主体信息,包括登陆类型、运行权限 + + - 设置设置信息,包括设置在使用电池运行时是否停止、在使用电池是是否允许运行、是否允许手动运行、是否设置多个实例 + + - 设置操作信息,包括启动程序,并设置运行程序的路径和参数 + + - 设置触发器信息,包括用户登录时触发 + +- 最后,使用 ITaskFolder 对象根据任务定义对象 ITaskDefinition的设置,注册任务计划 + +这样,任务计划创建的操作就完成了,只要满足设置的触发条件,那么就会启动指定程序。 + +## 删除任务计划 + + ITaskFolder 对象存储着已经注册成功的任务计划的信息,我们只需要将任务计划的名称传入其中,调用DeleteTask接口函数,就可以删除指定的任务计划了。 + +# 编码实现 + +## 创建任务计划的初始化 + +```c++ +CMyTaskSchedule::CMyTaskSchedule(void) +{ + m_lpITS = NULL; + m_lpRootFolder = NULL; + // 初始化COM + HRESULT hr = ::CoInitialize(NULL); + if(FAILED(hr)) + { + ShowError("CoInitialize", hr); + } + // 创建一个任务服务(Task Service)实例 + hr = ::CoCreateInstance(CLSID_TaskScheduler, + NULL, + CLSCTX_INPROC_SERVER, + IID_ITaskService, + (LPVOID *)(&m_lpITS)); + if(FAILED(hr)) + { + ShowError("CoCreateInstance", hr); + } + // 连接到任务服务(Task Service) + hr = m_lpITS->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t()); + if(FAILED(hr)) + { + ShowError("ITaskService::Connect", hr); + } + // 获取Root Task Folder的指针,这个指针指向的是新注册的任务 + hr = m_lpITS->GetFolder(_bstr_t("\\"), &m_lpRootFolder); + if(FAILED(hr)) + { + ShowError("ITaskService::GetFolder", hr); + } +} +``` + +## 创建任务计划 + +```c++ +BOOL CMyTaskSchedule::NewTask(char *lpszTaskName, char *lpszProgramPath, char *lpszParameters, char *lpszAuthor) +{ + if(NULL == m_lpRootFolder) + { + return FALSE; + } + // 如果存在相同的计划任务,则删除 + Delete(lpszTaskName); + // 创建任务定义对象来创建任务 + ITaskDefinition *pTaskDefinition = NULL; + HRESULT hr = m_lpITS->NewTask(0, &pTaskDefinition); + if(FAILED(hr)) + { + ShowError("ITaskService::NewTask", hr); + return FALSE; + } + + /* 设置注册信息 */ + IRegistrationInfo *pRegInfo = NULL; + CComVariant variantAuthor(NULL); + variantAuthor = lpszAuthor; + hr = pTaskDefinition->get_RegistrationInfo(&pRegInfo); + if(FAILED(hr)) + { + ShowError("pTaskDefinition::get_RegistrationInfo", hr); + return FALSE; + } + // 设置作者信息 + hr = pRegInfo->put_Author(variantAuthor.bstrVal); + pRegInfo->Release(); + + /* 设置登录类型和运行权限 */ + IPrincipal *pPrincipal = NULL; + hr = pTaskDefinition->get_Principal(&pPrincipal); + if(FAILED(hr)) + { + ShowError("pTaskDefinition::get_Principal", hr); + return FALSE; + } + // 设置登录类型 + hr = pPrincipal->put_LogonType(TASK_LOGON_INTERACTIVE_TOKEN); + // 设置运行权限 + // 最高权限 + hr = pPrincipal->put_RunLevel(TASK_RUNLEVEL_HIGHEST); + pPrincipal->Release(); + + /* 设置其他信息 */ + ITaskSettings *pSettting = NULL; + hr = pTaskDefinition->get_Settings(&pSettting); + if(FAILED(hr)) + { + ShowError("pTaskDefinition::get_Settings", hr); + return FALSE; + } + // 设置其他信息 + hr = pSettting->put_StopIfGoingOnBatteries(VARIANT_FALSE); + hr = pSettting->put_DisallowStartIfOnBatteries(VARIANT_FALSE); + hr = pSettting->put_AllowDemandStart(VARIANT_TRUE); + hr = pSettting->put_StartWhenAvailable(VARIANT_FALSE); + hr = pSettting->put_MultipleInstances(TASK_INSTANCES_PARALLEL); + pSettting->Release(); + + /* 创建执行动作 */ + IActionCollection *pActionCollect = NULL; + hr = pTaskDefinition->get_Actions(&pActionCollect); + if(FAILED(hr)) + { + ShowError("pTaskDefinition::get_Actions", hr); + return FALSE; + } + IAction *pAction = NULL; + // 创建执行操作 + hr = pActionCollect->Create(TASK_ACTION_EXEC, &pAction); + pActionCollect->Release(); + + /* 设置执行程序路径和参数 */ + CComVariant variantProgramPath(NULL); + CComVariant variantParameters(NULL); + IExecAction *pExecAction = NULL; + hr = pAction->QueryInterface(IID_IExecAction, (PVOID *)(&pExecAction)); + if(FAILED(hr)) + { + pAction->Release(); + ShowError("IAction::QueryInterface", hr); + return FALSE; + } + pAction->Release(); + // 设置程序路径和参数 + variantProgramPath = lpszProgramPath; + variantParameters = lpszParameters; + pExecAction->put_Path(variantProgramPath.bstrVal); + pExecAction->put_Arguments(variantParameters.bstrVal); + pExecAction->Release(); + + /* 创建触发器,实现用户登陆自启动 */ + ITriggerCollection *pTriggers = NULL; + hr = pTaskDefinition->get_Triggers(&pTriggers); + if (FAILED(hr)) + { + ShowError("pTaskDefinition::get_Triggers", hr); + return FALSE; + } + // 创建触发器 + ITrigger *pTrigger = NULL; + hr = pTriggers->Create(TASK_TRIGGER_LOGON, &pTrigger); + if (FAILED(hr)) + { + ShowError("ITriggerCollection::Create", hr); + return FALSE; + } + + /* 注册任务计划 */ + IRegisteredTask *pRegisteredTask = NULL; + CComVariant variantTaskName(NULL); + variantTaskName = lpszTaskName; + hr = m_lpRootFolder->RegisterTaskDefinition(variantTaskName.bstrVal, + pTaskDefinition, + TASK_CREATE_OR_UPDATE, + _variant_t(), + _variant_t(), + TASK_LOGON_INTERACTIVE_TOKEN, + _variant_t(""), + &pRegisteredTask); + if(FAILED(hr)) + { + pTaskDefinition->Release(); + ShowError("ITaskFolder::RegisterTaskDefinition", hr); + return FALSE; + } + pTaskDefinition->Release(); + pRegisteredTask->Release(); + + return TRUE; +} +``` + +## 删除任务计划 + +```c++ +BOOL CMyTaskSchedule::Delete(char *lpszTaskName) +{ + if(NULL == m_lpRootFolder) + { + return FALSE; + } + CComVariant variantTaskName(NULL); + variantTaskName = lpszTaskName; + HRESULT hr = m_lpRootFolder->DeleteTask(variantTaskName.bstrVal, 0); + if(FAILED(hr)) + { + return FALSE; + } + + return TRUE; +} +``` + +# 程序测试 + +在 main 函数中调用上述封装好的函数,进行测试。main 函数为: + +```c++ +int _tmain(int argc, _TCHAR* argv[]) +{ + CMyTaskSchedule task; + BOOL bRet = FALSE; + + // 创建 任务计划 + bRet = task.NewTask("520", "C:\\Users\\DemonGan\\Desktop\\520.exe", "", ""); + if (FALSE == bRet) + { + printf("Create Task Schedule Error!\n"); + } + + // 暂停 + printf("Create Task Schedule OK!\n"); + system("pause"); + + // 卸载 任务计划 + bRet = task.Delete("520"); + if (FALSE == bRet) + { + printf("Delete Task Schedule Error!\n"); + } + + printf("Delete Task Schedule OK!\n"); + system("pause"); + return 0; +} +``` + +测试结果: + +“以管理员身份运行程序”方式打开程序,提示任务计划创建成功。 + +![](http://www.write-bug.com/myres/static/uploads/2021/10/19/e542bb6eec0f93c6ec02b4f50973d741.writebug) + +打开任务计划列表进行查看,发现“520”任务计划成功创建。 + +![](http://www.write-bug.com/myres/static/uploads/2021/10/19/c7953c56b969f3394458c4d097bddfc9.writebug) + +![](http://www.write-bug.com/myres/static/uploads/2021/10/19/3566ef40f42abe9ab4365af312e51011.writebug) + +![](http://www.write-bug.com/myres/static/uploads/2021/10/19/9beb1edb6785e012fc6ef0d9888e06fe.writebug) + +然后,删除创建的任务计划,程序提示删除成功。 + +![](http://www.write-bug.com/myres/static/uploads/2021/10/19/5b95c68abce032a5e9452dc216b8ec0c.writebug) + +查看任务计划列表,发现“520”任务计划已经成功删除。 + +![](http://www.write-bug.com/myres/static/uploads/2021/10/19/e34a1e9c0c35d5ef284e8b235d1b3a7b.writebug) + +所以,测试成功。 + +# 总结 + +这个功能的实现涉及到COM组件的相关知识,所以初学者对此可能感到陌生,这是很正常的。其实,对于这方面的理解我也没有什么好的建议,只有多动手练几遍,加深程序逻辑和印象吧。 + +注意的地方就是,创建任务计划,要求程序必须要有管机员权限才行。所以,测试的时候,不要忘记以管理员身份运行程序。 + +# 参考 + +参考自《[Windows黑客编程技术详解](https://www.write-bug.com/article/1811.html "Windows黑客编程技术详解")》一书 \ No newline at end of file diff --git a/src/AutoRun_Task_Test.sln b/src/AutoRun_Task_Test.sln new file mode 100644 index 0000000..924d00f --- /dev/null +++ b/src/AutoRun_Task_Test.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.40629.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AutoRun_Task_Test", "AutoRun_Task_Test\AutoRun_Task_Test.vcxproj", "{72D26442-FF39-438F-A920-FFD8CBB9282A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {72D26442-FF39-438F-A920-FFD8CBB9282A}.Debug|Win32.ActiveCfg = Debug|Win32 + {72D26442-FF39-438F-A920-FFD8CBB9282A}.Debug|Win32.Build.0 = Debug|Win32 + {72D26442-FF39-438F-A920-FFD8CBB9282A}.Release|Win32.ActiveCfg = Release|Win32 + {72D26442-FF39-438F-A920-FFD8CBB9282A}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src/AutoRun_Task_Test.v12.suo b/src/AutoRun_Task_Test.v12.suo new file mode 100644 index 0000000..0e5a6d1 Binary files /dev/null and b/src/AutoRun_Task_Test.v12.suo differ diff --git a/src/AutoRun_Task_Test/AutoRun_Task_Test.cpp b/src/AutoRun_Task_Test/AutoRun_Task_Test.cpp new file mode 100644 index 0000000..af46835 --- /dev/null +++ b/src/AutoRun_Task_Test/AutoRun_Task_Test.cpp @@ -0,0 +1,35 @@ +// AutoRun_Task_Test.cpp : ̨Ӧóڵ㡣 +// + +#include "stdafx.h" +#include "MyTaskSchedule.h" + + +int _tmain(int argc, _TCHAR* argv[]) +{ + CMyTaskSchedule task; + BOOL bRet = FALSE; + + // ƻ + bRet = task.NewTask("520", "C:\\Users\\DemonGan\\Desktop\\520.exe", "", ""); + if (FALSE == bRet) + { + printf("Create Task Schedule Error!\n"); + } + + // ͣ + printf("Create Task Schedule OK!\n"); + system("pause"); + + // ж ƻ + bRet = task.Delete("520"); + if (FALSE == bRet) + { + printf("Delete Task Schedule Error!\n"); + } + + printf("Delete Task Schedule OK!\n"); + system("pause"); + return 0; +} + diff --git a/src/AutoRun_Task_Test/AutoRun_Task_Test.vcxproj b/src/AutoRun_Task_Test/AutoRun_Task_Test.vcxproj new file mode 100644 index 0000000..48431b4 --- /dev/null +++ b/src/AutoRun_Task_Test/AutoRun_Task_Test.vcxproj @@ -0,0 +1,99 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {72D26442-FF39-438F-A920-FFD8CBB9282A} + Win32Proj + AutoRun_Task_Test + + + + Application + true + v120_xp + MultiByte + + + Application + false + v120_xp + true + MultiByte + + + + + + + + + + + + + true + + + false + + + + Use + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDebug + + + Console + true + + + + + Level3 + Use + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + true + MultiThreaded + + + Console + true + true + true + + + + + + + + + + + + + + Create + Create + + + + + + + \ No newline at end of file diff --git a/src/AutoRun_Task_Test/AutoRun_Task_Test.vcxproj.filters b/src/AutoRun_Task_Test/AutoRun_Task_Test.vcxproj.filters new file mode 100644 index 0000000..8d70140 --- /dev/null +++ b/src/AutoRun_Task_Test/AutoRun_Task_Test.vcxproj.filters @@ -0,0 +1,42 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + + + + 头文件 + + + 头文件 + + + 头文件 + + + + + 源文件 + + + 源文件 + + + 源文件 + + + \ No newline at end of file diff --git a/src/AutoRun_Task_Test/MyTaskSchedule.cpp b/src/AutoRun_Task_Test/MyTaskSchedule.cpp new file mode 100644 index 0000000..eab5d6d --- /dev/null +++ b/src/AutoRun_Task_Test/MyTaskSchedule.cpp @@ -0,0 +1,379 @@ +#include "stdafx.h" +#include "MyTaskSchedule.h" + + +void ShowError(char *lpszText, DWORD dwErrCode) +{ + char szErr[MAX_PATH] = {0}; + ::wsprintf(szErr, "%s Error!\nError Code Is:0x%08x\n", lpszText, dwErrCode); + ::MessageBox(NULL, szErr, "ERROR", MB_OK | MB_ICONERROR); +} + + +CMyTaskSchedule::CMyTaskSchedule(void) +{ + m_lpITS = NULL; + m_lpRootFolder = NULL; + // ʼCOM + HRESULT hr = ::CoInitialize(NULL); + if(FAILED(hr)) + { + ShowError("CoInitialize", hr); + } + // һTask Serviceʵ + hr = ::CoCreateInstance(CLSID_TaskScheduler, + NULL, + CLSCTX_INPROC_SERVER, + IID_ITaskService, + (LPVOID *)(&m_lpITS)); + if(FAILED(hr)) + { + ShowError("CoCreateInstance", hr); + } + // ӵTask Service + hr = m_lpITS->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t()); + if(FAILED(hr)) + { + ShowError("ITaskService::Connect", hr); + } + // ȡRoot Task Folderָ룬ָָע + hr = m_lpITS->GetFolder(_bstr_t("\\"), &m_lpRootFolder); + if(FAILED(hr)) + { + ShowError("ITaskService::GetFolder", hr); + } +} + + +CMyTaskSchedule::~CMyTaskSchedule(void) +{ + if(m_lpITS) + { + m_lpITS->Release(); + } + if(m_lpRootFolder) + { + m_lpRootFolder->Release(); + } + // жCOM + ::CoUninitialize(); +} + + +BOOL CMyTaskSchedule::Delete(char *lpszTaskName) +{ + if(NULL == m_lpRootFolder) + { + return FALSE; + } + CComVariant variantTaskName(NULL); + variantTaskName = lpszTaskName; + HRESULT hr = m_lpRootFolder->DeleteTask(variantTaskName.bstrVal, 0); + if(FAILED(hr)) + { + return FALSE; + } + + return TRUE; +} + + +BOOL CMyTaskSchedule::DeleteFolder(char *lpszFolderName) +{ + if(NULL == m_lpRootFolder) + { + return FALSE; + } + CComVariant variantFolderName(NULL); + variantFolderName = lpszFolderName; + HRESULT hr = m_lpRootFolder->DeleteFolder(variantFolderName.bstrVal, 0); + if(FAILED(hr)) + { + return FALSE; + } + + return TRUE; +} + + +BOOL CMyTaskSchedule::NewTask(char *lpszTaskName, char *lpszProgramPath, char *lpszParameters, char *lpszAuthor) +{ + if(NULL == m_lpRootFolder) + { + return FALSE; + } + // ͬļƻɾ + Delete(lpszTaskName); + // + ITaskDefinition *pTaskDefinition = NULL; + HRESULT hr = m_lpITS->NewTask(0, &pTaskDefinition); + if(FAILED(hr)) + { + ShowError("ITaskService::NewTask", hr); + return FALSE; + } + + /* עϢ */ + IRegistrationInfo *pRegInfo = NULL; + CComVariant variantAuthor(NULL); + variantAuthor = lpszAuthor; + hr = pTaskDefinition->get_RegistrationInfo(&pRegInfo); + if(FAILED(hr)) + { + ShowError("pTaskDefinition::get_RegistrationInfo", hr); + return FALSE; + } + // Ϣ + hr = pRegInfo->put_Author(variantAuthor.bstrVal); + pRegInfo->Release(); + + /* õ¼ͺȨ */ + IPrincipal *pPrincipal = NULL; + hr = pTaskDefinition->get_Principal(&pPrincipal); + if(FAILED(hr)) + { + ShowError("pTaskDefinition::get_Principal", hr); + return FALSE; + } + // õ¼ + hr = pPrincipal->put_LogonType(TASK_LOGON_INTERACTIVE_TOKEN); + // Ȩ + // Ȩ + hr = pPrincipal->put_RunLevel(TASK_RUNLEVEL_HIGHEST); + pPrincipal->Release(); + + /* Ϣ */ + ITaskSettings *pSettting = NULL; + hr = pTaskDefinition->get_Settings(&pSettting); + if(FAILED(hr)) + { + ShowError("pTaskDefinition::get_Settings", hr); + return FALSE; + } + // Ϣ + hr = pSettting->put_StopIfGoingOnBatteries(VARIANT_FALSE); + hr = pSettting->put_DisallowStartIfOnBatteries(VARIANT_FALSE); + hr = pSettting->put_AllowDemandStart(VARIANT_TRUE); + hr = pSettting->put_StartWhenAvailable(VARIANT_FALSE); + hr = pSettting->put_MultipleInstances(TASK_INSTANCES_PARALLEL); + pSettting->Release(); + + /* ִж */ + IActionCollection *pActionCollect = NULL; + hr = pTaskDefinition->get_Actions(&pActionCollect); + if(FAILED(hr)) + { + ShowError("pTaskDefinition::get_Actions", hr); + return FALSE; + } + IAction *pAction = NULL; + // ִв + hr = pActionCollect->Create(TASK_ACTION_EXEC, &pAction); + pActionCollect->Release(); + + /* ִг·Ͳ */ + CComVariant variantProgramPath(NULL); + CComVariant variantParameters(NULL); + IExecAction *pExecAction = NULL; + hr = pAction->QueryInterface(IID_IExecAction, (PVOID *)(&pExecAction)); + if(FAILED(hr)) + { + pAction->Release(); + ShowError("IAction::QueryInterface", hr); + return FALSE; + } + pAction->Release(); + // ó·Ͳ + variantProgramPath = lpszProgramPath; + variantParameters = lpszParameters; + pExecAction->put_Path(variantProgramPath.bstrVal); + pExecAction->put_Arguments(variantParameters.bstrVal); + pExecAction->Release(); + + /* ʵû½ */ + ITriggerCollection *pTriggers = NULL; + hr = pTaskDefinition->get_Triggers(&pTriggers); + if (FAILED(hr)) + { + ShowError("pTaskDefinition::get_Triggers", hr); + return FALSE; + } + // + ITrigger *pTrigger = NULL; + hr = pTriggers->Create(TASK_TRIGGER_LOGON, &pTrigger); + if (FAILED(hr)) + { + ShowError("ITriggerCollection::Create", hr); + return FALSE; + } + + /* עƻ */ + IRegisteredTask *pRegisteredTask = NULL; + CComVariant variantTaskName(NULL); + variantTaskName = lpszTaskName; + hr = m_lpRootFolder->RegisterTaskDefinition(variantTaskName.bstrVal, + pTaskDefinition, + TASK_CREATE_OR_UPDATE, + _variant_t(), + _variant_t(), + TASK_LOGON_INTERACTIVE_TOKEN, + _variant_t(""), + &pRegisteredTask); + if(FAILED(hr)) + { + pTaskDefinition->Release(); + ShowError("ITaskFolder::RegisterTaskDefinition", hr); + return FALSE; + } + pTaskDefinition->Release(); + pRegisteredTask->Release(); + + return TRUE; +} + + +BOOL CMyTaskSchedule::IsExist(char *lpszTaskName) +{ + if(NULL == m_lpRootFolder) + { + return FALSE; + } + HRESULT hr = S_OK; + CComVariant variantTaskName(NULL); + CComVariant variantEnable(NULL); + variantTaskName = lpszTaskName; // ƻ + IRegisteredTask *pRegisteredTask = NULL; + // ȡƻ + hr = m_lpRootFolder->GetTask(variantTaskName.bstrVal, &pRegisteredTask); + if(FAILED(hr) || (NULL == pRegisteredTask)) + { + return FALSE; + } + pRegisteredTask->Release(); + + return TRUE; +} + + +BOOL CMyTaskSchedule::IsTaskValid(char *lpszTaskName) +{ + if(NULL == m_lpRootFolder) + { + return FALSE; + } + HRESULT hr = S_OK; + CComVariant variantTaskName(NULL); + CComVariant variantEnable(NULL); + variantTaskName = lpszTaskName; // ƻ + IRegisteredTask *pRegisteredTask = NULL; + // ȡƻ + hr = m_lpRootFolder->GetTask(variantTaskName.bstrVal, &pRegisteredTask); + if(FAILED(hr) || (NULL == pRegisteredTask)) + { + return FALSE; + } + // ȡ״̬ + TASK_STATE taskState; + hr = pRegisteredTask->get_State(&taskState); + if(FAILED(hr)) + { + pRegisteredTask->Release(); + return FALSE; + } + pRegisteredTask->Release(); + // Ч + if(TASK_STATE_DISABLED == taskState) + { + return FALSE; + } + + return TRUE; +} + + +BOOL CMyTaskSchedule::Run(char *lpszTaskName, char *lpszParam) +{ + if(NULL == m_lpRootFolder) + { + return FALSE; + } + HRESULT hr = S_OK; + CComVariant variantTaskName(NULL); + CComVariant variantParameters(NULL); + variantTaskName = lpszTaskName; + variantParameters = lpszParam; + + // ȡƻ + IRegisteredTask *pRegisteredTask = NULL; + hr = m_lpRootFolder->GetTask(variantTaskName.bstrVal, &pRegisteredTask); + if(FAILED(hr) || (NULL == pRegisteredTask)) + { + return FALSE; + } + // + hr = pRegisteredTask->Run(variantParameters, NULL); + if(FAILED(hr)) + { + pRegisteredTask->Release(); + return FALSE; + } + pRegisteredTask->Release(); + + return TRUE; +} + + +BOOL CMyTaskSchedule::IsEnable(char *lpszTaskName) +{ + if(NULL == m_lpRootFolder) + { + return FALSE; + } + HRESULT hr = S_OK; + CComVariant variantTaskName(NULL); + CComVariant variantEnable(NULL); + variantTaskName = lpszTaskName; // ƻ + IRegisteredTask *pRegisteredTask = NULL; + // ȡƻ + hr = m_lpRootFolder->GetTask(variantTaskName.bstrVal, &pRegisteredTask); + if(FAILED(hr) || (NULL == pRegisteredTask)) + { + return FALSE; + } + // ȡǷѾ + pRegisteredTask->get_Enabled(&variantEnable.boolVal); + pRegisteredTask->Release(); + if(ATL_VARIANT_FALSE == variantEnable.boolVal) + { + return FALSE; + } + + return TRUE; +} + + +BOOL CMyTaskSchedule::SetEnable(char *lpszTaskName, BOOL bEnable) +{ + if(NULL == m_lpRootFolder) + { + return FALSE; + } + HRESULT hr = S_OK; + CComVariant variantTaskName(NULL); + CComVariant variantEnable(NULL); + variantTaskName = lpszTaskName; // ƻ + variantEnable = bEnable; // Ƿ + IRegisteredTask *pRegisteredTask = NULL; + // ȡƻ + hr = m_lpRootFolder->GetTask(variantTaskName.bstrVal, &pRegisteredTask); + if(FAILED(hr) || (NULL == pRegisteredTask)) + { + return FALSE; + } + // Ƿ + pRegisteredTask->put_Enabled(variantEnable.boolVal); + pRegisteredTask->Release(); + + return TRUE; +} + diff --git a/src/AutoRun_Task_Test/MyTaskSchedule.h b/src/AutoRun_Task_Test/MyTaskSchedule.h new file mode 100644 index 0000000..a95b239 --- /dev/null +++ b/src/AutoRun_Task_Test/MyTaskSchedule.h @@ -0,0 +1,50 @@ +#ifndef _MY_TASK_SCHEDULT_H_ +#define _MY_TASK_SCHEDULT_H_ + + +#include +#include +#include +#pragma comment(lib, "taskschd.lib") + + +class CMyTaskSchedule +{ +private: + + ITaskService *m_lpITS; + ITaskFolder *m_lpRootFolder; + +public: + + CMyTaskSchedule(void); + ~CMyTaskSchedule(void); + +public: + + // ɾָƻ + BOOL Delete(char *lpszTaskName); + BOOL DeleteFolder(char *lpszFolderName); + + // ƻ + BOOL NewTask(char *lpszTaskName, char *lpszProgramPath, char *lpszParameters, char *lpszAuthor = ""); + + // жָƻǷ + BOOL IsExist(char *lpszTaskName); + + // жָƻ״̬ǷЧ + BOOL IsTaskValid(char *lpszTaskName); + + // ָƻ + BOOL Run(char *lpszTaskName, char *lpszParam); + + // жָƻǷ + BOOL IsEnable(char *lpszTaskName); + + // ָƻǷǽ + BOOL SetEnable(char *lpszTaskName, BOOL bEnable); + +}; + + +#endif \ No newline at end of file diff --git a/src/AutoRun_Task_Test/ReadMe.txt b/src/AutoRun_Task_Test/ReadMe.txt new file mode 100644 index 0000000..c51450f --- /dev/null +++ b/src/AutoRun_Task_Test/ReadMe.txt @@ -0,0 +1,30 @@ +======================================================================== + 控制台应用程序:AutoRun_Task_Test 项目概述 +======================================================================== + +应用程序向导已为您创建了此 AutoRun_Task_Test 应用程序。 + +本文件概要介绍组成 AutoRun_Task_Test 应用程序的每个文件的内容。 + + +AutoRun_Task_Test.vcxproj + 这是使用应用程序向导生成的 VC++ 项目的主项目文件,其中包含生成该文件的 Visual C++ 的版本信息,以及有关使用应用程序向导选择的平台、配置和项目功能的信息。 + +AutoRun_Task_Test.vcxproj.filters + 这是使用“应用程序向导”生成的 VC++ 项目筛选器文件。它包含有关项目文件与筛选器之间的关联信息。在 IDE 中,通过这种关联,在特定节点下以分组形式显示具有相似扩展名的文件。例如,“.cpp”文件与“源文件”筛选器关联。 + +AutoRun_Task_Test.cpp + 这是主应用程序源文件。 + +///////////////////////////////////////////////////////////////////////////// +其他标准文件: + +StdAfx.h, StdAfx.cpp + 这些文件用于生成名为 AutoRun_Task_Test.pch 的预编译头 (PCH) 文件和名为 StdAfx.obj 的预编译类型文件。 + +///////////////////////////////////////////////////////////////////////////// +其他注释: + +应用程序向导使用“TODO:”注释来指示应添加或自定义的源代码部分。 + +///////////////////////////////////////////////////////////////////////////// diff --git a/src/AutoRun_Task_Test/stdafx.cpp b/src/AutoRun_Task_Test/stdafx.cpp new file mode 100644 index 0000000..b9a1c1a --- /dev/null +++ b/src/AutoRun_Task_Test/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : ֻ׼ļԴļ +// AutoRun_Task_Test.pch ΪԤͷ +// stdafx.obj ԤϢ + +#include "stdafx.h" + +// TODO: STDAFX.H +// κĸͷļڴļ diff --git a/src/AutoRun_Task_Test/stdafx.h b/src/AutoRun_Task_Test/stdafx.h new file mode 100644 index 0000000..baa4bbc --- /dev/null +++ b/src/AutoRun_Task_Test/stdafx.h @@ -0,0 +1,15 @@ +// stdafx.h : ׼ϵͳļİļ +// Ǿʹõĵ +// ضĿİļ +// + +#pragma once + +#include "targetver.h" + +#include +#include + + + +// TODO: ڴ˴óҪͷļ diff --git a/src/AutoRun_Task_Test/targetver.h b/src/AutoRun_Task_Test/targetver.h new file mode 100644 index 0000000..7a7d2c8 --- /dev/null +++ b/src/AutoRun_Task_Test/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// SDKDDKVer.h õ߰汾 Windows ƽ̨ + +// ҪΪǰ Windows ƽ̨Ӧó WinSDKVer.h +// WIN32_WINNT ΪҪֵ֧ƽ̨Ȼٰ SDKDDKVer.h + +#include diff --git a/src/Debug/AutoRun_Task_Test.exe b/src/Debug/AutoRun_Task_Test.exe new file mode 100644 index 0000000..a083dab Binary files /dev/null and b/src/Debug/AutoRun_Task_Test.exe differ