1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > .net 创建计划任务开机后自动以管理员身份启动运行 win7 ~ win10

.net 创建计划任务开机后自动以管理员身份启动运行 win7 ~ win10

时间:2024-06-18 21:22:05

相关推荐

.net 创建计划任务开机后自动以管理员身份启动运行 win7 ~ win10

假如要启动 this.exe。以下逻辑中会启动先后关联启动三个实例分别是ABC。先启动第一个实例A,A启动实例B,B启动实例C.

要求:

1.如果没有以管理员权限运行,则请求管理员权限运行,即使没有请求成功或请求成功之前,也要先以非管理员权限运行,因为它定时要执行一些任务,不能因阻塞而错过。

2.如果没有以管理员权限运行,也要可以动态申请以管理员权限来注册开机启动,然后托盘显示右键菜单指示是否已经设置开机启动。

3.支持Windows XP 到 Windows 10.

4.自启过程无需人工干预,全自动无阻塞。

5.不能关闭UAC,如果这个都关了,我们就不用讨论了。

要实现以上3点,其实并不容易,XP容易实现自不必说,从Vista开始就不那么容易了。

有两个难点:

1. 以管理员身份开机自启。注册表实现不了,启动菜单目录也实现不了。因为即使设置了程序的兼容性以管理员身份运行,但弹出的那个UAC确认框谁来点呢?据我所知,用计划任务是目前唯一可以实现以管理员身份启动并且不需要UAC确认的。

2. 当以非管理员身份运行时,动态申请管理员权限,当然这个是需要UAC确认的。

用来做一些人工设置的时候,这时候人是在电脑旁边的。比如设置开机自启,取消开机自启。

这个解决方案比较简单,实例A用RunAs方式申请管理员权限启动一个新实例B,传入命令行参数,B执行完自动结束。即使申请启动失败,A也可以继续存活,想要申请过程无阻塞就新开一个线程来做。

但有一个问题,B有没有启动成功?用户有没有在UAC确认时允许?即使是用户确认了,B成功在计划任务创建了开机以管理员身份启动。但是A依然无法判断是否成功设置了开机自启,托盘无法正确的为用户指示开机自启状态。有人会说查询一下计划任务里有没有我们创建的任务就行了,很可惜,因为A没有管理员权限,所以无法查询。

我其实也搞不懂,微软为什么查询计划任务都需要管理员权限。

既然B都有管理员权限了,它返回一个ExitCode不就行了。当然这样可以,但是开机自启是敏感操作,很可能被杀软干掉,这样我们的开机自启状态指示就变得不可靠。

有一个办法,B既然已经有了管理员权限,让它启动一个C,C就是一个完全有管理员权限的实例,B自我关闭,返回一个ExitCode给A,A收到通知也关闭,一切不就解决了嘛。这就是我的方案。

当然也可以不启动C,B关闭A,B继续以管理员权限运行,但是如何返回状态给A让A自我结束,或者B干掉A,就不是一个ExitCode可以解决的了,通讯或查找程序可能变得复杂。

下面附上创建、查询、删除计划任务的代码:

Public Class Form1Private Const TASK_TRIGGER_LOGON = &H9Private Const TASK_ACTION_EXEC = &H0Private Const TASK_CREATE = &H2Private Const TASK_CREATE_OR_UPDATE = &H6Private Const TASK_RUNLEVEL_HIGHEST = &H1Private Const TASK_LOGON_GROUP = &H4Private Const TASK_LOGON_NONE = &H0Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.LoadEnd SubPublic Function CreateOrUpdateTask(ByVal strTaskName As String, ByVal strAuthor As String, ByVal strTaskDescription As String, ByVal strPath As String, ByVal strWorkingDir As String, Optional ByVal strArguments As String = "", Optional ByVal bUseHighestSecLevel As Boolean = True) As LongDim objService As ObjectobjService = CreateObject("Schedule.Service")objService.Connect()Dim objTaskFolder As ObjectobjTaskFolder = objService.GetFolder("\")Dim objTaskDef As ObjectobjTaskDef = objService.NewTask(0)Dim objPrincipal As ObjectobjPrincipal = objTaskDef.principalWith objPrincipal.LogonType = 1.RunLevel = TASK_RUNLEVEL_HIGHESTEnd WithDim colTriggers As ObjectDim objTrigger As ObjectDim colActions As ObjectDim objAction As ObjectDim objInfo As ObjectDim objSettings As ObjectcolTriggers = objTaskDef.TriggersobjTrigger = colTriggers.Create(TASK_TRIGGER_LOGON)objTrigger.Enabled = TruecolActions = objTaskDef.ActionsobjAction = colActions.Create(TASK_ACTION_EXEC)objAction.Path = strPathobjAction.WorkingDirectory = strWorkingDirobjAction.Arguments = strArgumentsobjInfo = objTaskDef.RegistrationInfoobjInfo.Author = strAuthorobjInfo.Description = strTaskDescriptionobjSettings = objTaskDef.SettingsWith objSettings.Enabled = True.Hidden = False.StartWhenAvailable = True.DisallowStartIfOnBatteries = False.StopIfGoingOnBatteries = False.AllowHardTerminate = FalseEnd WithTryIf bUseHighestSecLevel ThenobjTaskFolder.RegisterTaskDefinition(strTaskName, objTaskDef, TASK_CREATE_OR_UPDATE, "Administrators", , TASK_LOGON_GROUP)ElseobjTaskFolder.RegisterTaskDefinition(strTaskName, objTaskDef, TASK_CREATE_OR_UPDATE, , , TASK_LOGON_NONE)End IfCatch ex As ExceptionReturn Err.NumberEnd TryCreateOrUpdateTask = 0objService = NothingobjInfo = NothingobjTaskFolder = NothingobjTaskDef = NothingobjPrincipal = NothingEnd FunctionPublic Function DeleteTask(ByVal strTaskName As String) As LongDim objService As ObjectDim objTaskFolder As ObjectTryobjService = CreateObject("Schedule.Service")objService.Connect()objTaskFolder = objService.GetFolder("\")objTaskFolder.DeleteTask(strTaskName, 0)Catch ex As ExceptionReturn Err.NumberEnd TryobjService = NothingobjTaskFolder = NothingDeleteTask = 0End FunctionPublic Function TaskAvailable(taskName) As BooleanDim service = CreateObject("Schedule.Service")Call service.Connect()' Get the task folder that contains the tasks. Dim rootFolderrootFolder = service.GetFolder("\")Dim taskCollectiontaskCollection = rootFolder.GetTasks(0)Dim numberOfTasksnumberOfTasks = taskCollection.CountIf numberOfTasks = 0 ThenDebug.Print("No tasks are registered.")ElseDebug.Print("Number of tasks registered: " & numberOfTasks)Dim registeredTaskFor Each registeredTask In taskCollectionDim name As String = registeredTask.NameDebug.Print("Task Name: " & name)Dim taskStateSelect Case registeredTask.StateCase "0"taskState = "Unknown"Case "1"taskState = "Disabled"If (name = taskName) ThenTaskAvailable = FalseExit FunctionEnd IfCase "2"taskState = "Queued"Case "3"taskState = "Ready"Case "4"taskState = "Running"Case ElsetaskState = "Unknown"End SelectIf (name = taskName) ThenTaskAvailable = TrueExit FunctionEnd IfDebug.Print(" Task State: " & taskState)NextEnd IfTaskAvailable = FalseEnd FunctionPrivate Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.ClickMsgBox(CreateOrUpdateTask("Test", Interaction.Environ("USERDOMAIN") & "\" & Interaction.Environ("USERNAME"), "a Test Task", Application.ExecutablePath, Application.StartupPath, "", True))End SubPrivate Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.ClickMsgBox(DeleteTask("Test"))End SubEnd Class

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。