0

Got an old program that was installed with a package generated by InstallShield for VS2013. Recently upgraded to VS2015 community, but since InstallShield is not available for the community, i had to redo my installers with Installer Projects. I've got to the point where I have a working installer, everything seemed to be fine, until i tried to upgrade. I have a matching UpgradeCode in my installers, larger Version number, InstallAllUsers matches that of the old one and RemovePreviousVersions is set to true. Afaik everything should be in order.

Running the new installer correctly uninstalls the previous version, and the GUI looks like its installing the new one correctly, it even appears correctly in the add/remove programs list in control panel. Yet, the whole directory to where the new version should have been installed is missing. Running the installer again to repair then really installs the new files.

What am i missing? Why cant it get through the upgrade in one go? What kind of debugging is available in this kind of situation?

Any helpful comments, pointers and links are greatly appreciated.

edit: After posting I've also tried versioning my assemblies as was pointed out here, but with no results. I found out that version 65535 is invalid though.

Google tells me there is something called REINSTALLMODE, but i cant seem to find any place where i would be able to affect it.

Community
  • 1
  • 1
Noino
  • 551
  • 3
  • 13
  • 1
    Enable verbose logging to see what's really happening. `msiexec -i yoursetup.msi -l*v logfile.txt` – zett42 Apr 01 '17 at 13:18
  • @zett42 Woah, 3k lines of debugs, i see alot of guid's and crypyic propertychanges notes etc. Are there any common strings i should look for while I'm reading through it? – Noino Apr 03 '17 at 08:44
  • MSI (s) (78:E8) [09:47:04:318]: File: C:\Program Files (x86)\ `...` AddIn.dll; Overwrite; Won't patch; Existing file is a lower version. This looks like it matters – Noino Apr 03 '17 at 09:59
  • Yeah, so it seems clear to me that my problem indeed is related to versions, and probably InstallShield has written the old files with some ridiculously high number. Found out that i am able to [change REINSTALLMODE](http://stackoverflow.com/questions/1947472/passing-reinstallmode-to-an-msi-file) after creating the msi, so the real question now becomes, how can i do it so it affects both the generated msi and exe files – Noino Apr 03 '17 at 11:36
  • Changing `REINSTALLMODE` on the msi did not work, im still missing the whole directory. Reading this log, it seems like the msi wants to copy new files first, and delete the old version after.. That seems a bit backwards? – Noino Apr 03 '17 at 12:28
  • 1
    _msi wants to copy new files first, and delete the old version after_ -- That is possible, depending on the sequencing of [`RemoveExistingProducts`](https://msdn.microsoft.com/en-us/library/windows/desktop/aa371197(v=vs.85).aspx) action. If old version is indeed deleted after, this could already be the root of the problem as this is tricky to get right. I suggest sequencing `RemoveExistingProducts` immediately before `InstallInitialize`. MSDN states that this is "inefficent" but in my experience it's the most robust way. – zett42 Apr 03 '17 at 13:30

1 Answers1

0

First of all, thanks to @zett42 for your helpful comments. You gave me just the right amount of keywords to guide me in the right direction, that eventually lead me to find a solution.

I ended up setting REINSTALLMODE to amus as well as changing the RemoveExistingProducts sequence value. Honestly i have no idea why 1525, but it works for now, and based on my earlier tests, once migration from the package installed with InstallShield is through, i wont need to do all this and upgrades will just work. Anyway, following script was modelled based on this answer, with help from this post, and even microsoft´s documentation was useful (for once).

So then, this is my add_reinstall_prop.vbs:

set objArgs = WScript.Arguments
set o_installer = CreateObject("WindowsInstaller.Installer")
set o_database = o_Installer.OpenDatabase(objArgs(0), 1)
set o_MSIView = o_DataBase.OpenView("INSERT INTO Property (Property, Value) 
Values( 'REINSTALLMODE', 'amus')")
o_MSIView.Execute
set o_MSIView = o_DataBase.OpenView("UPDATE InstallExecuteSequence SET Sequence=1525 WHERE Action='RemoveExistingProducts'")
o_MSIView.Execute
o_DataBase.Commit

Autoapply it with PostBuildEvent:

"%VS_PBE_TOOLS_PATH%add_reinstall_prop.vbs" "$(BuiltOuputPath)"

where %VS_PBE_TOOLS_PATH% is an environment variable pointing to the directory.

Somehow this change also affects the exe file that installer projects generates even though afaik I'm only doing things on the msi package, since the exe already exists when the PostBuildEvent runs. If someone has a easy explanation for that, i'd appreciate it.

Community
  • 1
  • 1
Noino
  • 551
  • 3
  • 13