我们有一个C ++非托管应用程序似乎会导致UAC提示。它似乎发生在 Win7而不是Vista
不幸的是,UAC dlg是系统模式的,所以我无法附加调试器来检查它所在的代码,并且在msdev下运行(我们使用的是2008)在提升模式下运行。
我们在程序/ winmain的开头放了一个消息框,但它甚至没有那么远,所以显然这是在启动代码中。
什么能够如此早地导致UAC通知,以及我可以采取哪些其他措施来追踪原因?
修改
显然清单在这里是一个重要的问题,但它似乎没有帮助我 - 或者我可能没有正确配置清单文件。
有人可以提供示例清单吗?
此外,链接器/ UAC魔术是否会发现程序“可能”写入注册表并根据其设置其UAC要求?有些代码路径可能触发UAC,但是当UAC dlg出现时我们甚至都没有。
另一个奇怪的是,在启用UAC的Vista上似乎没有发生这种情况。
这是一个清单(我认为是自动生成的):
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level='asInvoker' uiAccess='false' />
</requestedPrivileges>
</security>
</trustInfo>
<dependency>
<dependentAssembly>
<assemblyIdentity type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*' />
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly>
<assemblyIdentity type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*' />
</dependentAssembly>
</dependency>
</assembly>
然后将这个添加到清单列表中以查看它是否有帮助
<?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="[removed for anonymity]"
type="win32"
/>
<description>
[removed for anonymity]
</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="x86"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges>
<requestedExecutionLevel
level="asInvoker"
uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
以下是使用ManifestViewer工具的实际EXE
- <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity version="1.0.0.0" processorArchitecture="x86" name="[removed]" type="win32" />
<description>[removed]</description>
- <dependency>
- <dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="x86" publicKeyToken="6595b64144ccf1df" language="*" />
</dependentAssembly>
</dependency>
- <dependency>
- <dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*" />
</dependentAssembly>
</dependency>
- <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
- <security>
- <requestedPrivileges>
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
似乎可能是由于我们的应用上的xp兼容性设置。我得测试一下。 (我们在安装程序中设置了这一点,因为某些声音驱动程序在win7上无法正常工作)
答案 0 :(得分:11)
Windows会根据各种条件(Understanding and Configuring User Account Control in Windows Vista中列出)自动提升应用程序:
在创建32位进程之前, 检查以下属性 确定它是否是一个 安装程序:
- 文件名包括“安装”,“设置”,“更新”等关键字
- 以下版本控制资源字段中的关键字:供应商,公司名称,产品名称,文件描述,原始文件名,内部名称和导出名称。
- 可执行文件中嵌入的并排清单中的关键字。
- 可执行文件中链接的特定StringTable条目中的关键字。
- 可执行文件中链接的RC数据中的关键属性。
- 可执行文件中的目标字节序列。
所有这些的最佳解决方案是create a manifest that prevents elevation,尽管重命名文件可能就足够了。
答案 1 :(得分:5)
如果您甚至没有使用主要功能,那么您的应用程序使用的DLL在其DllMain初始化中正在执行某项操作,或者您的应用程序具有请求提升的清单。
我认为您应该可以使用windbg进行远程调试;当显示提示时,您可以进入调试器并查看您的应用尝试执行的操作。
答案 2 :(得分:2)
我要检查的第一件事是应用程序清单。这是Windows在创建流程时首先要考虑的事情之一。它肯定会与UAC互动。
答案 3 :(得分:1)
在Windows 7(但不是Vista)上,如果您说应用程序需要XP兼容性设置,它也会提升。请参阅Is UAC on Win7 different than Vista? - 如果您不需要提升,但确实需要标记为XP compat,我认为您无法做任何事情。 OTOH,如果你不需要XP compat,请停止要求。
答案 4 :(得分:0)
Dependency Walker(depends.exe)wqs orignally写入以解决DLL问题,但其分析模式比这更有用。它可用于捕获有关进程创建的大量信息。特别要注意哪些DLL是必需的,以及在UAC提示时加载了哪些DLL会很有趣。 Depenceny Walker的输出也很可能明确地提到了UAC。