Skip to content
⌘ NSIS Forum Archive

Uninstall string not detected in Vista x64 and XP x64

9 posts

jweinraub#

Uninstall string not detected in Vista x64 and XP x64

Far as I am aware, this had always worked and I can't think why this won't work any longer.

ReadRegStr $R0 HKLM \
  "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"\
  "UninstallString"
  MessageBox MB_OK  "R0 val: $R0" IDOK  # debugging purposes -jw
  StrCmp $R0 "" no_remove_uninstaller 
On a Vista x64 box, the R0 value is blank, even though there is indeed an entry in the registry at that point.

On WinXP x64, however, the uninstall string doesn't even get populated. That part of the code had always worked and wouldn't had changed. I am not too sure why it stopped working for these two OSes. As it works fine in Win 7 x86/x64 and Win 8 x86/x64.

I am guessing it is something to do with the Wow6432 but why would it work fine in Win 7 and 8 x64?
jweinraub#
Okay, I think the problem is actually $INSTDIR is blanked on Vista x64 systems. So that is why it is failing. Any idea why $instdir will not be populated on Vista x64 but it is fine on other systems?
JasonFriday13#
So how are you writing $instdir to the registry? Are you using InstallDirRegKey? Are you copying to/from $instdir anywhere in the code? Are you using SetRegView?

The Wow6432Node thing is done inside the registry call, so it could be a bug in the XP/Vista API code, unlikely though.
jweinraub#
Originally Posted by JasonFriday13 View Post
So how are you writing $instdir to the registry? Are you using InstallDirRegKey? Are you copying to/from $instdir anywhere in the code? Are you using SetRegView?
!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" 
It does work in Win 7 x64 and Win 8 x64. Just not Vista x64 (and apparently XP x64 but I don't have that OS with me to fully test and verify now I've added the setregview below).

However, it now does detect it, it just doesn't run the uninstaller at least in vista x64. The message pops up but doesnt run it, as $instdir returns a null string at that point, but in all other OSes I've tested, it is properly populated, and thus works.

The Wow6432Node thing is done inside the registry call, so it could be a bug in the XP/Vista API code, unlikely though.
This is fixed by adding an additional setregview.
${If} ${RunningX64}
  SetRegView 64
  ReadRegStr $R0 HKLM \
  "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"\
  "UninstallString"
 ; MessageBox MB_OK  "val: $R0" IDOK  # debugging purposes -jw
  StrCmp $R0 "" no_remove_uninstaller
${Else}
  SetRegView 32
  ReadRegStr $R0 HKLM \
  "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"\
  "UninstallString"
 ; MessageBox MB_OK  "val: $R0" IDOK  # debugging purposes -jw
  StrCmp $R0 "" no_remove_uninstaller
${EndIf} 
Anders#
The Windows WOW64 registry reflection/redirection has changed at least 3 times. WinXP had the most basic version, then Vista added more reflected keys and in Win7 reflection was removed and keys are only redirected. See http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx for more.

This should not affect the uninstall key (in the default Windows configuration at least) but when dealing with registry issues on WOW64 you always have to remember that things might not be as they seem because you might be looking at a different key in Regedit etc.
jweinraub#
Anders,

Yeah I understand that part. But how does $INSTDIR get defined? Isn't that at runtime? Because I think that is where the problem is laying right now. It calls the uninstaller via $instdir\uninst.exe rather than the $R0 as it caused additional problems with something else, iirc (since tht line was commented out)
jweinraub#
In the uninst label I do this:
   ExecWait '"$INSTDIR\uninst.exe" _?=$INSTDIR' $R1
   StrCmp $R1 0 no_remove_uninstaller ; Success? If so we are done...
   Abort ; Uninstaller was canceled or failed, we cannot continue 
For some reason I had the $R0 method but htat failed because I have that commented out. I think the issue was a user pressing cancel and the install allowed it to be continued without aborting since it is mandatory to uninstall previous version before installing new one.
Anders#
Originally Posted by jweinraub View Post
But how does $INSTDIR get defined?
The installer basically does something like this:

StrCpy $InstDir ""
IfAttribute(InstallDir)
StrCpy $InstDir InstallDir
EndIf
IfAttribute(InstallDirRegKey)
RegReadStr $InstDir ...
StripQuotesAndParameters $InstDir
EndIf
IfCommandLine("/D")
StrCpy $InstDir GetCommandLine("/D")
EndIf
Call .onInit
....
and the uninstaller just does StrCpy $InstDir $ExeDir
jweinraub#
So that being said, is it better to use $R0 again?

Or something like: StrCpy $0 $r0
and then ExecWait '$0 _?=$INSTDIR' $R1
because it is weird how that one thing isn't being populated and far as i can tell, it had always worked in the past.