cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
fredliu
Level 5

Cannot remove file from program file when upgrade

Hi,

This issue is urgent.

I am using installshield2009, I make two simple installers, one is 32bit another is 64bit, 64bit installation directory is program file and 32bit installation directory is program file(x86), they can upgrade each other, when i upgrade from 64bit to 32bit , all files of 64bit in program file cannot be removed, the verbose log show installer is using program file(x86) to remove 64bit files,(if you donot believe, you can use installshield2009 to create two simple installer to test, you must can replay this issue). Anyone can tell me why, is it some property donot be set correctly or issue of installer.

Appreciated your replay.

Thanks
Labels (1)
0 Kudos
13 Replies
MSIYER
Level 8

the verbose log show installer is using program file(x86) to remove 64bit files

Reason for the behaviour:
When the msi is triggered the Windows Installer sets various private and public properties are set. This happens in both 32 bit and 64 bit installs.
This is what happens when you try to upgrade the 64-bit app with your 32-bit install. The installer, by the time it reaches RemoveExistingProducts standard action, has all properties set according to your 32-bit installation. This also affects the 64-bit uninstall as wrong properties are used.

I believe, the same server msiexec.exe process that is installing the 32-bit app is also now responsible for the uninstallation of 64-bit app at the call of RemoveExistingProducts.

Also, we have two kinds of msiexec.exe on the 64-bit system. As you can guess, one is 32-bit and the other is 64-bit.

Now, to attain the objective, i.e., uninstall 64-bit during the install of 32-bit(major upgrade), I would invoke the 64-bit installer in the UI Sequence using LaunchAppAndWait with LAAW_OPTION_WAIT parameter. Something like this:
LaunchAppAndWait("C:\\Windows\\System32\\msiexec.exe", " /X{F1142781-9BBA-435A-AF5A-6243CFE746DB}", LAAW_OPTION_WAIT);

Just FYI, 32-bit msiexec resides here:
C:\Windows\SysWOW64\msiexec.exe

This will initiate an uninstall and once it gets over, the UI Sequence will move forward and you can install your app without issues.
0 Kudos
MSIYER
Level 8

ADDENDUM:
Although I explicitly call 64-bit msiexec.exe I find that it uses the 32-bit version only. This is because the Installshield script engine is still 32-bit and needs a 32-bit host process to run.

Now, if I use 32-bit msiexec.exe manually for removing 64-bit apps, it succeeds. But I am not aware of the impact of such an action. The below code:
LaunchAppAndWait("C:\\Windows\\System32\\msiexec.exe", " /X{F1142781-9BBA-435A-AF5A-6243CFE746DB}", LAAW_OPTION_WAIT);
works but uses 32-bit process to uninstall 64-bit app.

For ensuring that the call we make to msiexec.exe invokes the 64-bit msiexec.exe, use a 64-bit dll custom action.
0 Kudos
fredliu
Level 5

Thanks for you reply.
As you say, if I upgrade from 32bit to 64bit, 64bit installer will use program file to remove 32bit files, but actually 64bit installer still use program file(x86 ) remove 32bit files and everything is OK.

LaunchAppAndWait("C:\\Windows\\System32\\msiexec.exe", " /X{F1142781-9BBA-435A-AF5A-6243CFE746DB}", LAAW_OPTION_WAIT);
The GUID is prodeuct code? if yes, my 32bit product need upgrade from previous 32bit product and currect 64bit product,so there will have two product code, one is previous 32bit another is currect 64bit,so i donot know if it is possible use this way.
0 Kudos
MSIYER
Level 8

As you say, if I upgrade from 32bit to 64bit, 64bit installer will use program file to remove 32bit files, but actually 64bit installer still use program file(x86 ) remove 32bit files and everything is OK.

I was talking about the reverse where you uninstall 64-bit app with 32-bit msiexec.exe. This is where the problem occurs. My statement was an observation rather than a proof.
Uninstalling a 32-bit app during 64-bit app install works exactly as desired.
I need to understand why all these things happen.

Yes:
LaunchAppAndWait("C:\\Windows\\System32\\msiexec.exe", " /X{F1142781-9BBA-435A-AF5A-6243CFE746DB}", LAAW_OPTION_WAIT);
the GUID shown is the product GUID.

In your case you need to establish the existence of the previous version of your application on the end-user system.Also, you need to establish what the bit value is. There might be some custom registry key that you use in your app.

According to the results of the above check you need to execute the call to LaunchAppAndWait to remove the 64-bit or the 32-bit whichever is found on the system.
0 Kudos
MSIYER
Level 8

I finally got to the heart of the matter. Please go through the following blog post by me:
http://msiyer.blogspot.com/2011/06/installation-behaviour-on-64-bit.html
0 Kudos
fredliu
Level 5

Thanks for your faster reply!

There is another issue, for example, now my product version is 1.0, and i setup a custom action to uninstall 64bit of 1.0 in 32bit installer, after my product upgrade to 2.0, then i need two custom action in my 32bit installer which one for uninstall 64bit of 1.0, another for uninstall 64bit of 2.0, if my product version reach to 10.0, need i setup 10 custom actions to uninstall all version of 64bit?

Thanks
0 Kudos
fredliu
Level 5

By the way, I cannot open your link

Thanks
0 Kudos
fredliu
Level 5

Sorry, I really cannot open your link.
Can you send me the content to my email.
My email is fred.liu@quest.com

Thanks in advance!
0 Kudos
MSIYER
Level 8

I assume you read the blog post.

In scenarios such as these where we are bound by Windows Installer, we need to find workarounds.

I do not see the need for you to have 10 CAs. You can have a list of GUIDs with you in the CA and uninstall the GUID thats found on the system.

You can create a bootstrapper exe and handle all the product GUIDs in it.
MsiConfigureProduct API function is a good option. Use it with MsiEnumRelatedProducts. Look here for more details:
http://msdn.microsoft.com/en-us/library/aa370103(v=vs.85).aspx

You can also create a C++ dll that handles the scenario or create a c# dll and call MsiConfigureProduct using PInvoke. Any such scheme can be employed.

Any how you need to figure out whats best in your situation because the behaviour displayed by Windows Installer is by design.
0 Kudos
MSIYER
Level 8

The blog post contents:

NOTE: All scenarios mentioned are for 64-bit machines only.
Upgrade here means MAJOR UPGRADE only

Scenario 1:
A 32-bit application is installed on the machine. The package is marked as Intel;xxxx in the Template Summary. The files contained are dropped to Program Files(x86) folder. Uninstall also happens fine. 32-bit msiexec.exe is used for install and uninstall.
Upgrading the app using another 32-bit package is also as desired.

Scenario 2:
A 32-bit app is already installed. When upgrading it using 64-bit package, the WIN64DUALFOLDERS determines what happens to the path variables. The below log file entry clearly illustrates this:
WIN64DUALFOLDERS: Substitution in 'C:\Program Files (x86)\SHAKESPEARE_INC\Othello\' folder had been blocked by the 1 mask argument (the folder pair's iSwapAttrib member = 0).
This means that the file system redirection will not happen. All paths will be defined as desired. For example:
ProgramFilesFolder will be C:\Program Files (x86)
ProgramFiles64Folder will be C:\Program Files
and so on...
The end result would be as expected.
The 64-bit msiexec.exe is used in the whole process.

Scenario 3:
A 64-bit app is installed. The next version is a 32-bit app with a 32-bit installer(for whatever reason).
32-bit msiexec.exe is invoked and the uninstall of 64-bit begins. This is followed by the install of 32-bit app.
The 64-bit application is uninstalled and 32-bit app installs properly but 64-bit app folders do not go anywhere.
The registry read-write is properly handled by the Windows Installer in conjunction with the OS services while
WIN64DUALFOLDERS changes all path variables during install. The log has the following entry:
WIN64DUALFOLDERS: 'C:\Program Files (x86)\' will substitute 17 characters in 'C:\Program Files\' folder path. (mask argument = 0, the folder pair's iSwapAttrib member = 0).
This means:
ProgramFilesFolder will be C:\Program Files (x86)
ProgramFiles64Folder will become C:\Program Files (x86)

Also, 64-bit app uninstalled using 32-bit msiexec.exe did not display this behaviour. Even the folders disappeared after uninstall.
0 Kudos
fredliu
Level 5

Hi MSIYER,

Yes, i find the couple of functions in window installer API, but how i can use this couple of functions, need i use vbs, or installscript or create a bootstrapper exe which you mentioned in last post, but I donot know how to create a bootstrapper exe, can you please give some advises?

Thanks
Fred
0 Kudos
fredliu
Level 5

I see a thread http://community.acresso.com/showthread.php?t=174919&highlight=MsiConfigureProduct to say Windows Installer Functions Not for Use in Custom Actions
It seems to say I cannot use the couple of functions in vbs or installscript, so only i can use bootstrapper exe to handle, but how create bootstrapper exe
0 Kudos
MSIYER
Level 8

That thread was very informative. I did not know that.
Thanks for the same.

You can write a small C# exe that uses these functions, performs the uninstall and then invokes the msiexec.exe with the path to your msi file as parameter and exits. This adds a dependency to .NET. But its very easy to do in .NET. You can find a wealth of information on websites to perform each of the steps.

You can also use a Win32 C++ exe or MFC exe with MFC statically linked etc...
0 Kudos