【问题标题】:ClickOnce Prerequisite : Error: published installer may be corruptClickOnce 先决条件:错误:已发布的安装程序可能已损坏
【发布时间】:2012-10-15 22:49:34
【问题描述】:

我创建了一个自定义安装包,用于在客户端计算机上安装一些字体,并将其部署到 C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bootstrapper\Packages\FontsInstaller 下的先决条件文件夹中。一切都很好,在 Visual Studio 2010 中将其作为先决条件进行引用,我能够毫无问题地发布应用程序。

另一方面,客户端在哈希验证过程中出错:

验证文件哈希

错误:安装程序检测到文件“C:\Users\RMORAN~1\AppData\Local\Temp\VSD4684.tmp\FontsInstaller\fontsinstaller.msi”自最初发布以来已更改或可能已损坏。

我已经尝试使用 Bootstrapper Manifest Generator 包含哈希并排除它,我总是在客户端上得到相同的结果。一旦哈希验证失败,文件会立即被删除(出于安全原因)。

现在,我发现一个Microsoft Connect bug report 说:

“我安装了一个自定义引导程序包作为我的应用程序的先决条件。当我在安装了 Visual Studio 2012 的系统上构建它时,安装失败并出现以下错误:

安装程序检测到文件“...”自最初发布以来已更改或可能已损坏。

我在 Visual Studio 2010 中构建,对包或项目没有任何更改。在未安装 Visual Studio 2012 时,这将按预期工作。"

我尝试在另一个未安装 VS2012 的工作站上构建此安装程序,并且它通过了客户端上的哈希验证(我遇到了签名问题,但那是另一回事)。这确实是具有 VS2012 的构建机器的问题,而不是客户端的问题,因为在我原来的工作站上构建的包在没有 VS2012 的机器上也会失败。

有没有其他人遇到过这个问题,如果有,除了没有安装VS2012,你有没有找到解决方法?

【问题讨论】:

  • 同样的问题!安装 vs2012 后,我的自定义引导程序包不想通过 clickonce 安装。你解决了吗?

标签: visual-studio-2010 visual-studio-2012 clickonce prerequisites


【解决方案1】:

我使用反射工具查看引导程序生成 MSBuild 任务(在安装了 .NET 4.5 的机器上),发现它增加了 product.xml 文件的 <PackageFile /> 元素。具体来说,它尝试从每个文件中计算一个公钥。如果它可以找到一个,它将键与PublicKey 属性的值进行比较。如果值不同,它会发出警告,但在这两种情况下,它都会保留刚刚计算的值。

如果无法确定公钥,它会计算文件的 SHA256 哈希值,并与 Hash 属性的值进行类似的比较,如果它们不同则发出警告并设置Hash 属性与计算值。

您可以通过从生成的setup.exe 中提取SETUPCFG 资源来确认这些发现;它是 product.xml 文件合并的文本版本。

无论如何,还记得我说过如果找不到公钥,它会计算文件的 SHA256 哈希吗? <PackageFiles> Element (Bootstrapper) 的文档说 Hash 属性的值应该是 SHA1 哈希

我无法验证生成的 setup.exe 使用 SHA1 或 SHA256 中的哪一个来验证 Hash 属性的值(它是非托管代码,我找不到它的符号),但让记录显示类似的 .NET 4.0 版本的引导程序生成器 MSBuild 任务显示它确实使用 SHA1 算法来计算 Hash 属性的值,因此通过推导我们可以说 setup.bin(至少Windows SDK v7.0A 中的一个)正在使用 SHA1。我很确定我尝试使用 Windows SDK v8.0A 中的 setup.bin 并且得到了相同(错误)的结果。 (可以通过将 setup.bin 从 v8.0A SDK 复制到仅支持 .NET 4.0 的机器并查看生成的 setup.exe 是否可以使用基于哈希的验证安装自定义引导程序包来确认这一点)

因此,如果 基于哈希的验证在设置引导程序中被破坏,我们至少可以改用公钥(基于证书)验证。好消息是,如果引导程序生成器能够从包文件中提取证书的公钥,它将自动开始使用此机制。坏消息是这意味着每个包文件都必须使用signtool.exe 和有效的代码签名证书进行签名(不是每个人都可能有代码签名证书,尽管如果你正在做单击一次,您可能会...)。

一旦我签署了我们的自定义引导程序使用的包文件,当我使用安装了 .NET 4.5 的机器构建项目时,我在运行时停止安装失败,同时在使用机器时仍然生成有效的引导程序没有安装 .NET 4.5。

tl;dr:使用代码签名证书对包文件进行签名,以避免 .NET 4.5 中引入的缺陷。

【讨论】:

  • 我签署了包文件(.msi),使用的证书与我用于签署 click once 应用程序的证书相同。成功签到了。然后为它创建了一个引导清单。我仍然收到错误file XYZ.msi changed since it was initially published or may be corrupt 在日志中我看到错误发生在Verifying file hash 之后。在我安装.net 4 并安装VS2012 之前,应用程序引导程序运行良好。有什么想法吗?
  • 好的,所以我确实在我的 win 7 机器上安装了所有 Windows 更新,并使用相同的签名包制作清单,并且错误更改为 WinVerifyTrust returned -2146762487 File not trusted Error: Setup has detected that the publisher of file &lt;My custom package&gt; cannot be verified. 此错误仅出现在我的证书上未安装签名包。但我无法在 200 台机器上安装此证书
  • 是的,它确认它仅适用于我进入 Memory Management Console 并手动添加证书的系统
  • @jaminator:听起来您的证书不像是受信任的代码签名证书。在您签名的文件上:右键单击 > 属性 > 数字签名 > 详细信息 > 查看证书 > 证书路径。是否所有内容都受信任并来自一个普遍部署的受信任根?
  • 我遇到了同样的问题。它适用于 .Net 4.0 机器。但是,在 .NET 4.5 机器上失败了。
【解决方案2】:

您需要将GenerateBootstrapper Path 更改为:

C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bootstrapper

C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\Bootstrapper

【讨论】:

    【解决方案3】:

    您需要从以下位置更改 GenerateBootstrapper Path:

    C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bootstrapper

    C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\Bootstrapper

    并复制 msi 包(您要使用的) 从 C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bootstrapper 到 C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\Bootstrapper

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多