【问题标题】:Finding the reason for a UAC elevation in Windows 7在 Windows 7 中查找 UAC 提升的原因
【发布时间】:2013-12-08 15:34:33
【问题描述】:

我继承了一个应用程序的维护,该应用程序在运行时偶尔会导致出现 UAC 管理员提升(您希望允许这个吗?)对话框。对我来说,首先要尝试的显然是“打开 UAC 日志记录”,重新运行应用程序以显示对话框,然后在日志中找到条目,例如“2013-11-23-19: 10:03 [MyApplication] 尝试写入注册表项 [MyRegistryKey]。需要管理员授权”,然后采取措施解决问题,以便在使用应用程序时对话框不会出现。

但是,有些人在 2008/09 年发布了有关与 Vista 相关的 UAC 日志记录的问题,答案类似于“UAC 不记录,但对于未来版本来说这将是一个很棒的功能”。 UAC 日志记录是否曾经在 Windows 7 中或作为补丁版本中实施过?如果没有,是否有常用的替代技术?

【问题讨论】:

  • 您是这个应用程序的开发者吗?如果没有,那你就来错地方了。超级用户回答与编程无关的计算机管理问题。
  • 谢谢,本。我从开发人员的角度来看这个,是的。我不熟悉该应用程序,但如果我知道出了什么问题,那么我可以访问代码并可能立即找到解决方案。你是这个意思吗?
  • 所以你打算从源代码重建应用程序?是的,这很重要,不是您从哪里获得代码,而是您正在更改代码,而不是简单地找到有问题的注册表项并更改其权限。
  • 它必须进行进程外调用,因为必须在启动进程之前完成提升。一旦进程存在,它就会与控制权限(包括 UAC 提升级别)的登录令牌永久关联。
  • 好的,谢谢。这就说得通了。如果我可以从日志记录中找到有关进程外调用的一些详细信息,那么这将使我的任务更有效率。我目前的调查可能是一次性的,但我可以看到未来还有其他类似的“海拔”案例。

标签: windows logging windows-7 uac


【解决方案1】:

我最终解决了这个问题。这就是发生的事情。

1) 我尝试了 Ben 关于使用 sysinternals 工具的建议。看起来有用的工具是

依赖行者 流程浏览器 进程监控器

它们每个都提供了很多关于正在发生的事情的信息,我可以看到这些将需要成为许多(如果不是大多数)Windows 问题的第一个呼叫端口。但是,在我的情况下,我双击该应用程序并获得了 UAC 用户 ID/密码对话框,但随后发现在对话框出现之前,工具并未写入太多信息。

在尝试解决 UAC 问题时,消化 Microsoft Press Windows Internals 书籍的内容似乎也很有用。

2) 我尝试使用应用程序兼容性工具包,但无论是在 XP(它工作的地方)还是 Windows 7(两者都使用标准用户,都显示了 UAC 对话框和管理员用户,它工作),但它显示程序没有问题

3) 然后我煞费苦心地尝试从头开始重新创建应用程序,从一个空项目开始,然后一点一点地复制文件和设置。在每个阶段,我检查了应用程序是否会在不显示 UAC 对话框的情况下启动。

最终我应用了一个更改,这导致 UAC 对话框浮出水面。这是一个 VB6 应用程序,我在 Project、Properties、Make 对话框中更改了“应用程序标题”和“产品名称”。每个字段的先前(失败)值为“ApplicationName Update”。为了使应用程序在没有 UAC 提升的情况下工作,我必须做的是删除“更新”这个词。

正如 Ian 上面所建议的,看起来 UAC 启发式正在被应用,并且被应用于 exe 中的值。我看到 Windows Internals 这本书确实谈到了在决定是否提升时扫描 exe 中的字节序列。

4) 总而言之,对我有用的方法是一点一点地重新组装应用程序,看看在哪个阶段触发了 UAC 对话框。一旦发生这种情况,了解 Ian 在上一个答案中给出的四个原因就变得很重要了。

5) 我应该指出,我已经通过删除启发式方法中标记的内容来解决问题,但没有考虑 Ian 建议的替代方案:“asInvoker”。这可能是最好的尝试,而不是花时间在(旧版)应用程序中解决问题。

【讨论】:

    【解决方案2】:

    找到日志中的条目,例如“2013-11-23-19:10:03 [MyApplication] 尝试写入注册表条目 [MyRegistryKey]。需要管理员授权”

    UAC 不是这样工作的。 Windows 不监视应用程序,并根据活动决定它下次应该在提升的情况下运行。

    在这方面,Windows 7 的行为与 Windows XP 大致相同。如果您的应用以标准用户身份运行,请尝试写入:

    HKLM\Software\Cotoso\Litware
    

    您的应用程序将收到Access Denied 错误消息。

    除非为有问题的应用启用文件和注册表虚拟化

    不幸的是,大多数应用程序都写得不好。大多数应用程序在 Windows 2000 或 Windows XP 上以标准用户身份运行时,都会严重崩溃。自 1999 年以来,作为 Windows 徽标要求的一部分,Microsoft 要求开发人员在以标准用户身份运行时测试他们的应用程序。几乎没有人这样做。

    这就是为什么从 Windows Vista 开始,Microsoft 添加了一项功能,让您的有缺陷的应用程序认为它已成功写入 HKLMProgram Files强>。如果写入失败,如果用户是管理员,成功,Windows 将重新发出写入操作,但这次将其重定向到会成功的地方。例如:

    writes to 
       HKLM\Software
    are redirected to 
       HKCU\<User SID>_Classes\VirtualStore\Machine\Software
    
    writes to 
       C:\Program Files
    are redirected to 
       C:\Users\Westwell\AppData\Local\VirtualStore\Program Files
    

    这些重定向机制都不会导致您的应用程序在下次启动时被提升。这两个功能都是临时的兼容性黑客。您可以通过在应用程序的程序集清单中添加 requestedExecutionLevelasInvoker 来告知 Windows 您正确编写了应用程序,选择退出文件和注册表虚拟化:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> 
       <assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="client" type="win32"/> 
    
       <description>Westwell Contoso</description> 
    
       <!-- Disable file and registry virtualization -->
       <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
          <security>
             <requestedPrivileges>
                <requestedExecutionLevel level="asInvoker" uiAccess="false"/>
             </requestedPrivileges>
          </security>
       </trustInfo>
    </assembly>
    

    现在只消除了为什么有时写入可以成功的旁白,即使用户是标准用户。

    UAC 提升何时发生

    应用程序可能会在启动时提示提升有五个原因:

    1. 您表明您的应用程序需要以管理员身份运行。

      如果您的应用需要以管理员身份运行,并且没有管理员身份就无法执行任何有用的功能,那么您可以将您的应用显示为requireAdministrator(而不是asInvoker):

      <description>Westwell Contoso</description> 
      
      <!-- Disable file and registry virtualization -->
      <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
         <security>
            <requestedPrivileges>
               <requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
            </requestedPrivileges>
         </security>
      </trustInfo>
      

      如果是这种情况,那么应用程序将始终以管理员身份运行。所以不是这样的。

    2. 您表明您的应用程序以管理员身份运行仅当用户实际上是管理员。

      RegEdit 等应用程序可以作为标准用户正常运行,它们不需要提升。但如果用户实际上是管理员 RegEdit 可以提示提升到用户的完整管理员权限。这通过将您的应用程序标记为highestAvailable(而不是asInvokerrequireAdministrator)来完成:

      <description>Westwell Contoso</description> 
      
      <!-- Disable file and registry virtualization -->
      <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
         <security>
            <requestedPrivileges>
               <requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
            </requestedPrivileges>
         </security>
      </trustInfo>
      

      如果是这种情况,您的应用会提示管理员提升权限,但不会提示标准用户。这不可能是原因,因为您的应用程序没有清单。

    3. 兼容性选项将应用程序标记为以管理员身份运行

      用户可以选择标记应用程序,使其提示提升:

      此复选框(和其他复选框)的状态存储在注册表中:

      HKCU\Software\Microsoft\WindowsNT\CurrentVersion\AppCompatFlags\Layers
      

      对于“所有用户”下:

      HKLM\Software\Microsoft\WindowsNT\CurrentVersion\AppCompatFlags\Layers
      

      此选项可以是每用户或每台机器。因此,有些用户可能会看到提升提示,而其他用户则不会。这可能是您的问题的根源。

    4. Installer detection heuristics

      默认情况下,Windows 会尝试识别应用程序可能是安装程序(例如setup.exeinstall.exeupdate.exe)并提示用户升级。可以通过组策略禁用此功能,策略名称为User Account Control: Detect application installations and prompt for elevation

    轻松修复

    简单的解决方法是简单地将您的应用程序标记为asInvoker。这将禁用启发式。

    之后,它必须是机器上的兼容性设置(HKCU 或 HKLM 中的 AppCompatFlags)。

    阅读奖励

    【讨论】:

    • 谢谢,伊恩。我最终明白了这一点。您的完整列表确实包含此问题的正确答案(“UAC 启发式”导致 Windows 认为该应用程序是安装程序),因此我将其标记为答案。我还在单独的答案中添加更多细节,以防这对其他人有用。
    猜你喜欢
    • 2011-02-11
    • 2011-03-19
    • 2011-11-18
    • 1970-01-01
    • 1970-01-01
    • 2011-01-17
    • 2011-02-20
    • 1970-01-01
    • 2011-03-01
    相关资源
    最近更新 更多