在我的VB6应用程序中,我打开其他EXE文件。我的应用程序在没有任何UAC提示的情况下运行,但我有一个检查软件更新的EXE。这会提示UAC提示。那么Windows如何决定是否显示UAC提示?我看到了link。那么它取决于我在我的应用程序中编写的代码吗?有趣的是,我的应用程序(即主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和其他一些。
但我仍然不清楚它。
答案 0 :(得分:27)
您几乎肯定会遇到Windows Installer Detection Technology兼容性启发式问题。 Windows将尝试检测应用程序何时是安装程序,并且可能需要升级。
安装程序检测仅适用于:
- 32位可执行文件
- 没有
的应用程序requestedExecutionLevel
- 以启用LUA的标准用户身份运行的交互式进程
醇>在创建32位进程之前,将检查以下属性以确定它是否为安装程序:
- 文件名包括“安装”,“设置”,“更新”等关键字
- 以下版本控制资源字段中的关键字:供应商,公司名称,产品名称,文件描述,原始文件名,内部名称和导出名称。
- 可执行文件中嵌入的并排清单中的关键字。
- 可执行文件中链接的特定StringTable条目中的关键字。
- 可执行文件中链接的RC数据中的关键属性。
- 可执行文件中的目标字节序列。
所以,正如你所说:
但是我有一个exe来检查软件的更新
我的猜测是CheckForUpdates.exe
触发了兼容性启发式。
正确要做的是将程序集清单添加到“检查”可执行文件中,通知Windows它应 不 提升效用。这是通过清单中的requestedExecutionLevel
asInvoker
完成的:
<强> 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="ITReasearchAssociates.Contoso.Updater"
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()
{
//Public domain: no attribution required
//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)
{
//Public domain: no attribution required
ProcessStartInfo startInfo = new ProcessStartInfo(Filename, Arguments);
startInfo.Verb = "runas";
System.Diagnostics.Process.Start(startInfo);
}
然后在启动时,您只需要查找 /downloadUpdate
命令行参数,就可以知道实际的工作是:< / p>
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);
}
}
注意:任何代码都会发布到公共域中。无需归属。
答案 1 :(得分:1)
有人可以在exe的配置中指定此文件需要以更高的权限执行。
How to request Admin Privileges
我不知道此更新的用途,但我建议它需要更新组件,如服务或位于ProgramFiles-Dir中的某些文件。因此,它需要管理员权限。
答案 2 :(得分:1)
您的程序可能缺少将其标记为非遗留的应用程序清单。因此,Windows将应用脚本安装程序检测启发式方法来确定您的程序是否为安装程序。这几乎是“意外”UAC提示被提升的唯一方式。
这些启发式方法包括EXE文件名中的关键字搜索和EXE的几个扩展属性,甚至可以在文件中查找众所周知的二进制签名(即字节字符串)。
顺便说一句,你的加密签名根本就没有进入。如果它不是由受信任的CA发布的话,它就无济于事。对于那个只因为Windows在UAC提示符上报告公文名称而信任代码的人来说是个傻瓜。恶意软件作者一直窃取这些内容,就此而言,当垃圾程序导致问题时,用户几乎无法获得并且几乎从未报告过。节省您的资金,代码签名证书是一个失败的概念。
答案 3 :(得分:0)
需要权限提升时使用UAC提示。您自己的VB6应用程序不需要它,因此默认行为是正常的。更新程序需要该权限,因此其作者将可执行文件标记为需要它。 Windows发现并提出了UAC提示。
现在,根据确切的Windows版本和安全更新,该权限仍然可用一段时间,甚至可用于其他(子)进程。这可以防止重复的UAC提示。