Monday, April 26, 2010

How to install shared assembly into GAC using Inno Setup

Well... This is my first post about IT. From now I’m going to share my experience in troubleshooting problems I faced with. There are some reasons to do so. First of all I hope that this info would be helpful to other people. I often find answers to my tech questions at someone’s blog. It saves me a lot of time. So I feel responsibility to return this energy back to the World. If someone will find my post useful – I’ll reach the goal. Another reason is to practice my written English. My native language is Russian. But if I have a problem I prefer to google solution in English because, on my humble opinion, there are much more info available on English and it is more detailed than info on Russian (because English-speaking audience is much wider than Russian-speaking). So it is a good idea to share information (especially IT information) on English.

Now, let's begin.

Here the results of my investigation on how Inno Setup (I've used version 5.3.9 - latest at the moment) works with GAC.
First of all, it do allow to install assemblies in GAC (you should add gacinstall flag to the file). Inno also automatically uninstall assemblies from GAC during uninstall process.

If you forget to add StrongAssemblyName parameter to the file you will be prompted by setup compiler to do that. Note that full assembly name have to be ended by "ProcessorArchitecture=MSIL" in order the assembly to be uninstalled correctly.

But if you have more than one application using the same assembly from GAC you faced with a problem. Inno Setup (as opposed to WiX) doesn't support GAC reference counting mechanism. When both applications are installed and you uninstall one of them, Inno will remove assembly from GAC (that makes other app nonworking).

To solve this issue, you can use another Windows internal mechanism of reference counting which Inno Setup supports. You can apply sharedfile flag to the file and it will solve the issue. But you will get a small side effect. Two copies of the assembly will be installed: one in GAC and another in a destination folder of installed app. The reference counting mechanism is keep working even if the file is installed by two different apps in there own folders. Of course installers of both apps should be written on Inno Setup (I haven’t tested the case when one setup is .msi and another is made by Inno).

Another side effect – during uninstall you get a dialog that asks you whether shared assembly should be uninstalled or not (if an assemblies’ reference count become 0).

To wipe out this dialog you should add uninsnosharedfileprompt to the file’s list of flags.

Thereby to more or less reliably install an assembly into GAC by the help of Inno Setup you should add three attributes to the files in [Files] section of setup script: gacinstall sharedfile uninsnosharedfileprompt.

Example:

[Files]
Source: "Files\MyAssembly.dll"; DestDir: "{app}"; StrongAssemblyName: "MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=48d60606109a2257, ProcessorArchitecture=MSIL"; Flags: "gacinstall sharedfile uninsnosharedfileprompt"

Last, I should say I haven’t tested the case of a shared assembly between two applications which written in different installation systems (for example WiX and Inno Setup), but suppose you will have some troubles if you are going to mix them up.

No comments: