【问题标题】:Can I get rid of UAC warning when autostart with Windows?使用 Windows 自动启动时,我可以摆脱 UAC 警告吗?
【发布时间】:2016-09-14 20:59:37
【问题描述】:

我用 c# 编写了一个小程序,可以帮助我公司在许可证之间切换。它是一个带有不同选项的菜单的托盘图标。

它会更改环境变量,并且需要在其清单中具有提升的权限。

这意味着每次程序启动时都会显示 UAC 警告,这并不理想,因为在 Windows 启动时让程序自动启动会非常好,而不会一直显示警告。

有什么好的方法吗?

是否可以:

  • 在没有提升权限的情况下运行程序并且只获取 UAC 当我调用函数更改变量时发出警告。
  • 更改 没有管理员权限的环境变量。
  • 以编程方式将程序添加到“白名单”(虽然更现实,但手动添加)

我知道 UAC 是用来防止恶意软件的,但如果能以一种使我能够在 Windows 启动时启动程序的方式来解决这个问题,那就太好了。

我无法解决这个问题的任何灵丹妙药。

有什么建议吗?

【问题讨论】:

  • 不是每个病毒、木马和恶意软件都会利用这个吗?
  • 解决这个问题的正常方法是您拥有一个 Windows 服务,该服务以您的程序与之对话的系统权限运行,在安装阶段设置。
  • 是的,我知道 UAC 就是因为这个原因。但是肯定有没有警告的具有管理员权限的软件,对吗??
  • 使用安全证书,并可选择将程序放在 Program Files 文件夹中。
  • 程序启动与否,运行时不能“升级”。但是,您可以做的是以管理员身份启动程序的第二个副本,并使用一些命令行参数告诉它完成工作然后退出。

标签: c# winforms uac


【解决方案1】:

解决此问题的正常方法是您拥有一个以系统权限运行的 Windows 服务,该服务将为您设置环境变量。

您需要让安装程序安装该服务并将其设置为自动启动。然后,您的托盘应用程序将需要通过某种进程间通信(如 WCF)与服务进行通信,然后托盘程序可以发送更改变量的请求,并且服务可以执行这些更改。


处理这个问题的另一种方法是启动你的程序,然后当你需要做一些需要 UAC 权限的事情时,你 launch a new copy of your program as an administrator 并传入命令行参数,告诉它完成你需要完成的工作然后退出。你也可以让你的程序检查它是否是管理员,如果它已经被提升,它可以跳过启动新副本的步骤。

【讨论】:

    【解决方案2】:

    您需要做的是将许可证信息移动到所有用户都可以写入的位置:

    • 用户自己的环境变量
    • %CSIDL_COMMON_APPDATA%(例如C:\ProgramData,所有用户都可以写入)
    • HKEY_CURRENT_USER

    理想的解决方案是写入一个通用的机器范围的位置:

    • %CSIDL_COMMON_APPDATA%(例如C:\ProgramData
    • HKEY_LOCAL_MACHINE/软件/Contoso/许可证
    • C:\Program Files\Contoso\License\license.txt

    旧版软件无法更改

    但假设有许多现有的不可更改的应用程序无法更改以查看其他任何地方,但您可以更改许可证信息的环境变量(在你打了那个设计者之后):

    • 将许可信息写入用户自己的环境变量中

    您的切换工具将调用:

    SetEnvironmentVariable("ContosoLicenseInfo", "V2h5IGFyZSB5b3UgZGVjb2RpbmcgdGhpbmdzIHRoYXQgZG9uJ3QgYmVsb25nIHRvIHlvdT8=");
    

    在 Windows XP 下你会做什么

    所有这些都与 UAC 有关。你必须问自己:

    在 Windows XP 下我会做什么?

    如果没有 UAC,并且用户作为标准用户运行,您的许可证切换工具会做什么?

    • 它会在启动时严重崩溃吗?
    • 它会在用户尝试使用它时立即崩溃吗?
    • 会以礼貌的方式失败吗?
    • 它会在启动时显示一条消息说:“抱歉,没有。”

    在 Windows 7 下你会做什么?

    更妙的是,您必须问一下您会为在 Windows 7 下运行的用户做些什么?一个标准用户登录,你在他们的启动组中有一个声称需要管理权限的程序。

    用户在登录时需要找管理员来运行您的工具吗?这不会飞。

    • 如果您坚决反对使用每个用户的位置。
    • 如果您坚决反对使用所有用户都可以写入的公共位置

    然后将您的工具更改为无需用户权限即可运行。

    只有当用户去做某事时,你才需要管理员权限。

    检查用户是否为管理员:

    Boolean IsUserAnAdmin()
    {
        PSID administratorsGroup;
        administratorsGroup = AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0);
    
        Boolean result = CheckTokenMembership(0, administratorsGroup);
        FreeSid(administratorsGroup);
    }
    

    如果他们是管理员,您可以按如下方式执行操作。

    如果用户不是管理员,那么您将 UAC 盾牌放在 应用 按钮上。

    然后您以管理员身份重新启动您的工具:

    ShellExecute("runas", "C:\Program Files\Contoso\LicenseSwitcher.exe", ...); //the "runas" verb triggers elevation
    

    但是在 Windows 7 下你会怎么做

    如果 UAC 被禁用,UAC 的任何东西都不起作用。在这种情况下:您是标准用户,仅此而已。

    在这种情况下,最好转换为:

    • 默认许可证的机器范围位置
    • 如果您想自己选择每个用户的位置

    【讨论】:

      【解决方案3】:

      UAC 可以通过提醒 Windows 用户(并要求明确的操作)特定应用程序正在请求提升的权限来保护他们。如果可以从应用程序本身绕过它,那将变得毫无意义:)

      我假设您正在寻求全局更改环境变量,因为我相信您可以为当前进程更改它们而不会被提升。

      【讨论】:

      • 是的,我需要设置环境“系统变量”,因为我们使用的许可证管理软件是从那里读取的。
      • @motosson 系统变量似乎是许可信息的一个奇怪的地方。注册表或某种配置文件不是更合适吗?那么您甚至不必担心 UAC。
      • 问题是我们正在使用第三方许可证管理器,它正在从 env-vars 中读取信息。我们对此无能为力。
      猜你喜欢
      • 2012-10-28
      • 2020-01-10
      • 1970-01-01
      • 1970-01-01
      • 2011-12-15
      • 2011-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多