ClickOnce Prerequisite : Error: published installer may be corrupt
Asked Answered
A

3

14

I've created a custom setup package to install some fonts on a client machine and deployed it to the prerequisites folder under C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bootstrapper\Packages\FontsInstaller. Everything is fine with reference it as a prerequisite in Visual Studio 2010 and I am able to publish the application without issue.

The client on the other hand gets an error during the Hash verification:

Verifying file hash

Error: Setup has detected that the file 'C:\Users\RMORAN~1\AppData\Local\Temp\VSD4684.tmp\FontsInstaller\fontsinstaller.msi' has either changed since it was initially published or may be corrupt.

I've tried including the hash and excluding it with the Bootstrapper Manifest Generator and I always get the same result on the client. The file is immediately deleted (for security reasons) as soon as it fails hash verification.

Now, I've found a Microsoft Connect bug report saying:

"I have a custom bootstrapper package installed as a prerequisite for my application. When I build this on a system that has Visual Studio 2012 installed, the installation fails with the following error:

Setup has detected that the file '...' has either changed since it was initially published or may be corrupt.

I am building in Visual Studio 2010, with no changes to the package or projects. When Visual Studio 2012 is not installed, this works as expected."

I tried building this installer on another workstation with no VS2012 installed, and it passes the hash validation on the client (I ran into a signing issue, but thats a different story). It really is a problem with the build machine having VS2012, not the client, as the package built on my original workstation also fails on the machine that does not have VS2012.

Has anyone else experienced this issue, if so, have you found a workaround besides not having VS2012 installed?

Autograft answered 25/10, 2012 at 17:22 Comment(1)
Same issue! after installing vs2012 my custom bootstrapper packages don't want to install with clickonce. Have you solved?Frederiksen
E
11

I used a reflection tool to look at the bootstrapper generation MSBuild task (on a machine with .NET 4.5 installed) and found that it augments the product.xml file's <PackageFile /> elements. Specifically, it attempts to compute a public key from each file. If it can find one, it compares the key with the value of the PublicKey attribute. If the values are different, it emits a warning but in both cases it keeps the value it just computed.

If it couldn't determine a public key, it then computes a SHA256 hash of the file and performs a similar comparison with the value of the Hash attribute, emitting a warning if they are different and setting the value of the Hash attribute with the computed value.

You can confirm these findings by extracting the SETUPCFG resource from the resulting setup.exe; it's a text version of a merge of the product.xml files.

Anyway, remember how I said it computes a SHA256 hash of the files if it could not find a public key? The documentation for the <PackageFiles> Element (Bootstrapper) says the value of the Hash attribute should be a SHA1 hash.

I was not able to verify which of SHA1 or SHA256 the resulting setup.exe uses to verify the value of the Hash attribute (it's unmanaged code and I couldn't find the symbols for it), but let the record show that a similar look at the .NET 4.0 version of the bootstrapper generator MSBuild task reveals that it is indeed using the SHA1 algorithm for computing the value of the Hash attribute, so by deduction we can say setup.bin (at least the one from the Windows SDK v7.0A) is using SHA1. I'm pretty sure I tried using the setup.bin from the Windows SDK v8.0A and I got the same (wrong) results. (One could confirm this by copying the setup.bin from the v8.0A SDK to a .NET 4.0-only machine and seeing if the resulting setup.exe can install a custom bootstrapper package using hash-based verification)

So, if hash-based verification is broken in the setup bootstrapper, we can at least use the public key (certificate-based) verification instead. The good news is that the bootstrapper generator will automatically start using this mechanism if it was able to extract the certificate's public key from the package file. The bad news is that this means each package file must be signed with signtool.exe and a valid code-signing certificate (not everybody might have a code-signing certificate lying around, although if you're doing click-once you might...).

Once I signed the package files used by our custom bootstrapper, I stopped getting the installation failures at run-time when I built the project using a machine that had .NET 4.5 installed, while still producing a valid bootstrapper when using a machine that did not have .NET 4.5 installed.

tl;dr: Sign your package files with a code-signing certificate to avoid a defect introduced in .NET 4.5.

Edirne answered 11/1, 2013 at 4:51 Comment(7)
I signed package file (.msi) with the same certificate I use to sign the click once application. It got successfully signed. Then created a bootstrap manifest for it. I am still getting error file XYZ.msi changed since it was initially published or may be corrupt In log I see error occurs just after Verifying file hash. The application bootstrap was working perfectly before I installed .net 4 while installing VS2012. Any ideas?Manichaeism
Ok so I did install all windows updates on my win 7 machine and made manifest with the same signed package and the error changed to WinVerifyTrust returned -2146762487 File not trusted Error: Setup has detected that the publisher of file <My custom package> cannot be verified. This error is only appearing on machine my certificate with which I signed the package is not installed. But I cant go around installing this certificate on 200 machinesManichaeism
Yup, its confirmed it only works on systems where I go in Memory Management Console and add certificate manuallyManichaeism
@jaminator: It doesn't sound like your certificate is a trusted code-signing certificate. On your signed file: right-click > Properties > Digital Signatures > Details > View Certificate > Certification Path. Is everything trusted and coming from a commonly-deployed trusted root?Edirne
I had the same issue. It worked on .Net 4.0 machine. But, failed on .NET 4.5 machine.Pneumatophore
I discovered today (vs2013) that for hash verification, it is looking for SHA256. when I ran msbuild with SHA1 hashes, it gave me this error: warning msb3165: the value of the 'hash' attribute does not match that of file. I used this command line program securityxploded.com/download-file.php?id=9801 . I'm not affiliated with it, I just googled to find something that would.Blond
Yes the new setup.bin from v8.1A or later will correctly use the SHA256 hash but at the time of the question, this didn't exist.Aliquot
B
1

You need to change GenerateBootstrapper Path from:

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

to

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

Brockbrocken answered 5/6, 2014 at 15:13 Comment(0)
C
1

You need to change GenerateBootstrapper Path from:

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

to

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

and copy msi packages (that you want to use) from C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bootstrapper to C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\Bootstrapper

Curler answered 14/5, 2015 at 0:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.