如何在启动时在 Windows 7 上以管理员身份自动运行程序?

Posted

技术标签:

【中文标题】如何在启动时在 Windows 7 上以管理员身份自动运行程序?【英文标题】:How to run a program automatically as admin on Windows 7 at startup? 【发布时间】:2011-07-22 14:39:00 【问题描述】:

我创建了自己的家长控制应用来监控我孩子的活动。该应用程序的唯一 GUI 是任务栏图标。该程序以管理员身份安装。我希望这个程序在 Windows 启动时以管理员用户身份自动启动,这样标准用户就不能从任务管理器中杀死它。

我可以在以下位置创建注册表项:

HKLM\Software\Microsoft\Windows\CurrentVersion\Run

使其在 Windows 启动时自动运行。问题是程序是以登录(标准)用户身份启动的。

如何让它在提升模式下运行?这在Win7中是否可能?

【问题讨论】:

一个可能更大的问题是,如果没有登录用户,程序根本就启动。这是一种在登录时运行程序的机制(如 Unix 上的 .login 脚本),而不是在引导时运行(如某些 /etc/rc/... 脚本)。 @Kaz:在这个问题的上下文中,这似乎不是问题(除非试图观察孩子与登录屏幕的交互) 【参考方案1】:

您需要将其插入任务调度程序,以便在用户登录后启动它,使用对系统具有管理访问权限的用户帐户,该帐户具有该帐户启动的进程的最高权限。

这是用于在以普通用户身份登录时自动启动具有管理权限的进程的实现。

我用它来启动需要提升权限才能正常工作的“Open*** GUI”帮助程序进程,因此无法从注册表项正确启动。

从命令行,您可以根据您想要完成的 XML 描述创建任务;所以例如我们有这个,从我的系统中导出,当我登录时它将以最高权限启动记事本:

<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
  <RegistrationInfo>
    <Date>2015-01-27T18:30:34</Date>
    <Author>Pete</Author>
  </RegistrationInfo>
  <Triggers>
    <LogonTrigger>
      <StartBoundary>2015-01-27T18:30:00</StartBoundary>
      <Enabled>true</Enabled>
    </LogonTrigger>
  </Triggers>
  <Principals>
    <Principal id="Author">
      <UserId>CHUMBAWUMBA\Pete</UserId>
      <LogonType>InteractiveToken</LogonType>
      <RunLevel>HighestAvailable</RunLevel>
    </Principal>
  </Principals>
  <Settings>
    <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
    <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
    <StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
    <AllowHardTerminate>true</AllowHardTerminate>
    <StartWhenAvailable>false</StartWhenAvailable>
    <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
    <IdleSettings>
      <StopOnIdleEnd>true</StopOnIdleEnd>
      <RestartOnIdle>false</RestartOnIdle>
    </IdleSettings>
    <AllowStartOnDemand>true</AllowStartOnDemand>
    <Enabled>true</Enabled>
    <Hidden>false</Hidden>
    <RunOnlyIfIdle>false</RunOnlyIfIdle>
    <WakeToRun>false</WakeToRun>
    <ExecutionTimeLimit>PT0S</ExecutionTimeLimit>
    <Priority>7</Priority>
  </Settings>
  <Actions Context="Author">
    <Exec>
      <Command>"c:\windows\system32\notepad.exe"</Command>
    </Exec>
  </Actions>
</Task>

它由管理员命令提示符注册,使用:

schtasks /create /tn "start notepad on login" /xml startnotepad.xml

这个答案真的应该转移到其他 stackexchange 站点之一,因为它本身实际上并不是一个编程问题。

【讨论】:

非常感谢您提供的信息。我会尝试一下,看看它是如何工作的。 “用户登录后”不是“Windows 启动”。 是的,但在您登录之前,您实际上并没有可以使用的桌面 @Petesh 您是如何让基于 UI 的应用程序以这种方式运行的?当我使用任务计划时,我可以运行一个应用程序,但我看不到它的 UI。 我想知道是否有任何方法可以通过注册表更改来做到这一点。如果是,甚至可以在没有(之前)引导操作系统的情况下安排它。【参考方案2】:
schtasks /create /sc onlogon /tn MyProgram /rl highest /tr "exeFullPath"

【讨论】:

它不会在会话 0 中运行并且您将无法看到 UI 吗?我想要同样的东西,它做到了,但它在我的用户名下的会话 0 中运行,因此 UI 不可用 "onlogon" 不是 Windows 启动。 在 Windows 7 上,它在用户的桌面上运行。用 calc.exe 试试吧。 @Cyber​​Shadow 我正在尝试使用需要管理员权限的应用程序来执行此操作。我在任务管理器中看到它,但它的 UI 不可见。 感谢您的回答。我们的 IT 部门最近通过组策略对我们公司域中的所有计算机强制启用 UAC。不幸的是,如果您以管理员身份运行命令提示符,您的驱动器映射将不可用。以前,我设置了一个简短的 .bat 文件,以便通过“运行”注册表项在登录时运行,该注册表项将设置我的所有驱动器映射。我需要一种在启动时为 SYSTEM 帐户运行类似 .bat 的方法。 “schtasks /ru SYSTEM”正是我所需要的。【参考方案3】:

这是不可能的。 但是,您可以创建在管理用户下运行的服务。

该服务可以在启动时自动运行并与您现有的应用程序通信。 当应用程序需要以管理员身份做某事时,它可以请求服务为它做这件事。

请记住,多个用户可以同时登录。

【讨论】:

非常感谢您的及时答复。实际上,我确实尝试从 Window Service 运行该应用程序,但无法使其工作。我可以在任务管理器中看到该程序(作为 SYSTEM 用户),但该图标未显示在任务栏中。当我将 Verb="runas" 添加到 StartInfo 时,出现异常“没有足够的存储空间来处理此命令”。我想这可能是因为没有办法弹出一个 GUI 来要求用户确认。 @miliu:服务无法与用户交互。你需要制作两个相互通信的程序。【参考方案4】:

我认为使用任务调度程序来自动启动程序不是很友好,有时它对我有副作用(例如未添加程序的托盘图标)。

为了解决这个问题,我制作了一个名为 Elevated Startup 的程序,它首先以管理员权限重新启动自身,然后启动目录中的所有文件。由于 Elevated Startup 现在已提升,因此它随后启动的所有程序也被授予管理员权限。该目录位于经典启动目录旁边的开始菜单上,并且工作方式非常相似。

当程序重新启动时,您可能会遇到一个 UAC 对话框,具体取决于您的 UAC 设置。

您可以在这里获取程序:https://stefansundin.github.io/elevatedstartup/

【讨论】:

因为这是最近的答案,我想添加评论。我正在尝试使用 Windows 10 上的任务调度程序对我的程序执行与 OP 相同的操作。但是,它将我的程序作为后台进程启动,这不是我想要的。我希望我的应用程序以管理员身份正常启动。您的计划是否考虑到这一点? 我相信会的。该程序应该像您右键单击快捷方式并使用“以管理员权限运行”一样启动。如果它的行为不符合您的要求,我很乐意进一步了解您的用例并让该程序为您工作。【参考方案5】:

将您的应用程序的兼容性设置为管理员(Run theprogram as an administrator)

将其插入task scheduler,然后关闭UAC

【讨论】:

我也遇到了同样的问题。用户界面不可见。任何帮助 @SenthilMuthiah 那是因为您的程序作为后台进程而不是应用程序运行。同样的事情发生在我身上。【参考方案6】:

您可以通过在以管理员身份运行时通过TaskSchedler library 安装任务来完成此操作。鉴于您的相关问题,我在这里假设 .NET/C# 是一种合适的平台/语言。

这个库让您可以精细地访问任务计划程序 API,因此您可以通过调用 schtasks 来调整您无法通过命令行设置的设置,例如启动的优先级。作为家长控制应用程序,您会希望它的启动优先级为 0(最大值),schtasks 默认创建的优先级为 7。

下面是安装正确配置的启动任务以在登录时无限期地以管理员身份运行所需应用程序的代码示例。此代码将为运行它的进程安装一个任务。

/*
Copyright © 2017 Jesse Nicholson  
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

/// <summary>
/// Used for synchronization when creating run at startup task.
/// </summary>
private ReaderWriterLockSlim m_runAtStartupLock = new ReaderWriterLockSlim();

public void EnsureStarupTaskExists()

    try
    
        m_runAtStartupLock.EnterWriteLock();


        using(var ts = new Microsoft.Win32.TaskScheduler.TaskService())
        
            // Start off by deleting existing tasks always. Ensure we have a clean/current install of the task.
            ts.RootFolder.DeleteTask(Process.GetCurrentProcess().ProcessName, false);

            // Create a new task definition and assign properties
            using(var td = ts.NewTask())
            
                td.Principal.RunLevel = Microsoft.Win32.TaskScheduler.TaskRunLevel.Highest;
                // This is not normally necessary. RealTime is the highest priority that
                // there is.
                td.Settings.Priority = ProcessPriorityClass.RealTime;
                td.Settings.DisallowStartIfOnBatteries = false;
                td.Settings.StopIfGoingOnBatteries = false;
                td.Settings.WakeToRun = false;
                td.Settings.AllowDemandStart = false;
                td.Settings.IdleSettings.RestartOnIdle = false;                    
                td.Settings.IdleSettings.StopOnIdleEnd = false;
                td.Settings.RestartCount = 0;                    
                td.Settings.AllowHardTerminate = false;
                td.Settings.Hidden = true;
                td.Settings.Volatile = false;
                td.Settings.Enabled = true;
                td.Settings.Compatibility = Microsoft.Win32.TaskScheduler.TaskCompatibility.V2;
                td.Settings.ExecutionTimeLimit = TimeSpan.Zero;

                td.RegistrationInfo.Description = "Runs the content filter at startup.";

                // Create a trigger that will fire the task at this time every other day
                var logonTrigger = new Microsoft.Win32.TaskScheduler.LogonTrigger();
                logonTrigger.Enabled = true;                    
                logonTrigger.Repetition.StopAtDurationEnd = false;
                logonTrigger.ExecutionTimeLimit = TimeSpan.Zero;
                td.Triggers.Add(logonTrigger);

                // Create an action that will launch Notepad whenever the trigger fires
                td.Actions.Add(new Microsoft.Win32.TaskScheduler.ExecAction(Process.GetCurrentProcess().MainModule.FileName, "/StartMinimized", null));

                // Register the task in the root folder
                ts.RootFolder.RegisterTaskDefinition(Process.GetCurrentProcess().ProcessName, td);
            
                        
    
    finally
    
        m_runAtStartupLock.ExitWriteLock();
    

【讨论】:

这是一个漂亮的库——不过只是一个注释。大多数时候不需要“实时”运行某些东西。而且你永远不会处理 td 感谢您为我指明这个方向。 @Sonic 感谢有关处置的提示。你是对的,“实时”通常不是必需的。此代码是从我编写的开源 Web 内容过滤器中复制的,因此有必要尽快启动它。【参考方案7】:

我编写的一个程序farmComm 可以解决这个问题。我将它作为开源和公共领域发布。

如果它不符合您的标准,您可以轻松地对其进行更改。

农场通讯:

在启动时在服务下运行,在用户登录或注销时继续运行。 在会话 0 中 在用户“NT AUTHORITY\SYSTEM”下。 产生任意进程(您选择); 也在会话 0 中 “不可见”或不显示任何用户界面/GUI 可以访问图形硬件(例如 GPU)。 响应活动会话,即使它发生变化,包括安全桌面。是这样的: 仅在用户空闲 8.5 分钟后生成进程 当用户从空闲状态恢复时终止生成

源脚本可在此处获得:

https://github.com/r-alex-hall/farmComm

【讨论】:

【参考方案8】:

您还应该考虑以管理员级别用户或服务身份运行进程的安全隐患。如果任何输入未正确验证,例如它是否正在侦听网络接口。如果此输入的解析器未正确验证,则可能会被滥用,并可能导致利用提升用户身份运行代码的漏洞。在 abatishchev 的示例中,这应该不是什么大问题,但如果要在企业环境中部署,请在大规模部署之前进行安全评估。

【讨论】:

有些程序需要提升,不一定会出现安全问题。例如,监控系统温度并将其显示在通知区域中的程序需要提升才能访问硬件,并且需要自动运行,但安全性对它来说没有实际意义。 我不同意运行这样的软件并不重要。我使用过软件,只是我同意您的观点,即某些软件需要提升的权限才能运行,但我不同意您认为在提升的级别上运行某些类型的软件并不重要。我使用的软件与您所描述的完全一样,是作为 root/admin 或提升用户在系统中站稳脚跟的。从那里,您可以访问该系统上具有该特权级别的任何其他软件或服务。如果不在该系统上,您可以使用该权限级别转到网络上的另一个系统。 是的,显然这可以被滥用,但这需要故意滥用(就像你说的那样)。我说的是受信任的用户和受信任的程序。不管你怎么看,有些程序需要提升。自从 UAC 以来,这些需要自动运行的程序一直是一个巨大的痛苦,即使是使用服务或计划任务的程序也很少能正常工作,需要各种变通方法才能(尝试)开始工作,而这只是最终成为一个更大的安全问题。 ?【参考方案9】:

我认为任务调度程序将是矫枉过正(恕我直言)。 win7有一个启动文件夹。

C:\Users\miliu\AppData\Roaming\Microsoft\Windows\开始菜单\程序\启动

只需为您的自动启动应用程序创建一个快捷方式,编辑快捷方式的属性并让它始终以管理员身份运行。

您的孩子当然可以关闭它,但如果他们精通技术,他们总能找到一种方法来阻止您。我知道我年轻的时候做过。

祝你好运!

【讨论】:

这行不通。 Windows 将忽略设置为以管理员身份运行的启动快捷方式。 真的吗?你有没有尝试过?因为它在我这边工作正常。我必须以管理员身份自动启动我的 LogitechSoundManager 才能使环绕声正常工作... 我也有这个问题,即使启动文件夹中的快捷方式已勾选“以管理员身份运行”选项,但启动时仍无法加载。有谁知道解决这个问题的方法吗? Cyber​​Shadow 是正确的,计算机的 UAC 已关闭。管理员启动快捷方式不起作用...必须使用任务调度程序 我发现至少在 Windows 10 上这不起作用。正如@vladimir-panteleev 所说,Windows 似乎只是忽略了它。

以上是关于如何在启动时在 Windows 7 上以管理员身份自动运行程序?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Windows XP 上以管理员身份运行另一个应用程序

如何在 Mac Pro 上以管理员身份运行终端

这是服务的实际用途吗?

程序启动时如何请求管理员权限?

如何在官方 docker php 映像上以非 root 用户身份运行 composer

检测 Java 应用程序是不是以 Windows 管理员身份运行