不以物喜,不以己悲

C++修改任务计划程序-电源条件

  1. 介绍
    应用程序需要进行守护,又不想另外运行一个软件去实时监测应用程序是否退出了,退出就重启。在Windows上可以利用任务计划程序,达到守护进程的作用。
  2. 创建任务计划
    在nsis脚本中可以直接使用schtasks命令来创建任务计划,以下是每分钟检测一次的脚本。
    nsExec::ExecToLog 'schtasks /create /tn "${PRODUCT_NAME}" /tr "\"$INSTDIR\ILink.exe\" -schtasks" /sc MINUTE /mo 1 /f' ;创建计划任务
  3. 问题
    使用schtasks命令行创建的任务计划,会在笔记本电脑未接通电源的情况下失效。失效原因为,任务计划中的条件项中的电源条件导致了失效
  4. 解决方案
    schtasks命令无法修改电源选项,故使用C++制作了一个小程序由nsis脚本中调用来关闭电源条件。
    以下是C++实现代码部分:
// SQTool.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#define _WIN32_DCOM
#include <iostream>
#include<comdef.h>
#include<wincred.h>
#include<taskschd.h>
#pragma comment(lib, "taskschd.lib")
#pragma comment(lib, "comsupp.lib")
#pragma comment(lib, "credui.lib")
using namespace std;

int wmain(int argc, WCHAR** argv)
{
        if (argc <= 1)
        {
                std::cout << "请输入正确的参数" << std::endl;
                return 1;
        }
        WCHAR* taskName = argv[1];
        std::wcout << L"任务名称为:" << taskName << std::endl;
        std::cout << "开始修改条件->电源-[只有在计算机使用交流电时才启动此任务]-[如果计算机改用电池电源,则停止]" << std::endl;
        std::cout << "设置->如果任务运行时间超过以下时间,停止任务" << std::endl;
        HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
        if (FAILED(hr))
        {
                std::cout << "CoInitializeEx failed:" << hr << std::endl;
                return 1;
        }
        hr = CoInitializeSecurity(
                NULL,
                -1,
                NULL,
                NULL,
                RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
                RPC_C_IMP_LEVEL_IMPERSONATE,
                NULL,
                0,
                NULL);
        if (FAILED(hr))
        {
                std::cout << "CoInitializeSecurity failed:" << hr << std::endl;
                return 1;
        }
        LPCWSTR wszTaskName = taskName;

        ITaskService* pService = nullptr;
        hr = CoCreateInstance(CLSID_TaskScheduler,
                NULL,
                CLSCTX_INPROC_SERVER,
                IID_ITaskService,
                (void**)&pService);
        if (FAILED(hr))
        {
                std::cout << "Failed to create an instance of ITaskService:" << hr << std::endl;
                return 1;
        }
        hr = pService->Connect(_variant_t(), _variant_t(),
                _variant_t(), _variant_t());
        if (FAILED(hr))
        {
                std::cout << "ITaskService:Connect failed:" << hr << std::endl;
                pService->Release();
                CoUninitialize();
                return 1;
        }
        ITaskFolder* pRootFolder = nullptr;
        hr = pService->GetFolder(_bstr_t(L"\\"), &pRootFolder);
        if (FAILED(hr))
        {
                std::cout << "Canot get root folder pointer:" << hr << std::endl;
                pService->Release();
                CoUninitialize();
                return 1;
        }
        IRegisteredTask* pRegisteredTask = nullptr;
        hr = pRootFolder->GetTask(taskName, &pRegisteredTask);
        if (FAILED(hr))
        {
                std::cout << "GetTask fail:" << hr << std::endl;
                return 1;
        }
        ITaskDefinition* pTaskDefinition = nullptr;
        hr = pRegisteredTask->get_Definition(&pTaskDefinition);
        if (FAILED(hr))
        {
                std::cout << "get_Definition fail:" << hr << std::endl;
                return 1;
        }
        ITaskSettings* pTaskSettings = nullptr;
        hr = pTaskDefinition->get_Settings(&pTaskSettings);
        if (FAILED(hr))
        {
                std::cout << "get_Settings fail:" << hr << std::endl;
                return 1;
        }
        pTaskSettings->put_DisallowStartIfOnBatteries(false);
        pTaskSettings->put_StopIfGoingOnBatteries(false);
        pTaskSettings->put_ExecutionTimeLimit(_bstr_t(L"PT0H"));
        hr = pRootFolder->RegisterTaskDefinition(
                _bstr_t(wszTaskName),
                pTaskDefinition,
                TASK_CREATE_OR_UPDATE,
                _variant_t(),
                _variant_t(),
                TASK_LOGON_INTERACTIVE_TOKEN,
                _variant_t(L""),
                &pRegisteredTask);
        if (FAILED(hr))
        {
                std::cout << "RegisterTaskDefinition fail:" << hr << std::endl;
                return 1;
        }
        pTaskSettings->Release();
        pTaskDefinition->Release();
        pRegisteredTask->Release();
        pRootFolder->Release();
        pService->Release();
        std::cout << "设置结束" << std::endl;
}

  1. 参考文档
    文档
posted @ 2024-07-03 17:26  这种人  阅读(76)  评论(0编辑  收藏  举报