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

Ang*_*xel 14 clickonce prerequisites visual-studio-2010 visual-studio-2012

我已经创建了一个自定义安装程序包,用于在客户端计算机上安装某些字体并将其部署到以下的先决条件文件夹中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错误报告说:

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

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

我在Visual Studio 2010中构建,没有对包或项目进行任何更改.如果未安装Visual Studio 2012,则按预期工作."

我尝试在没有安装VS2012的另一个工作站上构建此安装程序,并在客户端上传递哈希验证(我遇到了签名问题,但这是一个不同的故事).构建机器具有VS2012而不是客户端确实存在问题,因为在原始工作站上构建的软件包在没有VS2012的机器上也会出现故障.

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

Oli*_*ais 11

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

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

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

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

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

因此,如果在安装引导程序中破坏了基于散列的验证,我们至少可以使用公钥(基于证书)验证.好消息是,如果引导程序生成器能够从包文件中提取证书的公钥,它将自动开始使用此机制.坏消息是,这意味着必须使用signtool.exe一个有效的代码签名证书对每个包文件进行签名(并非所有人都可以使用代码签名证书,尽管如果您正在进行点击,您可能会......).

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

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