Windows计划任务开机启动程序

前言

Windows下需要管理员权限的开机程序启动时,如果Windows UAC等级设置的比较高,那么总是会提示是否启动某某程序的对话框,这对于用户来说体验非常不好,但是通过计划任务来设置程序以管理员身份启动就可以完全避免。

下面是C++和C#的实现代码,直接拿来用即可。

C++代码

   此代码是参考MSDN的里面,稍微进行了一点修改。MSDN例子

#define _CRT_SECURE_NO_WARNINGS
#define _WIN32_DCOM
#include <windows.h>
#include <iostream>
#include <stdio.h>
#include <comdef.h>
//  Include the task header file.
#include <taskschd.h>
#pragma comment(lib, "taskschd.lib")
#pragma comment(lib, "comsupp.lib")
using namespace std;
//是否存在指定名字的计划任务
bool IsExistScheduler(wchar_t *taskName)
{
	//  ------------------------------------------------------
//  Initialize COM.
	HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
	if (FAILED(hr))
	{
		return false;
	}
	//  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))
	{
		CoUninitialize();
		return false;
	}

	//  ------------------------------------------------------
	//  Create a name for the task.
	LPCWSTR wszTaskName = taskName;

	//  ------------------------------------------------------
	//  Create an instance of the Task Service. 
	ITaskService *pService = NULL;
	hr = CoCreateInstance(CLSID_TaskScheduler,
		NULL,
		CLSCTX_INPROC_SERVER,
		IID_ITaskService,
		(void**)&pService);
	if (FAILED(hr))
	{
		printf("Failed to create an instance of ITaskService: %x", hr);
		CoUninitialize();
		return false;
	}

	//  Connect to the task service.
	hr = pService->Connect(_variant_t(), _variant_t(),
		_variant_t(), _variant_t());
	if (FAILED(hr))
	{
		printf("ITaskService::Connect failed: %x", hr);
		pService->Release();
		CoUninitialize();
		return false;
	}

	//  ------------------------------------------------------
	//  Get the pointer to the root task folder.  This folder will hold the
	//  new task that is registered.
	ITaskFolder *pRootFolder = NULL;
	hr = pService->GetFolder(_bstr_t(L"\\"), &pRootFolder);
	if (FAILED(hr))
	{
		printf("Cannot get Root Folder pointer: %x", hr);
		pService->Release();
		CoUninitialize();
		return false;
	}
	//查看计划任务是否存在
	IRegisteredTask *ttt;
	auto ret=pRootFolder->GetTask(_bstr_t(wszTaskName),&ttt);
	if (ret != S_OK)
	{
		pRootFolder->Release();
		pService->Release();
		CoUninitialize();
		return false;
	}
	ttt->Release();
	pRootFolder->Release();
	pService->Release();
	CoUninitialize();
	return true;
}
//创建用户登录启动软件的任务
//taskName 任务名字
//executablePath 可执行文件路径
//creater 创建者
HRESULT LogonStartScheduler(wchar_t *taskName,wchar_t*executablePath,wchar_t *creater=NULL)
{
		//  ------------------------------------------------------
		//  Initialize COM.
		HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
		if (FAILED(hr))
		{
			return hr;
		}
		//  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))
		{
			CoUninitialize();
			return hr;
		}

		//  ------------------------------------------------------
		//  Create a name for the task.
		LPCWSTR wszTaskName = taskName;

		//  Get the windows directory and set the path to notepad.exe.
		wstring wstrExecutablePath = executablePath;


		//  ------------------------------------------------------
		//  Create an instance of the Task Service. 
		ITaskService *pService = NULL;
		hr = CoCreateInstance(CLSID_TaskScheduler,
			NULL,
			CLSCTX_INPROC_SERVER,
			IID_ITaskService,
			(void**)&pService);
		if (FAILED(hr))
		{
			printf("Failed to create an instance of ITaskService: %x", hr);
			CoUninitialize();
			return hr;
		}

		//  Connect to the task service.
		hr = pService->Connect(_variant_t(), _variant_t(),
			_variant_t(), _variant_t());
		if (FAILED(hr))
		{
			printf("ITaskService::Connect failed: %x", hr);
			pService->Release();
			CoUninitialize();
			return hr;
		}

		//  ------------------------------------------------------
		//  Get the pointer to the root task folder.  This folder will hold the
		//  new task that is registered.
		ITaskFolder *pRootFolder = NULL;
		hr = pService->GetFolder(_bstr_t(L"\\"), &pRootFolder);
		if (FAILED(hr))
		{
			printf("Cannot get Root Folder pointer: %x", hr);
			pService->Release();
			CoUninitialize();
			return hr;
		}
		//查看计划任务是否存在
		//IRegisteredTask *ttt;
		//auto ret=pRootFolder->GetTask(_bstr_t(L"OnebotStartScheduler"),&ttt);
		//if (ret == S_OK)
		//{
		//	ttt->Release();
		//	pRootFolder->Release();
		//	pService->Release();
		//	CoUninitialize();
		//	return 1;
		//}
		//  If the same task exists, remove it.
		pRootFolder->DeleteTask(_bstr_t(wszTaskName), 0);
		//  Create the task builder object to create the task.
		ITaskDefinition *pTask = NULL;
		hr = pService->NewTask(0, &pTask);

		pService->Release();  // COM clean up.  Pointer is no longer used.
		if (FAILED(hr))
		{
			printf("Failed to create a task definition: %x", hr);
			pRootFolder->Release();
			CoUninitialize();
			return hr;
		}

		//  ------------------------------------------------------
		//  Get the registration info for setting the identification.
		IRegistrationInfo *pRegInfo = NULL;
		hr = pTask->get_RegistrationInfo(&pRegInfo);
		if (FAILED(hr))
		{
			printf("\nCannot get identification pointer: %x", hr);
			pRootFolder->Release();
			pTask->Release();
			CoUninitialize();
			return hr;
		}
		if (creater != NULL)
		{
			WCHAR *AuthorName = creater;
			hr = pRegInfo->put_Author(AuthorName);
			if (FAILED(hr))
			{
			pRegInfo->Release();
				printf("\nCannot put identification info: %x", hr);
				pRootFolder->Release();
				pTask->Release();
				CoUninitialize();
				return hr;
			}
		}
			pRegInfo->Release();
		//  ------------------------------------------------------
		//  Create the settings for the task
		ITaskSettings *pSettings = NULL;
		hr = pTask->get_Settings(&pSettings);
		if (FAILED(hr))
		{
			printf("\nCannot get settings pointer: %x", hr);
			pRootFolder->Release();
			pTask->Release();
			CoUninitialize();
			return hr;
		}

		//  Set setting values for the task. 
		hr= pSettings->put_StartWhenAvailable(VARIANT_TRUE);
		if (FAILED(hr))
		{
			pSettings->Release();
			printf("\nCannot put setting info: %x", hr);
			pRootFolder->Release();
			pTask->Release();
			CoUninitialize();
			return 1;
		}
		hr = pSettings->put_DisallowStartIfOnBatteries(VARIANT_FALSE);
		pSettings->Release();
		if (FAILED(hr))
		{
			printf("\nCannot put setting info: %x", hr);
			pRootFolder->Release();
			pTask->Release();
			CoUninitialize();
			return hr;
		}

		//  ------------------------------------------------------
		//  Get the trigger collection to insert the logon trigger.
		ITriggerCollection *pTriggerCollection = NULL;
		hr = pTask->get_Triggers(&pTriggerCollection);
		if (FAILED(hr))
		{
			printf("\nCannot get trigger collection: %x", hr);
			pRootFolder->Release();
			pTask->Release();
			CoUninitialize();
			return hr;
		}

		//  Add the logon trigger to the task.
		ITrigger *pTrigger = NULL;
		hr = pTriggerCollection->Create(TASK_TRIGGER_LOGON, &pTrigger);
		pTriggerCollection->Release();
		if (FAILED(hr))
		{
			printf("\nCannot create the trigger: %x", hr);
			pRootFolder->Release();
			pTask->Release();
			CoUninitialize();
			return hr;
		}

		ILogonTrigger *pLogonTrigger = NULL;
		hr = pTrigger->QueryInterface(
			IID_ILogonTrigger, (void**)&pLogonTrigger);
		pTrigger->Release();
		if (FAILED(hr))
		{
			printf("\nQueryInterface call failed for ILogonTrigger: %x", hr);
			pRootFolder->Release();
			pTask->Release();
			CoUninitialize();
			return hr;
		}
	
		hr = pLogonTrigger->put_Id(_bstr_t(L"Trigger1"));
		if (FAILED(hr))
			printf("\nCannot put the trigger ID: %x", hr);

		wchar_t computerName[256] = { 0 };
		wchar_t userName[256] = { 0 };
		DWORD dwSize = 256;
		if (!GetComputerNameW(computerName, &dwSize)|| !GetUserNameW(userName, &dwSize))
		{		
			pRootFolder->Release();
			pTask->Release();
			CoUninitialize();
			return S_FALSE;
		}
		lstrcatW(computerName, (wchar_t*)L"\\");
		lstrcatW(computerName, userName);
		std::wcout << "当前用户名:" << computerName << endl;

		//  Define the user.  The task will execute when the user logs on.
		//  The specified user must be a user on this computer.  
		hr = pLogonTrigger->put_UserId(computerName);
		pLogonTrigger->Release();
		if (FAILED(hr))
		{
			printf("\nCannot add user ID to logon trigger: %x", hr);
			pRootFolder->Release();
			pTask->Release();
			CoUninitialize();
			return hr;
		}

		//  ------------------------------------------------------
		//  Add an Action to the task. This task will execute notepad.exe.     
		IActionCollection *pActionCollection = NULL;

		//  Get the task action collection pointer.
		hr = pTask->get_Actions(&pActionCollection);
		if (FAILED(hr))
		{
			printf("\nCannot get Task collection pointer: %x", hr);
			pRootFolder->Release();
			pTask->Release();
			CoUninitialize();
			return hr;
		}

		//  Create the action, specifying that it is an executable action.
		IAction *pAction = NULL;
		hr = pActionCollection->Create(TASK_ACTION_EXEC, &pAction);
		pActionCollection->Release();
		if (FAILED(hr))
		{
			printf("\nCannot create the action: %x", hr);
			pRootFolder->Release();
			pTask->Release();
			CoUninitialize();
			return hr;
		}

		IExecAction *pExecAction = NULL;
		//  QI for the executable task pointer.
		hr = pAction->QueryInterface(
			IID_IExecAction, (void**)&pExecAction);
		pAction->Release();
		if (FAILED(hr))
		{
			printf("\nQueryInterface call failed for IExecAction: %x", hr);
			pRootFolder->Release();
			pTask->Release();
			CoUninitialize();
			return hr;
		}

		//  Set the path of the executable to notepad.exe.
		hr = pExecAction->put_Path(_bstr_t(wstrExecutablePath.c_str()));
		pExecAction->Release();
		if (FAILED(hr))
		{
			printf("\nCannot set path of executable: %x", hr);
			pRootFolder->Release();
			pTask->Release();
			CoUninitialize();
			return hr;
		}

		//  ------------------------------------------------------
		//  Save the task in the root folder.
		IRegisteredTask *pRegisteredTask = NULL;

		hr = pRootFolder->RegisterTaskDefinition(
			_bstr_t(wszTaskName),
			pTask,
			TASK_CREATE_OR_UPDATE,
			_variant_t(computerName),
			_variant_t(),
			TASK_LOGON_INTERACTIVE_TOKEN,
			_variant_t(L""),
			&pRegisteredTask);
		if (FAILED(hr))
		{
			printf("\nError saving the Task : %x", hr);
			pRootFolder->Release();
			pTask->Release();
			CoUninitialize();
			return hr;
		}

		printf("\n Success! Task successfully registered. ");

		// Clean up
		pRootFolder->Release();
		pTask->Release();
		pRegisteredTask->Release();
		CoUninitialize();
		return 0;
	
}

C#代码

注意需要安装nuget包TaskScheduler

        /// <summary>
        /// 开机自启
        /// </summary>
        /// <param name="taskName">任务名字</param>
        /// <param name="fileName">可执行文件路径(如果路径存在空格,最好将路径用双引号包起来,"C:\\Program Files (x86)\\123.exe")</param>
        /// <param name="description">任务藐视</param>
        public static void AutoStart(string taskName,string fileName,string description)
        {
            if (string.IsNullOrEmpty(taskName) || string.IsNullOrEmpty(fileName))
            {
                throw new ArgumentNullException();
            }
            string TaskName = taskName;
            var logonUser = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
            string taskDescription = description;
            string deamonFileName = fileName;

            using (var taskService = new TaskService())
            {
                var tasks = taskService.RootFolder.GetTasks(new System.Text.RegularExpressions.Regex(TaskName));
                foreach (var t in tasks)
                {
                    taskService.RootFolder.DeleteTask(t.Name);
                }

                var task = taskService.NewTask();
                task.RegistrationInfo.Description = taskDescription;
                task.Settings.DisallowStartIfOnBatteries = false;//当使用电源时,也运行此计划任务
                task.Triggers.Add(new LogonTrigger { UserId = logonUser });
                task.Principal.RunLevel = TaskRunLevel.Highest;
                task.Actions.Add(new ExecAction(deamonFileName));

                taskService.RootFolder.RegisterTaskDefinition(TaskName, task);
            }
        }

 

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
回答: 在Windows中设置开机自启动项有几种方法可以选择。一种方法是通过打开开机启动文件夹来添加开机启动项。你可以在文件夹路径"C:\Users(用户)\Administrator(当前用户名)\AppData\Roaming\Microsoft\Windows\Start Menu\Programs(「开始」菜单)\Programs(程序)\Startup(启动)"中找到启动文件夹,将需要开机自启动的程序或软件的快捷方式放入该文件夹中即可。\[1\] 另一种方法是使用任务计划程序来设置开机自启动项。你可以通过在"我的电脑"上右键点击并选择"管理"来打开任务计划程序。在任务计划程序中,你可以选择创建基本任务或创建任务,然后按照提示填写相关信息,选择启动程序并指定需要开机自启动的应用程序或批处理文件。\[2\] 还有一种方法是通过注册表来设置开机自启动项。你可以按下Win + R组合键打开运行窗口,输入"regedit.exe"进入注册表编辑器。在注册表编辑器中,导航到"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run"位置,右键点击空白处并新建字符串值,将需要开机自启动的应用程序位置填入数值数据位置中即可。\[3\] 以上是三种常用的方法来设置Windows开机自启动项。你可以根据自己的需求选择其中一种方法来添加开机自启动项。 #### 引用[.reference_title] - *1* *2* [windows10添加开机自启动项在哪设置?电脑开机自启动怎么设置](https://blog.csdn.net/qq_41608099/article/details/117767043)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Windows设置程序开机自启动的几种方法(整理发布)](https://blog.csdn.net/pizai147258/article/details/126540889)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值