I have made additional custom page with button "uninstall" , this page appears
if product is already installed. I also try to keep button "next" disabled
until user uninstall previous version.
I disabled it sucessfully but i can't turn it enabled back.
What's wrong with this code?
product.ini
---------------------------
[Settings]
NumFields=2
[Field 1]
Type=label
Text=uninstall need
Left=0
Right=-1
Top=0
Bottom=10
[Field 2]
Type=Button
Flags=NOTIFY
Text=&Uninstall..
Left=-60
Right=-10
Top=19
Bottom=33
install_product.nsi
---------------------------
!define PRODUCT_NAME "product"
!define PRODUCT_FILEVERSION "10"
!define PRODUCT_VERSION "1.0"
!define PRODUCT_PUBLISHER "me"
!define PRODUCT_WEB_SITE ""
!define PRODUCT_UNINSTALLER "uninstall.exe"
!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
!define PRODUCT_UNINST_ROOT_KEY "HKLM"
!define PRODUCT_STARTMENU_REGVAL "product:StartMenuDir"
!include "MUI.nsh"
Page custom PageAlreadyInstalled PageAlreadyInstalledLeave
!insertmacro MUI_PAGE_DIRECTORY
; Start menu page
var ICONS_GROUP
!define MUI_STARTMENUPAGE_NODISABLE
!define MUI_STARTMENUPAGE_DEFAULTFOLDER "product"
!define MUI_STARTMENUPAGE_REGISTRY_ROOT "${PRODUCT_UNINST_ROOT_KEY}"
!define MUI_STARTMENUPAGE_REGISTRY_KEY "${PRODUCT_UNINST_KEY}"
!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "${PRODUCT_STARTMENU_REGVAL}"
!insertmacro MUI_PAGE_STARTMENU Application $ICONS_GROUP
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE "English"
ReserveFile "product.ini"
!insertmacro MUI_RESERVEFILE_INSTALLOPTIONS
Name "${PRODUCT_NAME} ${PRODUCT_VERSION}"
OutFile "install_product${PRODUCT_FILEVERSION}.exe"
InstallDir "$PROGRAMFILES\product"
LangString messNotPlugins ${LANG_RUSSIAN} "Âûáðàííûé êàòàëîã íå ÿâëÿåòñÿ êàòàëîãîì ïëàãèíîâ Far ïî óìîë÷àíèþ. Ïðîäîëæèòü?"
;LangString messNotPlugins ${LANG_ENGLISH} "Selected folder is not default folder for Far plugins. Continue?"
;LangString TEXT_IO_TITLE ${LANG_ENGLISH} "InstallOptions page"
;LangString TEXT_IO_SUBTITLE ${LANG_ENGLISH} "This is a page created using the InstallOptions plug-in."
LangString TEXT_IO_TITLE ${LANG_ENGLISH} "Îáíàðóæåíà ïðåäûäóùàÿ èíñòàëÿöèÿ"
LangString TEXT_IO_SUBTITLE ${LANG_RUSSIAN} "Íà êîìïüþòåðå óæå óñòàíîâëåíà product"
Function .onInit
InitPluginsDir
File /oname=$PLUGINSDIR\product.ini product.ini
FunctionEnd
Section "MainSection" SEC01
SetOutPath "$INSTDIR"
SectionEnd
Section -Post
WriteUninstaller "$INSTDIR\${PRODUCT_UNINSTALLER}"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "${PRODUCT_NAME}"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\${PRODUCT_UNINSTALLER}"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\${PRODUCT_UNINSTALLER},0"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "${PRODUCT_STARTMENU_REGVAL}" "$ICONS_GROUP"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}"
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}"
WriteRegDWORD ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "NoModify" "1"
WriteRegDWORD ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "NoRepair" "1"
SectionEnd
Function un.onInit
FunctionEnd
Section Uninstall
ReadRegStr $ICONS_GROUP ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "${PRODUCT_STARTMENU_REGVAL}"
; Delete self
Delete "$INSTDIR\${PRODUCT_UNINSTALLER}"
RMDir /r "$INSTDIR"
RMDir /r "$SMPROGRAMS\$ICONS_GROUP"
DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}"
SetAutoClose false
SectionEnd
Function CheckAlreadyInstalled
ReadRegStr $R0 "${PRODUCT_UNINST_ROOT_KEY}" "${PRODUCT_UNINST_KEY}" "UninstallString"
FunctionEnd
Function PageAlreadyInstalled
call CheckAlreadyInstalled
StrCmp $R0 "" 0 +2
Abort
ifFileExists $R0 showPage WasManuallyDeleted
WasManuallyDeleted:
Abort
showPage:
GetDlgItem $R4 $HWNDPARENT 1
EnableWindow $R4 0
!insertmacro MUI_HEADER_TEXT "$(TEXT_IO_TITLE)" "$(TEXT_IO_SUBTITLE)"
loop:
!insertmacro MUI_INSTALLOPTIONS_DISPLAY_RETURN "product.ini"
pop $0
messagebox mb_ok $0
strCmp $0 "success" 0 end0
call CheckAlreadyInstalled
StrCmp $R0 "" 0 loop
end0:
FunctionEnd
Function PageAlreadyInstalledLeave
ReadINIStr $0 "$PLUGINSDIR\product.ini" "Settings" "State"
StrCmp $0 0 done ; Next button?
StrCmp $0 2 btnUninstall
Abort
btnUninstall:
GetDlgItem $R4 $HWNDPARENT 1
EnableWindow $R4 1
ClearErrors
ExecWait '$R0 _?=$INSTDIR'
abort
done:
call CheckAlreadyInstalled
StrCmp $R0 "" next1
Abort
next1:
FunctionEnd
Custom Page :: Next button
17 posts
Add a messagebox to check whether it gets to your EnableWindow call and check whether the control handle is correct.
I spend 3 hours checking handles, they are okey. "Next" button gets enabled, but after uninstaller finshes, It turns back to disabled. Seems to me, nsis did that. I am sure my script doesnt disable it second time.
Can you please explain exactly what goes wrong? After the installation has finished, NSIS will disable the Next button.
this is picture just before the uninstall have finished.
When back window was show up, button 2 was disabled by my code.
When user launched uninstall, button 2 was enabled by my code.
So, now it is enabled.
but,if i click button 1 now, the button 2 will sudenly got disabled, and this is wrong.
When back window was show up, button 2 was disabled by my code.
When user launched uninstall, button 2 was enabled by my code.
So, now it is enabled.
but,if i click button 1 now, the button 2 will sudenly got disabled, and this is wrong.
This is exactly the same button. Cancel is always disabled when the uninstallation has finished.
So why this code does not enable the button ?
btnUninstall:
ClearErrors
ExecWait '$R0 _?=$INSTDIR'
GetDlgItem $R4 $HWNDPARENT 1
messageBox mb_ok "Here, $R4"
EnableWindow $R4 1
abort
btnUninstall:
ClearErrors
ExecWait '$R0 _?=$INSTDIR'
GetDlgItem $R4 $HWNDPARENT 1
messageBox mb_ok "Here, $R4"
EnableWindow $R4 1
abort
So you mean that the button is disabled after you close the uninstaller? The uninstaller has nothing to do with the installer.
When exactly does it enable the button? Does it wait for the installer?
Add some messageboxes before every step in your leave function.
When exactly does it enable the button? Does it wait for the installer?
Add some messageboxes before every step in your leave function.
YES. installer's button "Next" gets disabled after i call Abort in leave function. Please compile code i provide in first message, it compiles with no problem. I am attaching source and compiled exe
Add a messagebox before the other EnableWindow call, is that one called again?
No, EnableWindow is not called again. No code executed after Abort call.
So the first EnableWindows call (with the 0 parameter) is not called?
Do you get the same behavior if you do not run the uninstaller?
Do you get the same behavior if you do not run the uninstaller?
Yes, it is not called again. things are same if installer does not run at all.
This is minimal code that reproduce this bahavoir.
Function PageEnter
GetDlgItem $R4 $HWNDPARENT 1
EnableWindow $R4 0
sleep 500
messageBox mb_OK "disabled $R4"
!insertmacro MUI_HEADER_TEXT "$(TEXT_IO_TITLE)" "$(TEXT_IO_SUBTITLE)"
loop:
!insertmacro MUI_INSTALLOPTIONS_DISPLAY_RETURN "product.ini"
pop $0
goto loop
FunctionEnd
Function PageLeave
GetDlgItem $R4 $HWNDPARENT 1
EnableWindow $R4 1
sleep 500
MessageBox mb_ok "enabled $R4"
Abort
FunctionEnd
This is minimal code that reproduce this bahavoir.
Function PageEnter
GetDlgItem $R4 $HWNDPARENT 1
EnableWindow $R4 0
sleep 500
messageBox mb_OK "disabled $R4"
!insertmacro MUI_HEADER_TEXT "$(TEXT_IO_TITLE)" "$(TEXT_IO_SUBTITLE)"
loop:
!insertmacro MUI_INSTALLOPTIONS_DISPLAY_RETURN "product.ini"
pop $0
goto loop
FunctionEnd
Function PageLeave
GetDlgItem $R4 $HWNDPARENT 1
EnableWindow $R4 1
sleep 500
MessageBox mb_ok "enabled $R4"
Abort
FunctionEnd
Another minimal example. Do anybody hear me?
Function PageEnter
GetDlgItem $R4 $HWNDPARENT 1
EnableWindow $R4 0
!insertmacro MUI_INSTALLOPTIONS_DISPLAY "product.ini"
FunctionEnd
Function PageLeave
GetDlgItem $R4 $HWNDPARENT 1
EnableWindow $R4 1
Abort
FunctionEnd It seems to restore the button state. For now you can use display a messagebox if uninstall was not clicked.
Ok. For now i'll not use such page at all; unil next nsis release, i'll use messagebox in .onInit. Thank you.
fixed.