ClickOnce 安全性、应用程序版本控制以及清单语法和语义存在各种问题,可能导致 ClickOnce 部署不成功。
ClickOnce 和 Windows 用户帐户控制
在 Windows Vista 和更高版本的 Windows 中,应用程序默认以标准用户身份运行,即使当前用户使用具有管理员权限的帐户登录也是如此。 如果应用程序必须执行需要管理员权限的操作,它会告知操作系统,然后提示用户输入其管理员凭据。 此功能名为“用户帐户控制”(UAC),可防止应用程序进行更改,这些更改可能会影响整个作系统,而无需用户显式批准。 Windows 应用程序声明需要权限提升,通过在其应用程序清单的trustInfo
节中指定requestedExecutionLevel
属性。
由于暴露应用程序于安全权限提升攻击的风险,如果为客户端启用了 UAC,ClickOnce 应用程序无法请求权限提升。 任何尝试将其 requestedExecutionLevel
属性设置为 requireAdministrator
或 highestAvailable
的 ClickOnce 应用程序都无法在 Windows Vista 及更高版本上安装。
在某些情况下,ClickOnce 应用程序可能会尝试使用管理员权限运行,因为 Windows 上的安装程序检测逻辑。 在这种情况下,可以将应用程序清单中的属性设置为 requestedExecutionLevel
asInvoker
。 这将导致应用程序本身在没有权限提升的情况下运行。 Visual Studio 会自动将此属性添加到所有应用程序清单。
如果你开发的应用程序需要应用程序的整个生存期的管理员权限,则应考虑改用 Windows Installer (MSI) 技术部署应用程序。 有关详细信息,请参阅 Windows Installer 基础知识。
在线应用程序配额和部分信任应用程序
如果 ClickOnce 应用程序联机运行,而不是通过安装运行,则它必须适合为联机应用程序预留的配额。 此外,以部分信任方式运行的网络应用程序(如具有受限的安全权限集)不能超过配额大小的一半。
注释
在 ClickOnce for .NET Core 和 .NET 5 或更高版本中,不支持需要代码访问安全性的部分信任。 在 .NET Framework 中,使用代码访问安全性不是最佳做法,不建议这样做。
有关详细信息以及如何更改联机应用程序配额的说明,请参阅 ClickOnce 缓存概述。
版本控制问题
如果将强名称分配给程序集并递增程序集版本号以反映应用程序更新,则可能会遇到问题。 使用对强命名程序集的引用编译的任何程序集都必须重新编译,否则程序集将尝试引用旧版本。 程序集将尝试此作,因为程序集在其绑定请求中使用旧版本值。
例如,假设在您自己的项目中,有一个版本为 1.0.0.0 的强名称的程序集。 编译程序集后,将其添加为对包含主应用程序的项目的引用。 如果更新程序集,将版本递增到 1.0.0.1,并尝试在不重新编译应用程序的情况下对其进行部署,则应用程序将无法在运行时加载程序集。
仅当手动编辑 ClickOnce 清单时,才会发生此错误;如果使用 Visual Studio 生成部署,则不应遇到此错误。
在清单中指定单个 .NET Framework 程序集
如果已手动编辑 ClickOnce 部署以引用旧版 .NET Framework 程序集,则应用程序将无法加载。 例如,如果在清单中指定的版本之前添加了对 .NET Framework 版本的 System.Net 程序集的引用,则会发生错误。 一般而言,您不应该尝试指定对单个 .NET Framework 程序集的引用,因为应用程序运行所依赖的 .NET Framework 版本已在应用程序清单中指定为依赖项。
清单解析问题
ClickOnce 使用的清单文件是 XML 文件,它们必须格式正确且有效:它们必须遵守 XML 语法规则,并且仅使用相关 XML 架构中定义的元素和属性。
清单文件中可能导致问题的内容是为包含特殊字符的应用程序选择名称,例如单引号或双引号。 应用程序的名称是其 ClickOnce 标识的一部分。 ClickOnce 当前不分析包含特殊字符的标识。 如果应用程序无法激活,请确保仅对名称使用字母和数字字符,并尝试再次部署它。
如果已手动编辑部署或应用程序清单,则可能无意中损坏了它们。 损坏的清单将阻止正确的 ClickOnce 安装。 您可以通过在运行时在ClickOnce 错误对话框中单击详细信息,并在日志中读取错误信息来调试此类错误。 日志将列出以下消息之一:
语法错误的说明,以及发生错误的行号和字符位置。
违反清单架构使用的元素或属性的名称。 如果已手动将 XML 添加到清单,则必须将添加内容与清单架构进行比较。 有关详细信息,请参阅 ClickOnce 部署清单 和 ClickOnce 应用程序清单。
ID冲突。 部署和应用程序清单中的依赖项引用在它们
name
和publicKeyToken
属性中必须是唯一的。 如果两个属性在清单中的任何两个元素之间匹配,则清单分析不会成功。
手动更改清单或应用程序时的预防措施
更新应用程序清单时,必须重新对应用程序清单和部署清单进行签名。 部署清单包含对应用程序清单的引用,其中包含该文件的哈希及其数字签名。
部署提供程序使用的注意事项
ClickOnce 部署清单具有一个 deploymentProvider
属性,该属性指向应从中安装和服务应用程序的位置的完整路径:
<deploymentProvider codebase="http://myserver/myapp.application" />
当 ClickOnce 创建应用程序并强制安装应用程序时,将设置此路径。 路径指向 ClickOnce 安装程序将从中安装应用程序并搜索更新的标准位置。 如果使用 xcopy 命令将 ClickOnce 应用程序复制到其他位置,但不更改 deploymentProvider
属性,则当 ClickOnce 尝试下载应用程序时,ClickOnce 仍将引用原始位置。
如果要移动或复制应用程序,还必须更新 deploymentProvider
路径,以便客户端实际从新位置安装。 如果已安装应用程序,则更新此路径主要是一个问题。 对于始终通过原始 URL 启动的联机应用程序,设置 deploymentProvider
是可选的。 如果 deploymentProvider
已设置,则会遵循它;否则,用于启动应用程序的 URL 将用作下载应用程序文件的基 URL。
注释
每次更新清单时,还必须再次对其进行签名。