找到日志中的条目,例如“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 添加了一项功能,让您的有缺陷的应用程序认为它已成功写入 HKLM 或 Program 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
这些重定向机制都不会导致您的应用程序在下次启动时被提升。这两个功能都是临时的兼容性黑客。您可以通过在应用程序的程序集清单中添加 requestedExecutionLevel 或 asInvoker 来告知 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 提升何时发生
应用程序可能会在启动时提示提升有五个原因:
-
您表明您的应用程序需要以管理员身份运行。
如果您的应用需要以管理员身份运行,并且没有管理员身份就无法执行任何有用的功能,那么您可以将您的应用显示为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>
如果是这种情况,那么应用程序将始终以管理员身份运行。所以不是这样的。
-
您表明您的应用程序以管理员身份运行仅当用户实际上是管理员。
RegEdit 等应用程序可以作为标准用户正常运行,它们不需要提升。但如果用户实际上是管理员 RegEdit 可以提示提升到用户的完整管理员权限。这通过将您的应用程序标记为highestAvailable(而不是asInvoker 或requireAdministrator)来完成:
<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>
如果是这种情况,您的应用会提示管理员提升权限,但不会提示标准用户。这不可能是原因,因为您的应用程序没有清单。
-
兼容性选项将应用程序标记为以管理员身份运行。
用户可以选择标记应用程序,使其提示提升:
此复选框(和其他复选框)的状态存储在注册表中:
HKCU\Software\Microsoft\WindowsNT\CurrentVersion\AppCompatFlags\Layers
对于“所有用户”下:
HKLM\Software\Microsoft\WindowsNT\CurrentVersion\AppCompatFlags\Layers
此选项可以是每用户或每台机器。因此,有些用户可能会看到提升提示,而其他用户则不会。这可能是您的问题的根源。
-
Installer detection heuristics。
默认情况下,Windows 会尝试识别应用程序可能是安装程序(例如setup.exe、install.exe、update.exe)并提示用户升级。可以通过组策略禁用此功能,策略名称为User Account Control: Detect application installations and prompt for elevation。
轻松修复
简单的解决方法是简单地将您的应用程序标记为asInvoker。这将禁用启发式。
之后,它必须是机器上的兼容性设置(HKCU 或 HKLM 中的 AppCompatFlags)。
阅读奖励