您几乎肯定会遇到Windows Installer Detection Technology兼容性启发式问题。 Windows将尝试检测应用程序是安装程序的时间,并且可能需要升级。
安装程序检测仅适用于:
- 32位可执行文件
- 应用程序不运行与LUA标准用户启用
32前requestedExecutionLevel
互动过程bit进程被创建,检查以下属性以确定它是否是安装程序:
- 文件名包括像关键字“安装”,“设置”,“更新”等
- 关键词在以下版本资源领域:供应商,公司名称,产品名称,文件描述,原始文件名,内部名称和导出名称。
- 嵌入在可执行文件中的并排清单中的关键字。
- 可执行文件中链接的特定StringTable条目中的关键字。
- 可执行文件中链接的RC数据中的关键属性。
- 可执行文件中字节的目标序列。
因此,当你说:
,但我有一个exe,检查软件更新
我的猜测是,这是CheckForUpdates.exe
触发兼容性启发。
的正确的事情是一个集清单到你的“检查”的可执行文件,通知的Windows,它应该不提升工具。这与asInvoker
一个requestedExecutionLevel
在清单中完成:
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);
}
}
注意:任何代码被释放到公共领域。无需归属。
我会补充说上面列出的文件名规则几乎肯定是不完整的。我有一个应用程序,当它命名为APP123.exe时,需要UAC,如果重命名为APP.exe,则不需要UAC。 – DaveInCaz