通過計划任務實現開機自啟動


實現原理:

  windows系統可以設置計划任務來執行一些定時任務。創建一個計划任務,設置任務的觸發條件以及執行操作。將觸發條件設置為用戶登錄,執行操作設置為啟動目標程序。這樣,程序就可以實現開機自啟動功能了。

  注意:創建計划任務要求程序必須要有管理員權限。

實現過程:

  (1).初始化操作

    1.初始化COM接口環境

    2.創建任務服務對象ITaskService,並將其鏈接到任務服務上

    3.從ITaskService對象中獲取根任務 Root Task Folde r的指針對象ITaskFolder,這個指針指向的是新注冊的任務。

  (2).創建任務技術

    1.創建任務定義對象來創建任務

    2.對任務定義對象 ITaskDefinition 進行設置

    3.使用 ITaskFolder 對象並利用任務定義對象 ITaskDefinition 的設置,注冊任務計划

實現代碼:

//CMyTaskSchedule.h

#pragma once


#include <taskschd.h>
#pragma comment(lib, "taskschd.lib")

class CMyTaskSchedule
{
public:
    CMyTaskSchedule();
    ~CMyTaskSchedule();

    //************************************
    // 函數名:  CMyTaskSchedule::NewTask
    // 返回類型:   BOOL
    // 功能: 創建計划任務
    // 參數1: char * lpszTaskName    計划任務名
    // 參數2: char * lpszProgramPath    計划任務路徑
    // 參數3: char * lpszParameters        計划任務參數
    // 參數4: char * lpszAuthor            計划任務作者
    //************************************
    BOOL NewTask(char* lpszTaskName, char* lpszProgramPath, char* lpszParameters, char* lpszAuthor);

    //************************************
    // 函數名:  CMyTaskSchedule::Delete
    // 返回類型:   BOOL
    // 功能: 刪除計划任務
    // 參數1: char * lpszTaskName    計划任務名
    //************************************
    BOOL Delete(char* lpszTaskName);

private:
    ITaskService *m_lpITS;
    ITaskFolder *m_lpRootFolder;
};
//CMyTaskSchedule.cpp

#include "pch.h"
#include "CMyTaskSchedule.h"

CMyTaskSchedule::CMyTaskSchedule()
{
    m_lpITS = NULL;
    m_lpRootFolder = NULL;
    //初始化COM
    HRESULT hr = CoInitialize(NULL);
    if (FAILED(hr))
    {
        MessageBox(NULL, L"初始化COM接口環境失敗!", L"Error", MB_OK);
        return;
    }

    //創建任務服務對象
    hr = CoCreateInstance(CLSID_TaskScheduler, NULL,
        CLSCTX_INPROC_SERVER, IID_ITaskService,
        (LPVOID*)(&m_lpITS));
    if (FAILED(hr))
    {
        MessageBox(NULL, L"創建任務服務對象失敗!", L"Error", MB_OK);
        return;
    }

    //連接到任務服務
    hr = m_lpITS->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t());
    if (FAILED(hr))
    {
        MessageBox(NULL, L"連接到任務服務失敗!", L"Error", MB_OK);
        return;
    }

    //獲取根任務的指針
    //獲取Root Task Folder 的指針 ,這個指針指向的是新注冊的任務
    hr = m_lpITS->GetFolder(_bstr_t("\\"), &m_lpRootFolder);
    if (FAILED(hr))
    {
        MessageBox(NULL, L"獲取根任務的指針失敗!", L"Error", MB_OK);
        return;
    }
}

CMyTaskSchedule::~CMyTaskSchedule()
{

    if (m_lpITS)
    {
        m_lpITS->Release();
    }
    if (m_lpRootFolder)
    {
        m_lpRootFolder->Release();
    }
    // 卸載COM
    CoUninitialize();
}

//創建任務計划
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))
    {
        MessageBox(NULL, L"創建任務失敗!", L"Error", MB_OK);
        return FALSE;
    }
    //設置注冊信息
    IRegistrationInfo *pRegInfo = NULL;
    CComVariant variantAuthor(NULL);
    variantAuthor = lpszAuthor;
    hr = pTaskDefinition->get_RegistrationInfo(&pRegInfo);
    if (FAILED(hr))
    {
        MessageBox(NULL, L"設置注冊信息失敗!", L"Error", MB_OK);
        return FALSE;
    }
    // 設置作者信息
    hr = pRegInfo->put_Author(variantAuthor.bstrVal);
    pRegInfo->Release();
    // 設置登錄類型和運行權限
    IPrincipal *pPrincipal = NULL;
    hr = pTaskDefinition->get_Principal(&pPrincipal);
    if (FAILED(hr))
    {
        MessageBox(NULL, L"設置登錄類型和運行權限失敗!", L"Error", MB_OK);
        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))
    {
        MessageBox(NULL, L"設置其他信息失敗!", L"Error", MB_OK);
        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))
    {
        MessageBox(NULL, L"創建執行動作失敗!", L"Error", MB_OK);
        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();
        MessageBox(NULL, L"創建執行動作失敗!", L"Error", MB_OK);
        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))
    {
        MessageBox(NULL, L"設置觸發器信息失敗!", L"Error", MB_OK);
        return FALSE;
    }
    // 創建觸發器
    ITrigger *pTrigger = NULL;
    hr = pTriggers->Create(TASK_TRIGGER_LOGON, &pTrigger);
    if (FAILED(hr))
    {
        MessageBox(NULL, L"創建觸發器失敗!", L"Error", MB_OK);
        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();
        MessageBox(NULL, L"注冊任務計划失敗!", L"Error", MB_OK);
        return FALSE;
    }
    pTaskDefinition->Release();
    pRegisteredTask->Release();
    return TRUE;
}

//刪除計划任務
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;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM