cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
knoepdan
Level 6

Problems with with file update rules

Hi

We have a very specific problem with our InstallShield 2010 Basic MSI project. The previous versions of our product, did not use basic msi to get installed, but we still want (need) to support an upgrade installation into the same folder.

So this is what happen:

1. User installs old version of product into folder X. The installation does not use msi.
2. The user installs new version of product, using the basic msi installer, into the same folder x. ( under the hood, the installer removes the old installer entries in the registry and the add/remove programms menu)
3. User starts application and expects to see the new version. However, the old version is still present (Some dlls of the new version are present and are most probably executed. The point is that not all dlls are the ones from the new version.)

I believe the file update rules are responsible for this mess.(I initialy thought/hoped, they would not be applied as the files in the folder did not belong to a msi installation) So if a dll is not properly versioned or a file other than a dll has changed, it will not be updated. While these rules may be usefull, in our case they are not.

So i tried to work around that but have not yet succeded. This is what i tried:

- Reinstall switch. There is a reinstall switch that should ensure that the entire application is reinstalled. We cannot use it as a few files out of the many that are to be copied should be used from the previously installed version. So this is definitly not an option

- Set files to overwrite always. This is what would probably be best. Unfortunately, we can not use this. For most of our features, we use dynamic file linking, and there we cannot set this checkbox (that would really be a nice feature for the next installShield release). Not dynamically link the files is not an option! Setting the overwrite setting in the msi table after installShield compilation is most probably far too complicated as not all files (but most) should have the overwrite always flag and i would also like to avoid for other reason.

- Deleting files in a custom action. This is what i tried. (i know that this complicates rollback, but these are matters we can live with). So i tried to create a custom action that runs in system context ( so process has access to program files folder even in vista) and deletes the files of the old version that need to be replaced (but does not touch a few files that should remain there). The file are deleted but the some of the new files (mainly ddl's) are not installed afterwards. It seems to me, that msi has decided which files are to be replaced before my custom action deletes all files.

So here are my questions:
- Does anyone have an idea how to best solve this problem?
- When does the msi installer in the execute sequence decide which files are to be replaced and which files not. (using the upgrade rules)
- My custom action that deletes the files. When should it run? (Even though the user needs administrator rights to execute the installer, i believe it should be executed as "deferred in system context", to ensure the custom action can access the program files folder (VISTA)
- Is there a built in standard action that i can move up or down in the execute sequence to ensure all files are installed when i delete old files beforehand? (maybe there i can also standard action that is to insert). I believe the actions RemoveExistingProducts may play an important role, but i have not yet had any promising results by changing the order of actions.



i will be grateful for any help.

Thanks in advance.

Daniel



PS1: triggering the uninstall of the old version is not an option
PS2: i have no influence on actual application (version of dll's) i have to solve this problem just by adapting the installer
PS3: silent installation needs to be supported, so anything that is done should be in the execute sequence only.
Labels (1)
0 Kudos
(15) Replies
knoepdan
Level 6

Does anyone have any ideas?
0 Kudos
knoepdan
Level 6

Hi

I am still struggling to find a reasonable solution! I start wondering if there is any. I welcome any ideas, suggestions.

Greetings
0 Kudos
palanisamy
Level 7

Can i Know ur old installer project type either BasicMsi or InstallScriptMSI or InstallScript project..
0 Kudos
Reureu
Level 10

RemoveExistingProducts is documented here http://msdn.microsoft.com/en-us/library/aa371197(VS.85).aspx.
It is used during a major upgrade. Is it the scenario you are trying to implement?

As for deleting files when you install the new version of the product, why don't you add the files to delete to the RemoveFile table? You don't need to define your own custom action for that.

Anyway, If I had to implement that behaviour, I would go for a normal installation, and add a few system searches to see whether some files / registry entries are already present on the target computer.
As for dynamic vs static file linking, I would never use dynamic file linking for versioned files (ie assemblies). Dynamic file linking can possibly be an option for resource files (ie graphics, text files), but as you saw, all options are not available for these files. So I would recommend you to forget the dynamical links and use the component wizard, which allows to quickly generate components whose files are statically linked.
0 Kudos
Reureu
Level 10

Hi,

You didn't finish writing your last reply.
But having a look at your first e-mail, it seems you are trying to implement a major upgrade scenario.

If that's the case, does the previous version have an upgrade code you could use to detect its presence on the target PC?

Some more questions

  • How was the previous version installed?
  • Did you use another type of installer?
  • Or even an installation based on a batch file?
  • How do you uninstall the previous version?


And a few ideas:

  • If you do have an upgrade code: go for the major upgrade scenario
  • If you don't, removing the files and the registry entries on installation, using the RemoveFile and RemoveRegistry tables might be the way to go.
  • Alternatively, you could detect the presence of some old files or registry entries when starting the installation of the new version, and display a message to the user, asking him to manually deinstall the previous version.


Regards
0 Kudos
knoepdan
Level 6

Hi

Thanks for your suggestions and questions. Here the information i failed to get accross.

We have an InstallShield 2010 Basic MSI project, for the new version of our product. We intend our customers to install the new version (using our new msi installer) on top of the old version that was deployed with a InstallScript Installer. So for the msi installer, it is a first time installation not an upgrade. Unfortunately, the on top installation does not work as some of the old (installScript installation) files are not overwritten. Until now, i have not succeded to remove the old files (the ones that need to be removed).

Here some more info on some peculiarities:

- we cannot use trigger the silent uninstaller of the old installation because it has proven to be unrelyable.
- I am also not happy about our dynamic file linking. However, i dont see any other way. We have lots of dll's and their number changes by the day since we are still developping the application.


I am going to try the RemoveTable approach. Hopefully, this will work (files get removed and the new files get installed (using a custom action, the new files were not installed as the installer has already decided then which files to copy. I hope this work this is also not an issue with the RemoveTable approach, as i see that the action is executed quite late in the execution sequence) and i delete all needed files by using wildcards (as there may be different old versions installed and it almost impossible to know all file names)
I will inform you about my findings.


PS: Reureu: i did not quite understand how i can use the system search to delete the needed files (remember, i dont know all file names that are to be deleted)

Greetings and thanks for your support
0 Kudos
knoepdan
Level 6

You are quick Reureu (i deleted one unfinished post, it was not meant to get published)

So here the answers to your questions:

- Previous version(s) were installed by InstallScript Installed
- Yes: InstallShield InstallScript project
- No we dont use a batch file
- When the old installer did an upgrade, it did the following:
- deletes all files (except a few) in the install folder
- it removes the registry entry in the registry to ensure installation is no longer displayed in the "Add/Remove" programms folder
- It deletes the Setup.exe belonging to the installation (in a InstallShield folder)
- Attention: It does not (!) trigger a uninstallation of the previous version. The reason for this is, that (silent) uninstallation has not proven to be relyable.



I believe using the Upgrade Code wont work, but i give the RemoveFiles Table a go. Forcing the user to manually uninstall the old version is also an option (not best one but it is still valid)

Greetings and thanks
0 Kudos
Reureu
Level 10

What you can do in the new setup:

  • Detect the old installed version: Use the search system tool to find some files and/or registry entries of the previous version. Set some properties accordingly. You must ensure that the files/entries you search for are removed by the normal deinstallation of the old version.
  • Test if these properties are set to certain values, display a message forcing the user to deinstall the old version. In such a case, the next button of the UI dialog you are going to use should be disabled.
  • If your new setup needs to support silent installation, you also need to implement a test in the execute sequence, which will abort the installation if the old version is still on the target PC.
  • As a clean up measure during the installation of the new setup, you should add files and registry entries that were leftover by the deinstallation of the old version, by adding them to the RemoveFile and RemoveRegistry tables.

Gosh! I should launch my own consulting company, don't you think? 😉

Regards
0 Kudos
Sairen
Level 7

knoepdan,

Intriguing problem. Hey, it's for stuff like this that we installation developers earn our stripes, so to speak. It's more than glorified XCopy! 😉

So, to look at some of your questions...
- When does the msi installer in the execute sequence decide which files are to be replaced and which files not. (using the upgrade rules)
Components, not files, are marked for installation during the costing procedure. If you are not getting logs from these upgrades, you definitely should be (ask if you don't know how or look it up). Look at the CostFinalize action in the log, and one of the last things in that section might be some helpful bits about disallowing installation of component: {GUID} for this, that, or the other reason. That can give you a clue.

Later on, decisions about file replacement will happen during script execution with InstallFiles. Search the log for the file name, and you're looking for a line that's something like
File: C:\path\to\file.txt Won't overwrite; Won't patch; Existing file is of an equal version
(look for "Won't overwrite")

- My custom action that deletes the files. When should it run? (Even though the user needs administrator rights to execute the installer, i believe it should be executed as "deferred in system context", to ensure the custom action can access the program files folder (VISTA)
Deferred in System Context is very good for this. Try a couple places... Try after RemoveExistingProducts for a start. If the costing is really giving you fits and the components themselves aren't getting marked for installation, try putting your action before costing (ie, before CostInitialize) and see if that helps.

I don't think RemoveExistingProducts will be much good for you here since that triggers with a major upgrade, which you're not doing here. Although...hm, you might be able to populate the Upgrade table (either through the Upgrades view or the Direct Editor) if you have a product code from your old version. If InstallScript projects have an upgrade code. I plead ignorance, but it might be less of a headache to leverage all that built-in functionality.

Also, let me add with Reureu that dynamic file linking can get you into real trouble later down the road. I would advise you to move away from that as soon as you can, even if it's not an option now. If you're really curious about what sort of trouble, ask, but I wanted to keep this thread on target.

Well, I hope that helps. Good luck - write back with what you find.
0 Kudos
knoepdan
Level 6

I guys, I thank you for your answers and your suggestions. I will definitly inform you about my findings. Right now, i dont have a lot of time but i will soon get back to the task.
Thanks for your help
knoepdan
0 Kudos
knoepdan
Level 6

Hi guys

I have not been able to make it work the way I want. Below my findings:

- Using a custom action that runs in the system context to delete files from a previous non-msi installation is not possible because:
-> a deffered custom action must be placed after InstallInitialize, otherwise an exception is thrown. Unfortunately, the action "CostFinalize", which determines whether files should be overwritten or not, runs before InstallInitialize. Anything done in a deffered custom action has thus no influence on which files are copied.
-> The same applies for any entries in the RemoveFile table as the RemoveFiles action runs after CostFinalize.


So i will have to resort replace the dynamically linked files with static ones and set the always overwrite attribute to true/yes. In this very project, this is not an optimal solution but it most probably works.

Thanks for your help.

PS1: please correct me if my findings are somewhat incorrect.
PS2: It would be nice to have the "overwrite always" attribute for dynamically linked files too. Maybe in installshield 2010
0 Kudos
Reureu
Level 10

Hi Dan,

I don't think you need to define your own custom actions to delete the files left over by the previous version.
Are you trying to say that the RemoveFile table does not allow you to remove the files of the previous version?

All you need to do is to add some entries to the RemoveFile table, then make sure the InstallMode is set either to msidbRemoveFileInstallModeOnInstall (1) or msidbRemoveFileInstallModeOnBoth (3), so that the files are removed when you install the new version.

The RemoveFile table is documented here: http://msdn.microsoft.com/en-us/library/aa371201(VS.85).aspx


Regards
0 Kudos
knoepdan
Level 6

Hi Rereu

From RemoveFiles table did not work for me. It does remove the files as it should. Unfortunately, the msi installer decides prior to removing the files from the RemoveFiles table which files are to be copied and which aren't. (CostFinalize action). So the new files are not copied if the update msi update rules state that a file is the same as the old one (even if - as in our case - it isnt).

So i had to resort to flag all files as "overwrite always". To do this i had to make all files statically linked (and not dynamically), which i understand is generally better, although in our specific case it comes with a lot of unwanted sideeffects. However, i have a solution i can and have to live with.

Thanks for your help

Greetings
0 Kudos
Reureu
Level 10

Hi Dan,

Now I think I understood your problem a little more.
Did you try the REINSTALLMODE property?

REINSTALLMODE is normally used in conjunction with REINSTALL when repairing a product.
But it can also be used at installation.

This property is set to "omus" by default on installation.
You can try to set REINSTALLMODE to "amus". This should allow to force all files to be reinstalled. It would save you having to set the "always overwrite" flag.

So the complete solution could be:

  • Use the system search to see whether the previous version of your application is present on the target computer.
  • If it is present, set the REINSTALLMODE to "amus" to make sure that all existing files are overwritten, even if their file version is the same as before.
  • Add the files that were installed by the previous version, but that are not reinstalled by the new version in the RemoveFile table, to avoid leaving orphan files on the target PC.


Regards
0 Kudos
knoepdan
Level 6

Hi Reureu

Thanks for your suggestion. If only I had known about REINSTALLMODE earlier. I believe using REINSTALLMODE is the probably the cleanest way to solve my problem. In our case, there are still issues as a few files should not be overwritten, but i believe these can be solved easily. (As i have a working solution by now (the overwrite flag), i am not going to change my installer as long i am short on time. If i find time, i will definitly go with your suggestions. )


Thanks a lot for your help and greetings
0 Kudos