开机自启动有很多种方式 : 注册表实现, 任务计划等等;
这里只介绍用com接口实现对任务计划(win32的API :NetScheduleJobAdd在Win7 上没有效果)
我们用到的是ITaskService interface [Task Scheduler] 接口的一些相关函数,因此对系统有一定的要求:
Requirements
Client |
Requires Windows Vista. |
Server |
Requires Windows Server 2008. |
Header |
Declared in Taskschd.h. |
Library |
Use Taskschd.lib. |
DLL |
Requires Taskschd.dll. |
下面开始介绍如何实现对任务计划的一些操作:
首先创建一个名为test的任务计划
然后创建一个win32的控制台程序添加下面两个文件,然后再main函数中实现相关的测试。代码如下:
1. TaskScheduleFun.h
#pragma once
#include <stdio.h>
#include <tchar.h>
// com include
#include <comdef.h>
#include <comutil.h>
// task header include
#include <taskschd.h>
// task lib
#pragma comment(lib, "taskschd.lib")
#pragma comment(lib, "comsupp.lib")
#define _WIN32_DCOM
#define MAX_XMLREAD MAX_PATH*10
// Attentions
// Provide by Vivian
// For all functions as following, you must do TaskScheduleComInit before you call others and
// TaskScheduleComUnInit at the end
// Task schedule init
BOOL TaskScheduleComInit();
// Task schedule uninit
void TaskScheduleComUnInit();
// Delete task according to TaskName
void TaskScheduleTaskDelet(BSTR bstrTaskName, BSTR bstrFloder= _bstr_t("//"));
// Create task
BOOL TaskScheduleTaskCreateFromXml(BSTR bstrTaskName, const char* pstrSaveName, BSTR bstrFloder = _bstr_t("//"));
// Save task information to xml file
BOOL TaskScheduleTaskSave(BSTR bstrTaskName, const char* pstrSaveName, BSTR bstrFloder = _bstr_t("//"));
================================================================================
2. TaskScheduleFun.cpp
#include "TaskScheduleFun.h"
// Debug msg
TCHAR tszDebug_Task[MAX_PATH] = {0};
BOOL TaskScheduleComInit()
{
// init 1-2
// 1. Initialize COM.
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if( FAILED(hr) )
{
OutputDebugString(TEXT("Com CoInitializeEx() Failed!/r/n"));
return FALSE;
}
// 2. Set general COM security levels.
hr = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT_PRIVACY, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, 0, NULL);
if( FAILED(hr) )
{
OutputDebugString(TEXT("Com CoInitializeSecurity() Failed!/r/n"));
CoUninitialize();
return FALSE;
}
return TRUE;
}
void TaskScheduleComUnInit()
{
CoUninitialize();
}
BOOL TaskScheduleGetITaskFolder(BSTR bstrFloder, ITaskService **ppService, ITaskFolder **ppTaskFolder)
{
// Save Target Task to Xml file 1-3
// 1.Create an instance of the Task Service.
HRESULT hr = CoCreateInstance(CLSID_TaskScheduler, NULL, CLSCTX_INPROC_SERVER, IID_ITaskService, (void**)ppService);
if (FAILED(hr))
{
OutputDebugString(TEXT("TaskScheduleTaskSave :: ITaskService CoCreateInstance() failed!/r/n"));
return FALSE;
}
// 2.Connect to local pc
hr = (*ppService)->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t());
if( FAILED(hr) )
{
OutputDebugString(TEXT("TaskScheduleTaskSave :: ITaskService Connect() failed!/r/n"));
return FALSE;
}
// 3.Get the pointer to the task folder.
hr = (*ppService)->GetFolder(bstrFloder , ppTaskFolder);
if( FAILED(hr) )
{
OutputDebugString(TEXT("TaskScheduleTaskSave :: ITaskService GetFolder() failed!/r/n"));
return FALSE;
}
return TRUE;
}
void TaskScheduleTaskDelet(BSTR bstrTaskName,BSTR bstrFloder)
{
ITaskService *pService = NULL; // Task Service
ITaskFolder *pTaskFolder = NULL; // Task folder
// If the same task exists, remove it. 1-2
// 1.Get ITaskFolder interface
BOOL bres = TaskScheduleGetITaskFolder(bstrFloder, &pService, &pTaskFolder);
if(!bres)
{
OutputDebugString(TEXT("TaskScheduleTaskSave :: TaskScheduleGetITaskFolder() failed!/r/n"));
}
// 2. Delete task
pTaskFolder->DeleteTask(bstrTaskName, 0);
if (pService)
{
pService->Release();
}
if (pTaskFolder)
{
pTaskFolder->Release();
}
}
BOOL SaveTaskXmlInfToFile(BSTR bstrXmlText, const char* pstrSaveName)
{
// Save TaskXml Information To File 1-3
char* pstrXml = NULL;
BOOL brtnInf = TRUE;
// 1. transfer BSTR to char*
pstrXml = _com_util::ConvertBSTRToString(bstrXmlText);
// 2. Open file and write
FILE *stream = NULL;
stream = fopen(pstrSaveName, "w+");
if(stream != NULL )
{
int nwrite = fwrite((void*)pstrXml, sizeof(char), strlen(pstrXml), stream);
_stprintf_s(tszDebug_Task, MAX_PATH, TEXT("Wrote %d items/r/n"), nwrite);
OutputDebugString(tszDebug_Task);
}
else
{
brtnInf = FALSE;
OutputDebugString(TEXT("SaveTaskXmlInfToFile :: Open file failed!/r/n"));
}
// 3. Close file
if(stream)
{
if ( fclose(stream))
{
OutputDebugString(TEXT("SaveTaskXmlInfToFile :: Close file failed!/r/n"));
return FALSE;
}
}
return brtnInf;
}
BOOL GetTaskXmlInfFromFile(BSTR *pbstrXmlText, const char* pstrSaveName)
{
// Get TaskXml Information From File 1-3
char strXml[MAX_XMLREAD] = {0};
BOOL brtnInf = TRUE;
// 1. Open file and read
FILE *stream = NULL;
stream = fopen(pstrSaveName, "r");
if(stream != NULL )
{
int numread = fread(strXml, sizeof(char), MAX_XMLREAD, stream);
strXml[numread] = '/0';
}
else
{
brtnInf = FALSE;
OutputDebugString(TEXT("GetTaskXmlInfFromFile :: Open file failed!/r/n"));
}
// 2. Transfer char* to BSTR
*pbstrXmlText = _com_util::ConvertStringToBSTR((const char*)strXml);
// 3. Close file
if(stream)
{
if (fclose(stream))
{
OutputDebugString(TEXT("GetTaskXmlInfFromFile :: Close file failed!/r/n"));
return FALSE;
}
}
return brtnInf;
}
BOOL TaskScheduleTaskSave(BSTR bstrTaskName, const char* pstrSaveName, BSTR bstrFloder)
{
// Save Target Task to Xml file 1-4
ITaskService *pService = NULL; // Task Service
ITaskFolder *pTaskFolder = NULL; // Task folder
IRegisteredTaskCollection* pTaskCollection = NULL; // Task collection
BSTR bstrXmlText = NULL; // XmlText
LONG numTasks = 0; // Task num
BOOL brtnInf = FALSE;
// 1.Get ITaskFolder interface
BOOL bres = TaskScheduleGetITaskFolder(bstrFloder, &pService, &pTaskFolder);
if(!bres)
{
OutputDebugString(TEXT("TaskScheduleTaskSave :: TaskScheduleGetITaskFolder() failed!/r/n"));
brtnInf = FALSE;
goto END_RETURN;
}
// 2.Get the registered tasks in the folder.
HRESULT hr = pTaskFolder->GetTasks(NULL, &pTaskCollection);
if( FAILED(hr) )
{
OutputDebugString(TEXT("TaskScheduleTaskSave :: ITaskFolder GetTasks() failed!/r/n"));
brtnInf = FALSE;
goto END_RETURN;
}
// 3. Get task counts
hr = pTaskCollection->get_Count(&numTasks);
if( numTasks == 0 )
{
OutputDebugString(TEXT("TaskScheduleTaskSave :: IRegisteredTaskCollection get_Count() failed!/r/n"));
brtnInf = FALSE;
goto END_RETURN;
}
_stprintf_s(tszDebug_Task, MAX_PATH, TEXT("Number of Tasks : %d./r/n"), numTasks);
OutputDebugString(tszDebug_Task);
// 4. Find target task
for(LONG i=0; i < numTasks; i++)
{
IRegisteredTask* pRegisteredTask = NULL;
hr = pTaskCollection->get_Item( _variant_t(i+1), &pRegisteredTask );
// Get Item
if( SUCCEEDED(hr) )
{
BSTR taskName = NULL;
hr = pRegisteredTask->get_Name(&taskName);
// Get name
if(SUCCEEDED(hr))
{
// Compare name
if(_bstr_t(taskName) == _bstr_t(bstrTaskName))
{
ITaskDefinition* pTaskDef = NULL;
hr = pRegisteredTask->get_Definition(&pTaskDef); // get task definition
if(SUCCEEDED(hr))
{
hr = pTaskDef->get_XmlText(&bstrXmlText); // get xml information
if(SUCCEEDED(hr))
{
bres = SaveTaskXmlInfToFile(bstrXmlText, pstrSaveName);
if (!bres)
{
OutputDebugString(TEXT("SaveTaskXmlInfToFile() failed!/r/n"));
brtnInf = FALSE;
}
}
}
if(pTaskDef)
{
pTaskDef->Release();
}
brtnInf = TRUE;
break;
}// end Compare name
}// end Get name
else
{
OutputDebugString(TEXT("TaskScheduleTaskSave :: IRegisteredTask get_Name() failed!/r/n"));
brtnInf = FALSE;
}
if (pRegisteredTask)
{
pRegisteredTask->Release();
}
if (taskName)
{
SysFreeString(taskName);
}
}// end Get Item
else
{
OutputDebugString(TEXT("TaskScheduleTaskSave :: IRegisteredTaskCollection get_Item() failed!/r/n"));
brtnInf = FALSE;
}
}// end 6. Find target task
END_RETURN:
if (pService)
{
pService->Release();
}
if (pTaskFolder)
{
pTaskFolder->Release();
}
if (pTaskCollection)
{
pTaskCollection->Release();
}
if (bstrXmlText)
{
SysFreeString(bstrXmlText);
}
return brtnInf;
}
// Create task
BOOL TaskScheduleTaskCreateFromXml(BSTR bstrTaskName, const char* pstrSaveName, BSTR bstrFloder)
{
// Save Target Task to Xml file 1-5
ITaskService *pService = NULL; // Task Service
ITaskFolder *pTaskFolder = NULL; // Task folder
ITaskDefinition *pTaskDef = NULL; // Task definition
IRegisteredTask *pRegisteredTask = NULL; // Task Register
BSTR bstrXmlText = NULL; // XmlText
BOOL brtnInf = TRUE;
// 1.Get ITaskFolder interface
BOOL bres = TaskScheduleGetITaskFolder(bstrFloder, &pService, &pTaskFolder);
if(!bres)
{
OutputDebugString(TEXT("TaskScheduleTaskCreateFromXml :: TaskScheduleGetITaskFolder() failed!/r/n"));
brtnInf = FALSE;
goto END_RETURN;
}
// 2.Create the task builder object to create the task.
HRESULT hr = pService->NewTask(0, &pTaskDef);
if(FAILED(hr))
{
OutputDebugString(TEXT("TaskScheduleTaskCreateFromXml :: NewTask() failed!/r/n"));
brtnInf = FALSE;
goto END_RETURN;
}
// 3.Read Task information from saved xml
bres = GetTaskXmlInfFromFile(&bstrXmlText, pstrSaveName);
if (!bres)
{
OutputDebugString(TEXT("GetTaskXmlInfFromFile() failed!/r/n"));
brtnInf = FALSE;
goto END_RETURN;
}
// 4.Load task xml information to ITaskDefinition
hr = pTaskDef->put_XmlText(bstrXmlText);
if(FAILED(hr))
{
OutputDebugString(TEXT("TaskScheduleTaskCreateFromXml :: put_XmlText() failed!/r/n"));
brtnInf = FALSE;
goto END_RETURN;
}
// 5.Regist Task
hr = pTaskFolder->RegisterTaskDefinition(bstrTaskName, pTaskDef, TASK_CREATE_OR_UPDATE,
_variant_t(L"Builtin//Administrators"), _variant_t(),
TASK_LOGON_GROUP, _variant_t(L""), &pRegisteredTask);
if(FAILED(hr))
{
OutputDebugString(TEXT("TaskScheduleTaskCreateFromXml :: RegisterTaskDefinition() failed!/r/n"));
brtnInf = FALSE;
goto END_RETURN;
}
END_RETURN:
if (pService)
{
pService->Release();
}
if (pTaskFolder)
{
pTaskFolder->Release();
}
if (pTaskDef)
{
pTaskDef->Release();
}
if (pRegisteredTask)
{
pRegisteredTask->Release();
}
if (bstrXmlText)
{
SysFreeString(bstrXmlText);
}
return brtnInf;
}
==============================================================================
3. How to use?
#include "stdafx.h"
#include "TaskScheduleFun.h"
#include <Shlwapi.h>
#pragma comment(lib, "shlwapi.lib")
int _tmain(int argc, _TCHAR* argv[])
{
// Task schedule init
BOOL bres = TaskScheduleComInit();
if(!bres)
{
OutputDebugString(TEXT("Task schedule com init failed!/r/n"));
return 0;
}
// xml file full path
char szPath[MAX_PATH] = {0};
DWORD dwres = GetModuleFileNameA(NULL, szPath, MAX_PATH);
if (dwres == 0)
{
OutputDebugString(TEXT("GetModuleFileNameA failed!/r/n"));
return 0;
}
if (!PathRemoveFileSpecA(szPath))
{
OutputDebugString(TEXT("PathRemoveFileSpecA failed!/r/n"));
return 0;
}
int nerror = strcat_s(szPath, MAX_PATH, "//test.txt");
if (nerror)
{
OutputDebugString(TEXT("Get xml file full path strcat_s failed!/r/n"));
return 0;
}
OutputDebugString(TEXT("Xml file full path is /r/n"));
OutputDebugStringA(szPath);
// TASKSCHEDULE_SAVE
bres = TaskScheduleTaskSave(_bstr_t("test"), szPath);
if (!bres)
{
OutputDebugString(TEXT("TaskScheduleTaskSave failed!/r/n"));
}
// TASKSCHEDULE_DELET
TaskScheduleTaskDelet(_bstr_t("test"));
// TASKSCHEDULE_CREATE: // Create new Task
bres = TaskScheduleTaskCreateFromXml(_bstr_t("test"), szPath);
if (!bres)
{
OutputDebugString(TEXT("TaskScheduleTaskCreateFromXml failed!/r/n"));
}
else
{
OutputDebugString(TEXT("TaskScheduleTaskCreateFromXml sucess~~!/r/n"));
}
// Task schedule uninit
TaskScheduleComUnInit();
return 0;
}
注意:在运行程序时一定要求管理员权限,否则只能找到系统自己的任务计划,无法找到用户自己创建的任务计划。
以上是在研究任务计划的时候写的。有什么问题可以留言,大家一起讨论。O(∩_∩)O~