Windows如何决定是否显示UAC提示?

在我的VB6应用程序中,我打开其他EXE文件。 我的应用程序运行没有任何UAC提示,但我有一个EXE,检查软件的更新。 这会提示UAC提示。 那么Windows如何决定是否显示UAC提示? 我看到了这个链接 。 那么它取决于我在我的应用程序中编写的代码? 有趣的是,我的应用程序(这是主要的EXE文件)不提示UAC,而检查和下载更新的小EXE提示UAC。 我有所有的数字签名的EXE文件。 我已经浏览了以下链接:

http://msdn.microsoft.com/en-us/library/windows/desktop/aa511445.aspx

http://technet.microsoft.com/en-us/library/cc505883.aspx和其他一些。

但是我仍然不清楚。

您几乎可以肯定地打击Windows 安装程序检测技术兼容性启发式。 Windows将尝试检测应用程序是否是安装程序,并且可能需要升级。

安装程序检测仅适用于:

  1. 32位可执行文件
  2. 没有requestedExecutionLevel应用程序
  3. 以启用LUA的标准用户身份运行的交互式进程

在创建32位进程之前,将检查以下属性以确定它是否是安装程序:

  • 文件名包含“安装”,“设置”,“更新”等关键字。
  • 以下“版本控制资源”字段中的关键字:供应商,公司名称,产品名称,文件说明,原始文件名,内部名称和导出名称。
  • 嵌入在可执行文件中的并行清单中的关键字。
  • 可执行文件中链接的特定StringTable条目中的关键字。
  • 在可执行文件中链接的RC数据中的关键属性。
  • 可执行文件中的目标字节序列。

所以,如你所说:

但我有一个exe文件来检查软件的更新

我的猜测是,这个CheckForUpdates.exe触发兼容性启发式。

正确的做法是将一个程序集清单提供给“检查”可执行文件,通知Windows它不应该提升该实用程序。 这是通过清单中asInvokerrequestedExecutionLevel完成的:

AssemblyManifest.xml:

 <?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>Update checker</description> <!-- Run as standard user. Disable file and registry virtualization --> <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"> <security> <requestedPrivileges> <requestedExecutionLevel level="asInvoker" uiAccess="false"/> </requestedPrivileges> </security> </trustInfo> </assembly> 

这样您的“检查更新”应用程序将永远不会提升,并且永远不会错误地获得管理权限。

如果您希望更新程序实际应用更新(需要管理权限的更新),则可以以管理员身份启动更新程序。

示例代码

 //Check if there are updates available if (!CheckForUpdatesAvailable()) return; //no updates. We're done //If the user is an administrator, then get the update if (IsUserAnAdmin()) { //Maybe throw in a "Hey, user, wanna get the update now?" dialog DownloadAndApplyUpdates(); return; } //The user is not an admin. //Relaunch ourselves as administrator so we can download the update //Maybe throw in a "Hey, user, wanna get the update now?" dialog. A button with a UAC shield on it ExecuteAsAdmin(Application.ExecutablePath, "/downloadUpdate"); 

与帮手功能:

 private Boolean IsUserAnAdmin() { //A user can be a member of the Administrator group, but not an administrator. //Conversely, the user can be an administrator and not a member of the administrators group. var identity = WindowsIdentity.GetCurrent(); return (null != identity && new WindowsPrincipal(identity).IsInRole(WindowsBuiltInRole.Administrator)); } private void ExecuteAsAdmin(string Filename, string Arguments) { ProcessStartInfo startInfo = new ProcessStartInfo(Filename, Arguments); startInfo.Verb = "runas"; System.Diagnostics.Process.Start(startInfo); } 

然后,您只需要在启动时查找/ downloadUpdate命令行参数,以确定您的工作是实际完成工作:

 public Form1() { InitializeComponent(); //Ideally this would be in program.cs, before the call to Application.Run() //But that would require me to refactor code out of the Form file, which is overkill for a demo if (FindCmdLineSwitch("downloadUpdate", true)) { DownloadAndApplyUpdates(); Environment.Exit(0); } } 

注意 :任何代码都被释放到公共领域。 不需要归属

您的程序可能缺乏将其标记为非遗留的应用程序清单。 因此,Windows将应用脚本安装程序检测启发式来确定您的程序是否是安装程序。 这几乎是唯一的方式提出“意外的”UAC提示。

这些启发式检查包括EXE文件名中的关键字搜索以及EXE的一些扩展属性,甚至可能会在文件内查找众所周知的二进制签名(即字节字符串)。

顺便说一句,你的加密签名根本就没有进入。 如果它不是由一个可信任的CA颁发,它不会有帮助。

对于那些仅仅因为Windows在UAC提示符上报告公共名称而信任代码的人来说就是一个傻瓜。 恶意软件作者一直在偷这些东西,因此在垃圾程序出现问题时,他们很容易获得,而且用户几乎从不报告。 节省你的钱,代码签名证书是一个失败的概念。

有人可以在exe的配置中指定该文件需要以更高的权限执行。

如何请求管理权限

我不知道这个更新是什么,但我建议它需要更新一个组件,如服务,或位于ProgramFiles-Dir中的一些文件。 因此它需要管理权限。

当需要特权提升时使用UAC提示。 您自己的VB6应用程序不需要它,因此默认行为是OK。 更新程序将需要该权限,因此其作者将可执行程序标记为需要它。 Windows发现并提出UAC提示。

现在取决于确切的Windows版本和安全更新,该特权仍然可用一段时间,甚至其他(子)进程。 这可能会阻止重复的UAC提示。