Archive: Vista Uninstall issue on 64bit system


Vista Uninstall issue on 64bit system
When running my NSIS installer on a 64bit version of vista I am making the following entry (plus others) via NSIS to the registry:

WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Adobe Flash Player" UninstallString $SYSDIR\Macromed\Flash\uninstall_activeX.exe"

However this gets translated by NSIS to the following in the registry:

HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Adobe Flash Player UninstallString C:\windows\system32\macromed\flash\uninstall_activeX.exe

The $SYSDIR on Vista64 (and where NSIS put all of the files that I specfied for $SYSDIR) into the following directory:

C:\windows\sysWOW64\macromed\flash\

Obviously this breaks add/remove programs.
Can anyone be my guiding light here?

Thank you,
Michael


So you're writing to the Wow32Node of HKLM, yet it fails to redirect C:\windows\system32 to C:\windows\syswow64? That's... Weird... :igor:

You have a number of options.

  1. Disable file system redirection when writing the uninstaller, so it'd really get written to system32 (see Includes\x64.nsh).
  2. Manually get syswow64.
    System::Call "kernel32::GetSystemWow64Directory( \
    t .r0, i ${NSIS_MAX_STRLEN})"
    DetailPrint $0
  3. Write the uninstaller to $PROGRAMFILES.

"WriteRegStr" when running on 64bit Vista writes to

HKLM\Software\WOW6432Node\Microsoft\...


Yeah, that's what I meant. You'd expect the Add/Remove control panel to be smart enough on what it executes and enable redirection when reading from there.


Sounds like a possible bug with Vista. I'll work around it for now using your suggestions. Thank you for the quick response.


Even weirder - it works on Windows XP x64. Are you sure that's the reason for the failure? Try running FileMon in the background and see exactly what it tries to open.


It's pretty straight forward in the script. First do

InstallDir "$SYSDIR\Macromed\Flash"
WriteUninstaller $INSTDIR\uninstall_activeX.exe

This copies the uninstaller to SysWOW64\Macromed\Flash

When I do the following on Vista x64:
WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" UninstallString $INSTDIR\uninstall_activeX.exe

It puts the $INSTDIR value as "SYSTEM32\Macromed\Flash". Everywhere else $INSTDIR is being properly redirected to SYSWOW64.

I haven't tried on XP x64. I will check that out as well.


But does the Add/Remove Control Panel actually try to run the file from system32? WriteRegStr will always write system32 because that's how the file system redirector works. When a file is actually accessed, it changes system32 to syswow64. I believe they chose this method of registry shell folders' registry separation because a lot of developers wrote directly to system32 without using GetSystemDirectory. What I don't understand is why system64 wasn't created instead. Any old and unported application would access system32 anyway as it's compiled for x86.


It does try to run it from the path in the registry (System32) and then Vista comes up with a dialog that says there is a problem with uninstall (and all of the files including the uninstaller are left on the system). When I change the registry entry to point to the correct location it works as expected. So my best guess is that the code that does the add/remove is not doing the file system mapping.

Possibly there is another place in the registry that add/remove is supposed to live on Vista?


There isn't any other new place I've heard of...


The behavior is the same on XP 64 as it is on Vista 64... So I have just made the following change and all is well.

${If} ${RunningX64}
System::Call "kernel32::GetSystemWow64Directory( \t .r0, i ${NSIS_MAX_STRLEN})"
WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayIcon $0\Macromed\Flash\uninstall_activeX.exe
WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" UninstallString $0\Macromed\Flash\uninstall_activeX.exe
${Else}
WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayIcon $INSTDIR\uninstall_activeX.exe
WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" UninstallString $INSTDIR\uninstall_activeX.exe
${EndIf}

I would think others would run into this problem as well... Is there a different way for entering the add/remove entry in NSIS than the way I am doing it that properly maps the path?


I've managed to reproduce this on XP x64 as well. All I had to do is put the uninstaller in a subfolder of syswow64 instead of syswow64 itself. That's an even weirder workaround that they've used. But I guess I can understand how it came to be. Instead of activating the redirector, they made a simple search and replace, only they compare the folder instead of really searching.

The reason no one else has reported it is because usually people don't put uninstallers in $SYSDIR. The common location is $PROGRAMFILES.


Ahh, yes. Program Files... Unfortunately being the Flash Player we have a strange location because we shipped as a part of XP... One day we will probably move out of there, but not as long as people are using XP :) Thanks for your help.


Well, the OCX itself can stay in system32, but I see no reason to keep the uninstaller there.


True. We try to keep everything in one place so as not to pollute the system anymore than people already think we do... being evil Flash and all. I'll consider moving the uninstaller in the future if this continues to plague us.

Thanks again.


BTW: We just shipped (Yesterday) our full rewrite of our installers using NSIS. It has been a great experience.