Managing Hang Hell with WiX and C #

We are on the eve of the launch of the product, and at the last moment I am bombarded with crash reports, which seem to be related to our installer, which is a WiX3 project with separate outputs for assembling x86 and x64. This is a constant problem that I have always considered fixed, only to find out that they are still hiding.

The product itself is a collection of binary files that communicate with each other through a remote .Net network, including the Windows service and a small COM component that is downloaded as an add-on to another application. The service works like SYSTEM, the COM part works in a low-right context, while the other parts work in normal user contexts. Other parts include a third-party DL library of COM object libraries and a common DLL with Remoting.net interfaces.

I have observed strange behavior with MSI, especially when upgrading the version. Between MS there is an “anal strong name” (in particular, an accurate version check before downloading this assembly), a documented WiX / MSI error that sees critical files deleted during updates (essentially, if the file in the MSI update has the same version number as and the existing installation, this file has been deleted) (editing: there were problems creating the specified documentation ...) and the need to work with Wow64 virtualization (x86 MSI can only write registry entries / HD through Wow64, but x64 MSI cannot work on x86 computers. ..), I am ready to collect all these and transfer to another installation of the system.

What I'm looking for on tips + tricks, tricks or suggestions on how to do it correctly so that I don't fight with the Windows installer, distorted logical thinking. I am tired of struggling with the WiX / MSI / Windows Installer. All you have to do is place the files and registry keys, where I will tell them, update them when necessary, and do not delete anything until the user deletes. Instead, dependencies are removed perforce, creating a whole bunch of fuzzy exceptions (can't wrap the try{} block around function declarations) and GPF in the whole application.

I am particularly interested in the “best practices” and examples regarding common and dependent DLLs and any tips on ensuring that the file needs to go to the GAC, that it really goes to the GAC and stays there until it fits, delete it.

Thanks!

Tom

+4
source share
3 answers

Start by reading the Ultimate Guide to Windows Installer .

Are you done? Excellent. Now think about disposing of the existing installation, starting from scratch, and attach an application error for everything that you currently have, to "work around" in the configuration. Almost every bit of twisted logic that you fought against exists for a specific purpose to make your installation more reliable and repairable.

If you do not need the reliability and fault tolerance of the Windows installer, or if you are trying to circumvent it in any way, use another. Windows Installer does much, much more than just "put files and registry keys where I say."

When you write an MSI package, you determine how you want the target system to look. The way it looks after configuration, a way to automatically recover if the file is deleted or the key data file is damaged. You determine how the system should roll back if the user later cancels during the upgrade from 1.0 to 2.0. Windows Installer runs 100% . From the development point of view, this is the most difficult concept to understand, you can’t just edit the configuration file or write some more data and expect it to be saved. After you think about it, the Windows installer will become a real piece of cake, and you will develop your programs and functions to work within your limitations, instead of trying to free yourself from them :)

A few other useful links ...

+3
source

Assuming you're at least on Wix 3.0, you can use MakeSfxCA.exe to depend on packages in one DLL. (This was an add-on from the DFT - Deployment Tools Foundation.) Basically, start by saying that the project copies the dependent DLLs. Create a CustomAction.config file. Test with a simple .bat file, for example:

REM MyMakeSfxCA.bat - Run under $ (TargetDir); abs. the way. "% WIX% \ SDK \ MakeSfxCA" ^% cd% \ Managed_custom_action_pkg.dll ^ "% WIX% \ SDK \ x86 \ sfxca.dll" ^% cd% \ Managed_custom_action.dll ^% cd% \ Dependent1.dll ^% cd % \ Dependent2.dll ^% cd% \ Microsoft.Web.Administration.dll ^% cd% \ Microsoft.Deployment.WindowsInstaller.dll ^% cd% \ CustomAction.config

Once this happens, convert to the event after the build: "$ (WIX) \ SDK \ MakeSfxCA" ^ $ (TargetDir) \ Managed_custom_action_pkg.dll ^ "$ (WIX) \ SDK \ x86 \ sfxca.dll" ^ $ (TargetDir) \ Managed_custom_action.dll ^ $ (TargetDir) \ Dependent1.dll ^ $ (TargetDir) \ Dependent2.dll ^ $ (TargetDir) \ Microsoft.Web.Administration.dll ^ $ (TargetDir) \ Microsoft.Deployment.WindowsInstaller.dll ^ $ (TargetDir) \ CustomAction.config

In your .wxs file, your binary key will look like this: <Binary Id = "Managed_custom_action_CA_dll" SourceFile = "$ (var.Managed_custom_action.TargetDir) $ (var.Managed_custom_action.TargetName) _pkg.dll" />

For them CustomAction.config you can find examples on the Internet, for example

This is the best way I've found when working with managed code.

+1
source

I’m kind of afraid to enter into this, but restrictions exist only where you have not followed the best upstream methods.

Take the “delete files” “error”. I have not seen this, but if I remember, it is usually caused by the following scenario:

build A: file 1: 1.0.0.0

build B: file 1: 1.0.0.0

Now you are doing a major update where you have RemoveExistingProducts scheduled after CostFinalize. FindRelated Products detects that the ProductCode will be removed, Costing says oh, I see that I have 1.0.0.0, but 1.0.0.0 is already installed, so I do not need to do anything, and then RemoveExistingProducts comes in and removes the old version, thereby deleting the file .

I always worked on this, planning the RemoveEXistingProducts method earlier and then proposed by Microsoft. He has been working for me for many years.

Regarding dependency, I run a software product line that consists of hundreds of functions expressed by hundreds of merge modules and thousands of files (15,000 +) consumed by dozens of installers on dozens of different functions, integration, core functions, maintenance and maintenance_integ.

How can I do it? One piece at a time and a lot of automation, SCM and virtual machines to make sure that everything really works as planned.

Being close to your delivery of goods, the only "answer" I can offer, really offers you to inform that people like me are always available for hire. You would be surprised how quickly some of us can turn projects and receive software delivery.

-1
source

Source: https://habr.com/ru/post/1306045/


All Articles