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

IT *_*her 22 windows security vb6 uac windows-7

在我的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和其他一些.

但我仍然不清楚它.

Ian*_*oyd 28

您几乎肯定会使用Windows Installer Detection Technology兼容性启发式方法.Windows将尝试检测应用程序何时是安装程序,并且可能需要提升.

安装程序检测仅适用于:

  1. 32位可执行文件
  2. 申请没有 requestedExecutionLevel
  3. 作为标准用户运行的交互式进程启用了LUA

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

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

所以,正如你所说:

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

我猜这CheckForUpdates.exe是触发兼容性启发式的.

正确的做事情是添加清单到你的"检查"的可执行文件,通知的Windows,它应该装配提升的效用.这与做requestedExecutionLevelasInvoker在清单:

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>
Run Code Online (Sandbox Code Playgroud)

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

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

示例代码

//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");
Run Code Online (Sandbox Code Playgroud)

使用辅助函数:

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);
}
Run Code Online (Sandbox Code Playgroud)

然后在启动时,您只需要查找/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);
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:任何代码都将发布到公共域中.无需归属.