cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
phil_d_b
Level 4

prevent major upgrade from removing other folders in INSTALLDIR

Hi all;

I have a project which is comprised of 2 features:
Server (components that are always installed)
Database (only installed in the release configuration using "Full" release flags)

What happens with this is that if you are installing for the first time, both features are installed. I use a release configuration called "full" for this. If you have a previous version installed, then I have a 2nd release configuration called "upgrade" that omits the "Database" feature.

Both of these features are installed in a folder structure like C:\program files\myproduct\Server and C:\program files\myproduct\Database.

The problem I am having is that when I run my "upgrade" configuration installer, it removes the entire "myproduct" file before doing the upgrade. This means that the database feature, which should of stayed in place and been untouched, is gone.

How do I prevent this? I need to have 2 features installed by my full installer, and then only 1 of those features is ever updated by subsequent releases. The other feature is a database, and once a customer is using it we don't want to have any patches/releases/upgrades ever change or remove this database.

Any help is appreciated.
Labels (1)
0 Kudos
(19) Replies
Nick_Umanski
Level 7

A much simpler way of doing this would be to have 1 feature, 1 configuration and simply set the 'Permanent' and 'Never Overwrite' flags on the Database components.
0 Kudos
phil_d_b
Level 4

Yes, I agree. Unfortunately this isn't an option. I am taking over the installer project here from someone who didn't set it up very well. I am now tasked with creating installers to upgrade/patch existing systems that were installed this "less than ideal" way.

If I was starting a new project today, I would do it the way you suggested.
0 Kudos
phil_d_b
Level 4

Although.... maybe what you suggest will still work even for existing installs that I need to upgrade. I will test it out...
0 Kudos
Nick_Umanski
Level 7

It will work for future upgrade, but if you've got one out there already, you are going to have to hack the cached file on the machine to make it compatible with this new functionality. Here is a VB script that you can run from a CA to do that:

on error resume next
Const msiOpenDatabaseModeTransact = 1
Set oInstaller = Session.Installer
For Each ProductCode in oInstaller.RelatedProducts(Session.Property("UpgradeCode"))
Set oDatabase = oInstaller.OpenDatabase( oInstaller.ProductInfo( ProductCode, "LocalPackage" ), msiOpenDatabaseModeTransact )
Set oView = oDatabase.OpenView("UPDATE `Component` SET `Attributes`='16' WHERE `Component`='Database'" )
oView.Execute
oDatabase.Commit
Next


Note that the value of Attributes is not set for your requirement, you will have to work out what that should be set to - it is a combined bitflag of several attributes. Run this CA at the start of the install before the old installer is run to uninstall the old version. Have a "Set oView..." line like this for every Component that you need to leave behind, setting the value of `Component` accordingly.
0 Kudos
phil_d_b
Level 4

Ok thanks! Now to see if I can dig up some information on that Attributes flag...
0 Kudos
Nick_Umanski
Level 7

All you need to do is modify the relevant components (ie set them to Permanent, Never Overwrite), then check the Component table for the value of 'Attributes'
0 Kudos
phil_d_b
Level 4

Excellent. Thanks!
0 Kudos
phil_d_b
Level 4

OH, here is another wrench to throw into the works. I am dealing with multiple upgrade codes. For some unknown reason, the person who started this project created a new upgrade code for every version of the installer. Instead of using upgrade codes correctly, he completely ignored them and instead ran regedit scripts to remove the old versions from add/remove programs. So my installers now have to deal with multiple possible upgrade codes and versions. I am talking years and years worth of them.
0 Kudos
Nick_Umanski
Level 7

So it sounds like your predecessor was removing the entries so that the new installer would act as a fresh install each time. Which is why you had to have two separate installers one for a 'real' fresh install and another for the upgrades which didn't interfere with the database. What a mess.

All the same I still think you should proceed in the way discussed above. Just keep the upgrade code the same from now on and the same as the last one that went out the door. The problem you have is where there are databases out there that were installed by earlier versions of the product who's registry entries have now been deleted. However, in those cases the un-installer is not going to run (hopefully), un-install is done by the old installer, not the new one. If the component codes have remained the same you should get away with it, but you will need to do some testing to confirm this.

Presumably your customers know that there is a problem with the installers, because they are having to select an upgrade installer rather than a full installer each time they go to upgrade. So tell them to back up their databases before doing the next upgrade just in case. Something that any decent DB administrator should do by default anyway.
0 Kudos
phil_d_b
Level 4

Thanks for your help Nick. You are right, it will require a lot of testing. Fortunately, although I don't have all of the historical installshield projects anymore, I DO have copies of the installers created. So I can setup almost any combination of previous installs/patches etc and test things out.
0 Kudos
phil_d_b
Level 4

Well, I must be doing something wrong because my installer is still completely removing all of the folders on my existing install before continuing.

I have my CA set up with Install Exec Sequence as , but this must be wrong. Right after it extracts the MSI, I see my previous installation folder completely deleted from the machine, then the installer recreates it and puts in all the new files.

Any ideas?
0 Kudos
Nick_Umanski
Level 7

Given that the guy who first set things up, uninstalled by adding RemoveRegistry actions, could he have also added RemoveFile actions for all the files?
0 Kudos
phil_d_b
Level 4

There is one RemoveFile action in the previous installer, but it is not a file that is related to the database. In my installer I have zero removefile actions.
0 Kudos
Nick_Umanski
Level 7

I presume you are running an edited version of the VBScript that I posted earlier, are you sure it is running? Are the Component names correct. Add a msgbox at the end of the script to halt the installer as soon as it runs, this will confirm that the script runs and then check to make sure the files are still there at that point before clicking the OK button.

My VBScript runs in both the UI and Execution sequences, I can't remember why, but try that.

Are the Component GUIDs the same across installers?

Have you created a brand new installer or taken the old one as a base and modified it, is there any suspicious CA deleting off files?

Post your modified VBScript please if that is possible.
0 Kudos
phil_d_b
Level 4

Here is my script:

on error resume next
MsgBox("starting")
Const msiOpenDatabaseModeTransact = 1
Set oInstaller = Session.Installer
For Each ProductCode in oInstaller.RelatedProducts(Session.Property("UpgradeCode"))
Set oDatabase = oInstaller.OpenDatabase( oInstaller.ProductInfo( ProductCode, "LocalPackage" ), msiOpenDatabaseModeTransact )
Set oView = oDatabase.OpenView("UPDATE 'Component' SET 'Attributes'='152' WHERE 'Component'='Database'" )
oView.Execute
oDatabase.Commit
Next
MsgBox("finished")


When I run the installer, I get both of my messageboxes and the folders are still there. They are removed shortly afterwards.

The component name is correct. I have started a brand new installer, not modifying one of the existing ones. The component GUIDs are NOT consistent across installers, they are different every time.
0 Kudos
Nick_Umanski
Level 7

Are you sure this line is correct:

Set oView = oDatabase.OpenView("UPDATE 'Component' SET 'Attributes'='152' WHERE 'Component'='Database'" )

Particular the last word 'Database' this is the name I gave you, I would have expected that to be different in your installer - and I thought there was more than one component involved?

Secondly I've had problems with the type of speech marks used. Look at the next two lines, the first is yours, the second is how I supplied it, with just the Attributes value corrected.

Set oView = oDatabase.OpenView("UPDATE 'Component' SET 'Attributes'='152' WHERE 'Component'='Database'" )
Set oView = oDatabase.OpenView("UPDATE `Component` SET `Attributes`='152' WHERE `Component`='Database'" )

Make your component GUIDs the same as the latest installer and just test against that one to start with.
0 Kudos
phil_d_b
Level 4

Yes, my component is actually called "Database", it's just a coincidence that you used the same name in the script. There are more than one component, but only this component needs to stay in place. All the others can be replaced.

I have changed the ` marks to ', but it didn't seem to make any difference.

Thanks again for your help, I will continue to work on it.
0 Kudos
phil_d_b
Level 4

Ok, this might be helpful. I removed the Action "RemoveExistingProducts" and now my database component stays in place and my installer completes succesfully. However, I am left with duplicate entries in add-remove programs: the previous version, and my new version. Does this suggest that something is wrong with my Upgrades settings? I have double and triple checked that I have the correct Upgrade codes and version number ranges...
0 Kudos
phil_d_b
Level 4

If anyone is still reading this, I figured out my problem. I was using Major Upgrade items instead of Minor Upgrades, which caused the entire program folder to be uninstalled. Switched to Minor Upgrade and it is working fine now, without any extra script needed.

😄
0 Kudos