关闭指定程序的 UAC 通知

在启动某些 Windows 程序时会弹出 UAC (用户账户控制)确认窗口,这表示该程序需要管理员权限来运行。用户可以选择批准或拒绝。

运行 Listary 每次都要弹出 UAC 通知

运行 Listary 每次都要弹出 UAC 通知

以管理员身份运行 Everything

以管理员身份运行 Everything

用户可以通过控制面板 > 系统和安全 > 更改用户帐户控制设置来更改 UAC 的行为。将滑块移动到从不通知便可以全局关闭系统 UAC 通知。Windows 并没有提供 UAC 通知的白名单功能。

UAC 设置

UAC 设置

程序触发 UAC 弹窗的方式基本分两种:

  1. 在程序清单 (Manifest) 中设置 requestedExecutionLevel

    xml<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
      <security>
        <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
          <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
        </requestedPrivileges>
      </security>
    </trustInfo>
  2. 使用 ShellExecute() 启动程序,将 lpOperation 参数设置为 "runas"

针对第一种情况,可以通过简单注册表操作来实现 UAC 静默。Listary 属于第一种情况,以它为例。在注册表编辑器中访问如下路径:

HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers

新建字符串值,数据名称为程序的路径,比如 D:\Apps\Listary\Listary.Service.exe, 数据值为 RunAsInvoker。其含义为忽略程序清单中的 requestedExecutionLevel,以程序调用者的权限运行。因此也就不会弹出 UAC 通知了。

该方法的缺点是,程序并没有获得管理员权限,可能会导致一些功能无法正常使用。

另外,也可以使用 NirSoft 的 AppCompatibilityView 图形工具来进行该操作。

对于第二种情况,则需要借助于任务计划程序。其原理为,新建一个不包含任何触发条件的任务,并设置为以最高权限运行,用户使用命令来触发该任务。由于任务本身具有管理员权限,因此不会弹出 UAC 通知。

用户可以在控制面板 > 管理工具 > 任务计划程序中以交互方式创建任务,或者使用命令行创建。

请在以管理员身份运行的命令行中执行下面的命令。
  1. 使用 schtasks 命令:

    cmdrem 由于 sctasks 命令不支持创建无触发器的任务,因此设置了一个无效执行时间
    schtasks /create /tn "RunAsAdmin\Everything" /tr "D:\Apps\Everything\everything.exe" /rl HIGHEST /sc once /st 00:00
  2. 使用 PowerShell 的 Register-ScheduledTask 命令:

    powershell# 不能省略 -UserId 参数,且必须与当前登入用户一致,否则程序无法在桌面上显示
    Register-ScheduledTask -TaskName "RunAsAdmin\Everything" -Action (New-ScheduledTaskAction -Execute "D:\Apps\Everything\everything.exe") -Principal (New-ScheduledTaskPrincipal -UserId ([System.Security.Principal.WindowsIdentity]::GetCurrent().Name) -RunLevel Highest)

使用下面的命令以管理员身份运行 Everything:

cmdschtasks.exe /run /tn "RunAsAdmin\Everything"

也可以将以上命令创建为快捷方式运行。