ClickOnce先决条件:错误:已发布的安装程序可能已损坏

时间:2012-10-25 17:22:27

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

我创建了一个自定义安装程序包,用于在客户端计算机上安装某些字体,并将其部署到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之外,您是否找到了解决方法?

3 个答案:

答案 0 :(得分:11)

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

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

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

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

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

因此,如果在设置引导程序中基于散列的验证被破坏,我们至少可以使用公钥(基于证书)验证。好消息是,如果引导程序生成器能够从包文件中提取证书的公钥,它将自动开始使用此机制。坏消息是,这意味着每个包文件必须使用setup.exe和有效的代码签名证书进行签名(并非所有人都可以拥有代码签名证书,不过如果你'重新点击 - 你可能......)。

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

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

答案 1 :(得分:1)

您需要更改GenerateBootstrapper Path

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

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

答案 2 :(得分:1)

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

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