ClickOnce Prerequisite : Error: published installer may be corrupt - visual-studio-2010

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?

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.

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

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

Related

What must I deploy for a project that uses OpenNETCF?

I created an .exe using the OpenNETCF's SerialPort class, but when I copied the .exe to the Motorola device running Windows CE 6 and tried to run it, I got:
TypeLoad
Exception
File or assembly name 'OpenNETCF, Version=1.3.50123.0...or one of its dependencies was not found.
What file or files do I need to copy over to remedy this? Is there a way to cause Visual Studio (2003, .NET 1.1) to bundle the required bits into the .exe?
I noticed in Build | Configuration Manager that the only context I have set up is "Debug"; would changing this from Debug to Release make any difference?
I don't know about Visual Studio 2003, but in 2008 you can create a Smart Device Deployment CAB, which essentially creates an installer for you, which would have a copy of all the references you need for your program to work.
This may have been overkill, but I copied all the OpenNETCF dlls over, and the problem was solved.

Include c++ as pre-req, but says "A new version already exists"

I'm using the Visual Studio Setup project. If I go to the properties of the Setup project, it lets me choose which pre-reqs are required, at which point I choose the C++ Redistributable.
On some systems, this works fine - but recently my users are reporting that the install failed because "A newer version of Microsoft Visual C++ 2010 Redistributable has been detected on the machine."
What's the proper way to do this? Is Visual Studio's detection fouled up somehow and unable to detect C++?
Yuck, this is ugly. I was wondering what would happen after Microsoft gave up on the side-by-side install of the runtime DLLs for VS2010. Seems clear, the interwebs are full of this installer error. The biggest victim seems to be Microsoft itself with Streets and Maps failing to install.
I'm not aware of any security patches for it so I have to guess that you haven't updated to SP1 yet. And your customers use a product of a vendor that did. This is a battle that you're always going to lose some day. Do consider taking advantage of the app-local deployment for the DLLs, copying them in the same directory as your main EXE. Simply copy them from the vc/redist directory before putting the setup package together, no need to tick the prerequisite. You'll need:
msvcr100.dll and msvcp100.dll for the regular CRT
atl100.dll if you use ATL
mfc100.dll, mfc100u.dll, mfcm100.dll, mfc100u.dll if you use MFC (u = Unicode, m = managed)
mfc100xxx.dll where xxx is the 3 letter language code if you use MFC on a non-English machine
vcomp100.dll if you use OpenMP in your code.
Only disadvantage is that they won't get updated if there's a security patch. That could be an advantage too, depending on what color glasses you wear. If you're uncomfortable about it then keeping the machine that creates the setup package updated, including enabling Windows Update, is an important requirement.
The default Visual C++ 2010 Redistributable uses a Product Code for detection. So Visual C++ 2010 SP1 Redistributable is not detected as installed. This is why the package tries to install it and fails.
A good solution is to create your own custom prerequisite which uses a better detection criteria. Here is an article which may help you:
http://blogs.msdn.com/b/astebner/archive/2010/05/05/10008146.aspx
Visual Studio setup projects do not support custom prerequisite creation. However, it can be done by manually generating the required manifests.
You can find the manifests structure here: http://msdn.microsoft.com/en-us/library/ms229223(VS.80).aspx
These manifests can be generated automatically with the Bootstrapper Manifest Generator tool.
After generating the package manifests, you can add all these files (including the package) in a separate folder in the Visual Studio prerequisites folder, for example:
C:\Program Files\Microsoft SDKs\Windows\v7.0A\Bootstrapper\Packages\
This way Visual Studio will show the prerequisite in your setup project properties page.

Visual C++ 2010 Runtime Libraries prerequisite keeps popping up on a VS 2010 created installer

I created an installer with Visual Studio 2010 Version 10.0.40.219.1 SP1 Rel. My application is built/compiled for x86 and requires VC++ runtime libraries. Thus, the setup project is configured with VC++ runtime libraries as a prerequisite.
Every time I run the installer I get the popup "The following components will be installed on your machine." "Visual C++ 2010 Runtime Libraries (x86)". The first time it gets installed asa expected. The second and subsequent times it asks me whether to repair or remove VC++ 2010.
This popup should only be displayed once, the first time it is discovered that VC++ redistributable is not installed.
Has anyone seen this? Anyone know how I can fix this?
Solution:
The answer I accepted gave me what I needed to resolve the issue. Here are the details on what I did to fix this, which was very simple in fact. I edited the file:
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bootstrapper\Packages\vcredist_x86\product.xml
In this file you will find the following:
<InstallChecks>
<MsiProductCheck Property="VCRedistInstalled" Product="{6EE91C1A-A2E7-38CD-AEBB-3B900A4D8868}"/>
</InstallChecks>
The above contains the incorrect product code. Replace the above with the correct product code for the Visual C++ 2010 SP1 redistributable as follows:
<InstallChecks>
<MsiProductCheck Property="VCRedistInstalled" Product="{F0C3E5D1-1ADE-321E-8167-68EF0DE699A5}"/>
</InstallChecks>
The link here shows the correct product codes for the various VC++ 2010 Redistributables.
This happens because the prerequisite detection criteria is incorrect.
A solution is to create your own custom prerequisite with a correct criteria. Perhaps this article will help:
http://blogs.msdn.com/b/astebner/archive/2010/05/05/10008146.aspx
Visual Studio setup projects do not support this. But it can be done by manually generating the required manifests.
You can find the manifests structure here: http://msdn.microsoft.com/en-us/library/ms229223(VS.80).aspx
These manifests can be generated automatically with the Bootstrapper Manifest Generator tool.
After generating the package manifests, you can add all these files (including the package) in a separate folder in the Visual Studio prerequisites folder, for example:
C:\Program Files\Microsoft SDKs\Windows\v7.0A\Bootstrapper\Packages\
You can then select the prerequisite in your setup project properties page.

How does the setup bootstrapper detect if prerequisites are installed?

Trying to solve this problem.
I would like to learn how the bootstrapper detects if prerequisites (specifically .NET 3.5) are installed.
According to this reference, a way to detect if .NET is installed is to check the following registry key:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.5
Using process monitor, I have inspected registry queries done by the bootstrapper (setup.exe) and it did not show any access to this registry key.
Does anybody know how the bootstrapper determines whether the prerequisites are installed on the target system?
Prerequisite packages for the msbuild GenerateBootStrapper packages are defined as XML files. The schema of those XML files is documented here. Take a look at the "InstallChecks" element to get an idea of what sort of checks are possible.
Curiously enough, I could not find such install checks in the prerequisite package for .NET 3.5. You can find this package in the windows SDK folder (C:\Program Files\Microsoft SDKs\Windows), along with the other predefined bootstrapper packages.

How are NUnit assemblies appearing in VS "Add Reference" dialog?

So after installing NUnit, the assemblies (nunit.framework, etc.) now appear in the References > Add Reference dialog, but they're not in the %WINDIR%\Microsoft.NET\Framework\v2.0.50727 dir and there is no NUnit registry entry for the Assembly Path (i.e. HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramewokr\AssemblyFolder).
There's also no automatic entries created in the project properties Reference Paths for the NUnit install directory. How the heck are they appearing in the "Add Dialog"?!?! I thought the mentioned way were the only ways assemblies could appear in "Add Reference".
I dug deeper into this at the weekend. Reproduced verbatim from my blog:
Why is NUnit not in the GAC? (or Why does [assembly X] not appear in Visual Studio's Add Reference dialog?)
Because Visual Studio doesn’t look for references in the GAC:
http://blogs.msdn.com/msbuild/archive/2007/04/12/new-reference-assemblies-location.aspx
http://blogs.msdn.com/junfeng/archive/2004/03/22/93708.aspx
This is by design.
You can either add your files explicitly, which doesn’t work if other people in your team have installed the files somewhere else, for example C:\Program Files\NUnit 2.4.6 vs. C:\Program Files\NUnit-2.4.6. Or (more specifically, because this is the problem I was having this morning) C:\Program Files\NUnit 2.4.6 vs. C:\Program Files (x86)\NUnit 2.4.6. Note the (x86) – my home PC is (as of last weekend) running Vista Ultimate x64.
You have a couple of options:
If your assemblies don’t already have homes, you can put them in the VS PublicAssemblies folder: http://blogs.msdn.com/csharpfaq/archive/2004/10/20/245239.aspx
If they already have homes, you can add them to the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\AssemblyFolders registry key: http://support.microsoft.com/?kbid=306149.
If you’re developing assemblies for other developers to use (i.e. you’re Microsoft or a development tool vendor), you can put these in a subdirectory of C:\Program Files\Reference Assemblies directory, and then add that to the AssemblyFolders registry key.
This means that your project files will reference the assembly by name (i.e. name, version, public key token, all that jazz), and it won’t matter where it’s actually installed on your PC.
Note, however, that this doesn’t work as-is on 64-bit, because Visual Studio is a 32-bit application. You actually need to register your stuff under HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\AssemblyFolders, and you should probably register under both.
There are also corresponding HKEY_CURRENT_USER variants of those keys, but (since that roams), it’s not much use (because the paths are usually relative to the machine, anyway).
Strange, [HKEY_CURRENT_USER\SOFTWARE\Microsoft.NETFramework\AssemblyFolders] should be the only thing driving this.
Perhaps this snippet from this page is relevant?
If you install the .NET Framework 3.0 Service Pack 1 (SP1), the following registry subkey is added:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\AssemblyFolders\v3.0
If you install the .NET Framework 3.5, the following registry subkey is added:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\AssemblyFolders\v3.5
On my install of NUnit I have a registry key
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\AssemblyFolders\NUnit 2.4.3
It seems to be the driver of this behaviour on my computer. Once I removed that key the references did not appear.

Resources