使用qt实现windows上的任务计划启动,并设置开机启动,获取当前用户,并设置当前用户权限的启动,避免导致程序出现权限不同导致的各种问题
头文件check_nodpad.h
#pragma once
#include <QDebug>
#include <QObject>
#include <QProcess>
#include <QTimer>
#include "check_nodpad.h"
#include <Lmcons.h>
#include <comdef.h>
#include <iostream>
#include <taskschd.h>
#include <windows.h>
class Check_nodpad : public QObject
{
// Q_OBJECT
public:
Check_nodpad(QObject *QObject = nullptr);
~Check_nodpad();
void close_nodpad();
HRESULT InitializeTaskService(ITaskService **ppService); //初始化任务列表
HRESULT GetCurrentUserName(std::wstring &userName);//获取当前登录用户名称
HRESULT CreateScheduledTask(ITaskService *pService,
const std::wstring &taskName,
const std::wstring &appPath,
const std::wstring &userName);//创建开机任务
HRESULT DeleteScheduledTask(ITaskService *pService, const std::wstring &taskName);//删除开机任务
HRESULT RunScheduledTask(ITaskService *pService, const std::wstring &taskName);//执行当前开机任务
bool IsTaskExists(ITaskService *pService, const std::wstring &taskName);//检测当前任务是否存在
private:
std::wstring taskName, appPath;
ITaskService *pService;
};
cpp文件
#include "check_nodpad.h"
Check_nodpad::Check_nodpad(QObject *QObject)
{
HRESULT hr = InitializeTaskService(&pService);
if (FAILED(hr)) {
return;
}
taskName = L"test_notepad";
appPath = L"C:\\Windows\\notepad.exe";
std::wstring userName;
hr = GetCurrentUserName(userName);
if (!this->IsTaskExists(pService, taskName)) {
hr = this->CreateScheduledTask(pService, taskName, appPath, userName);
if (FAILED(hr)) {
std::cerr << "Failed to create scheduled task." << std::endl;
} else {
std::cout << "Scheduled task created successfully." << std::endl;
}
} else {
std::cout << "Scheduled task already exists." << std::endl;
}
}
Check_nodpad::~Check_nodpad()
{
pService->Release();
CoUninitialize();
}
void Check_nodpad::close_nodpad()
{
int id = getProcessIdByName("notepad.exe");
if (id > 0) {
killProcessById(id);
}
}
HRESULT Check_nodpad::InitializeTaskService(ITaskService **ppService)
{
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (FAILED(hr)) {
std::cerr << "CoInitializeEx failed: " << hr << std::endl;
return hr;
}
hr = CoCreateInstance(CLSID_TaskScheduler,
NULL,
CLSCTX_INPROC_SERVER,
IID_ITaskService,
(void **) ppService);
if (FAILED(hr)) {
std::cerr << "Failed to create TaskService instance: " << hr << std::endl;
CoUninitialize();
return hr;
}
hr = (*ppService)->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t());
if (FAILED(hr)) {
std::cerr << "ITaskService::Connect failed: " << hr << std::endl;
(*ppService)->Release();
CoUninitialize();
return hr;
}
return S_OK;
}
HRESULT Check_nodpad::GetCurrentUserName(std::wstring &userName)
{
wchar_t userBuffer[UNLEN + 1];
DWORD userBufferSize = UNLEN + 1;
if (GetUserName(userBuffer, &userBufferSize)) {
userName = userBuffer;
return S_OK;
} else {
std::cerr << "Failed to get current user name: " << GetLastError() << std::endl;
return E_FAIL;
}
}
HRESULT Check_nodpad::CreateScheduledTask(ITaskService *pService,
const std::wstring &taskName,
const std::wstring &appPath,
const std::wstring &userName)
{
ITaskFolder *pRootFolder = NULL;
HRESULT hr = pService->GetFolder(_bstr_t(L"\\"), &pRootFolder);
if (FAILED(hr)) {
std::cerr << "Failed to get root folder: " << hr << std::endl;
return hr;
}
// 删除已存在的任务,避免冲突
pRootFolder->DeleteTask(_bstr_t(taskName.c_str()), 0);
ITaskDefinition *pTask = NULL;
hr = pService->NewTask(0, &pTask);
if (FAILED(hr)) {
std::cerr << "Failed to create new task: " << hr << std::endl;
pRootFolder->Release();
return hr;
}
// 设置任务信息
IRegistrationInfo *pRegInfo = NULL;
hr = pTask->get_RegistrationInfo(&pRegInfo);
if (SUCCEEDED(hr)) {
BSTR author = SysAllocString(L"AuthorName");
if (author) {
pRegInfo->put_Author(author);
SysFreeString(author);
}
pRegInfo->Release();
}
// 设置触发器 - 系统启动时
ITriggerCollection *pTriggerCollection = NULL;
hr = pTask->get_Triggers(&pTriggerCollection);
if (SUCCEEDED(hr)) {
ITrigger *pTrigger = NULL;
hr = pTriggerCollection->Create(TASK_TRIGGER_BOOT, &pTrigger);
if (SUCCEEDED(hr)) {
pTrigger->Release();
}
pTriggerCollection->Release();
}
// 设置操作 - 启动应用程序
IActionCollection *pActionCollection = NULL;
hr = pTask->get_Actions(&pActionCollection);
if (SUCCEEDED(hr)) {
IAction *pAction = NULL;
hr = pActionCollection->Create(TASK_ACTION_EXEC, &pAction);
if (SUCCEEDED(hr)) {
IExecAction *pExecAction = NULL;
hr = pAction->QueryInterface(IID_IExecAction, (void **) &pExecAction);
if (SUCCEEDED(hr)) {
BSTR path = SysAllocString(appPath.c_str());
if (path) {
pExecAction->put_Path(path);
SysFreeString(path);
}
pExecAction->Release();
}
pAction->Release();
}
pActionCollection->Release();
}
// 注册任务
IRegisteredTask *pRegisteredTask = NULL;
hr = pRootFolder->RegisterTaskDefinition(_bstr_t(taskName.c_str()),
pTask,
TASK_CREATE_OR_UPDATE,
_variant_t(userName.c_str()),
_variant_t(), // 空密码
TASK_LOGON_INTERACTIVE_TOKEN,
_variant_t(),
&pRegisteredTask);
if (FAILED(hr)) {
std::cerr << "Failed to register task: " << hr << std::endl;
}
pRegisteredTask->Release();
pTask->Release();
pRootFolder->Release();
return hr;
}
HRESULT Check_nodpad::DeleteScheduledTask(ITaskService *pService, const std::wstring &taskName)
{
ITaskFolder *pRootFolder = NULL;
HRESULT hr = pService->GetFolder(_bstr_t(L"\\"), &pRootFolder);
if (FAILED(hr)) {
std::cerr << "Failed to get root folder: " << hr << std::endl;
return hr;
}
hr = pRootFolder->DeleteTask(_bstr_t(taskName.c_str()), 0);
pRootFolder->Release();
return hr;
}
HRESULT Check_nodpad::RunScheduledTask(ITaskService *pService, const std::wstring &taskName)
{
ITaskFolder *pRootFolder = NULL;
HRESULT hr = pService->GetFolder(_bstr_t(L"\\"), &pRootFolder);
if (FAILED(hr)) {
std::cerr << "Failed to get root folder: " << hr << std::endl;
return hr;
}
IRegisteredTask *pRegisteredTask = NULL;
hr = pRootFolder->GetTask(_bstr_t(taskName.c_str()), &pRegisteredTask);
if (FAILED(hr)) {
std::cerr << "Failed to get registered task: " << hr << std::endl;
pRootFolder->Release();
return hr;
}
IRunningTask *pRunningTask = NULL;
hr = pRegisteredTask->Run(_variant_t(), &pRunningTask);
if (FAILED(hr)) {
std::cerr << "Failed to run task: " << hr << std::endl;
} else {
std::cout << "Task started successfully." << std::endl;
pRunningTask->Release();
}
pRegisteredTask->Release();
pRootFolder->Release();
return hr;
}
bool Check_nodpad::IsTaskExists(ITaskService *pService, const std::wstring &taskName)
{
ITaskFolder *pRootFolder = NULL;
HRESULT hr = pService->GetFolder(_bstr_t(L"\\"), &pRootFolder);
if (FAILED(hr)) {
std::cerr << "Failed to get root folder: " << hr << std::endl;
return false;
}
IRegisteredTask *pRegisteredTask = NULL;
hr = pRootFolder->GetTask(_bstr_t(taskName.c_str()), &pRegisteredTask);
if (SUCCEEDED(hr)) {
pRegisteredTask->Release();
pRootFolder->Release();
return true;
}
pRootFolder->Release();
return false;
}
通过以上函数,就可以轻松创建开机任务,以及执行当前开机任务,我这边主要是为了解决服务区启动程序的时候设置普通用户权限不生效的问题,通过系统任务列表的方式去实现,就可以轻松避免这样的问题出现