I have a NSIS script with two components to uninstall. If the user unchecks both components in the "Choose components" page, the Uninstall button is still active, and the uninstall process can continue without actually uninstalling anything. Is there any easy way to disable the "Uninstall" button if no component is selected?
The code for selecting the uninstaller section is the following:
# Macro for selecting uninstaller sections
!macro SELECT_UNSECTION SECTION_NAME UNSECTION_ID
Push $R0
ReadRegStr $R0 HKLM "${REGKEY}\Components" "${SECTION_NAME}"
StrCmp $R0 1 0 next${UNSECTION_ID}
!insertmacro SelectSection "${UNSECTION_ID}"
GoTo done${UNSECTION_ID}
next${UNSECTION_ID}:
!insertmacro UnselectSection "${UNSECTION_ID}"
done${UNSECTION_ID}:
Pop $R0
!macroend
Thanks in advance!
UninstPage Components un.InitComponents
UninstPage InstFiles
Section "un.Foo" SID_FOO
SectionEnd
Section /o "un.Bar" SID_BAR
SectionEnd
!include LogicLib.nsh
Function un.InitComponents
;!insertmacro SELECT_UNSECTION SECTION_NAME ...
Call un.onSelChange ; Make sure the initial button state is correct
FunctionEnd
Function un.onSelChange
GetDlgItem $1 $hwndParent 1
${If} ${SectionIsSelected} ${SID_FOO}
${OrIf} ${SectionIsSelected} ${SID_BAR}
EnableWindow $1 1
${Else}
EnableWindow $1 0
${EndIf}
FunctionEnd
Related
I removed info for available space but the install button is still disabled when there is no enough space for the installation itself. I want to make "install" button always enabled. I tried this but with no success:
Function .onInit
Call enableInstallBtn
FunctionEnd
Function enableInstallBtn
GetDlgItem $0 $hWndParent 1 ; Get button handle
EnableWindow $0 1
FunctionEnd
.onInit is executed before the UI exists. The documentation tells you to set dirverify to leave:
RequestExecutionLevel User
InstallDir $temp
!include MUI2.nsh
!include LogicLib.nsh
!define MUI_DIRECTORYPAGE_VERIFYONLEAVE
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE verifydir
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE "English"
Function verifydir
GetInstDirError $0
${If} $0 = 1
MessageBox MB_IconStop "Invalid installation directory!"
Abort
${EndIf}
FunctionEnd
Section
AddSize 999999999 ; I'm huge
SectionEnd
I'm making use of optional installation of components in NSIS installer as shown in Controlling Available Install Options on the NSIS wiki.
This works fine, dependent on what options the user has chosen, the related parts are installed.
But now there is a problem with the start menu entries which come in a separate section:
Section -startmenu
SetShellVarContext all
CreateDirectory "$SMPROGRAMS\MyInstall"
CreateShortCut "$SMPROGRAMS\MyInstallOpenAPC\Editor1.lnk" "$INSTDIR\Editor1.exe" "" "$INSTDIR\icon.ico" 0
CreateShortCut "$SMPROGRAMS\MyInstallOpenAPC\Editor2.lnk" "$INSTDIR\Editor2.exe" "" "$INSTDIR\icon.ico" 0
CreateShortCut "$SMPROGRAMS\MyInstallOpenAPC\Editor3.lnk" "$INSTDIR\Editor3.exe" "" "$INSTDIR\icon.ico" 0
CreateShortCut "$SMPROGRAMS\MyInstallOpenAPC\Editor4.lnk" "$INSTDIR\Editor4.exe" "" "$INSTDIR\icon.ico" 0
Sectionend
Dependent on the optionally installed packages I want to create only some of the start menu entries.
How can this be done? How can I create a relation between start menu entries and the installed sections?
You can check if the relevant component (section) is selected:
!include LogicLib.nsh
InstallDir "$ProgramFiles\MyApp"
Page Components
Page InstFiles
Section "Foo" SID_FOO
SetOutPath "$InstDir\Foo"
; ...
SectionEnd
Section "Bar" SID_BAR
SetOutPath "$InstDir\Bar"
; ...
SectionEnd
Section "Start menu shortcuts"
SetShellVarContext all
${If} ${SectionIsSelected} ${SID_FOO}
CreateDirectory "$SMPROGRAMS\MyApp"
CreateShortcut "$SMPROGRAMS\MyApp\Foo.lnk" "$InstDir\Foo\Foo.exe"
${EndIf}
${If} ${SectionIsSelected} ${SID_BAR}
CreateDirectory "$SMPROGRAMS\MyApp"
CreateShortcut "$SMPROGRAMS\MyApp\Bar.lnk" "$InstDir\Bar\Bar.exe"
${EndIf}
SectionEnd
Trying to use an NSI script that works with 2.46 Unicode, in the new version 3, this line:
!insertmacro UAC_AsUser_ExecShell '' '$INSTDIR\test.exe' '--openbrowser' '' SW_SHOWNORMAL
produces the following error:
!undef: "_UAC_ParseDefineFlags_orin_f2" not defined!
Error in macro _UAC_ParseDefineFlags_orin on macroline 12
Error in macro _UAC_ParseDefineFlags_Begin on macroline 6
Error in macro _UAC_ParseDefineFlagsToInt on macroline 1
Error in macro UAC_AsUser_Call on macroline 5
Error in macro UAC_AsUser_ExecShell on macroline 11
Error in script "c:\my.nsi" on line 308 -- aborting creation process
There is a similar, unanswered question, back from a year ago.
My question:
How to use the UAC plug-in with NSIS 3?
Using UAC plug-in v0.2.4c (20150526) from the wiki I can't reproduce your error with a simple clone of UAC_Basic.nsi in NSIS v3.01:
Unicode true
!addplugindir ".\plugins\x86-unicode" ; Only required if you have not copied the .dll
!define S_NAME "UAC minimal test ${NSIS_PACKEDVERSION}"
Name "${S_NAME}"
OutFile "${S_NAME}.exe"
RequestExecutionLevel user ; << Required, you cannot use admin!
InstallDir "$ProgramFiles\${S_NAME}"
!include UAC.nsh
!include MUI2.nsh
!macro Init thing
uac_tryagain:
!insertmacro UAC_RunElevated
${Switch} $0
${Case} 0
${IfThen} $1 = 1 ${|} Quit ${|} ;we are the outer process, the inner process has done its work, we are done
${IfThen} $3 <> 0 ${|} ${Break} ${|} ;we are admin, let the show go on
${If} $1 = 3 ;RunAs completed successfully, but with a non-admin user
MessageBox mb_YesNo|mb_IconExclamation|mb_TopMost|mb_SetForeground "This ${thing} requires admin privileges, try again" /SD IDNO IDYES uac_tryagain IDNO 0
${EndIf}
;fall-through and die
${Case} 1223
MessageBox mb_IconStop|mb_TopMost|mb_SetForeground "This ${thing} requires admin privileges, aborting!"
Quit
${Case} 1062
MessageBox mb_IconStop|mb_TopMost|mb_SetForeground "Logon service not running, aborting!"
Quit
${Default}
MessageBox mb_IconStop|mb_TopMost|mb_SetForeground "Unable to elevate , error $0"
Quit
${EndSwitch}
SetShellVarContext all
!macroend
Function .onInit
!insertmacro Init "installer"
FunctionEnd
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!define MUI_FINISHPAGE_RUN
!define MUI_FINISHPAGE_RUN_FUNCTION PageFinishRun
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_LANGUAGE "English"
Section
SectionEnd
Function PageFinishRun
!insertmacro UAC_AsUser_ExecShell '' '$WinDir\notepad.exe' '--openbrowser' '' SW_SHOWNORMAL
FunctionEnd
Digging an old thread:
I had the same problem, the UAC plugin on wiki has a small change compared to the version I was using with NSIS 2.x.
That small change fixed the issue
I want to pin shortcut to taskbar in windows 10. Script works fine but my utily is detected as malware trojan. Microsoft has removed the verb and this could be the reason for the same. So is there any alternative way to pin/unpin any program programatically.
OutFile "C:\PinUnpinExe\PinUnpinShortcut.exe"
!include 'StdUtils.nsh'
!include FileFunc.nsh
SilentInstall silent
RequestExecutionLevel user ;no elevation needed
ShowInstDetails hide
var inputParam
Section
${GetParameters} $inputParam
System::Call "kernel32::GetCurrentDirectory(i ${NSIS_MAX_STRLEN}, t .r0)"
${StdUtils.InvokeShellVerb} $0 "$0" "abc.exe" $inputParam
SectionEnd
This line is detected as virus.
${StdUtils.InvokeShellVerb} $0 "$0" "abc.exe" $inputParam
I'm ok with the other language solutions too.
Don't programmatically pin shortcuts, the taskbar is a place for users to put their favorite icons!
To unpin you can do this (NSIS 3+):
!include "LogicLib.nsh"
!include "Win\COM.nsh"
!macro UnpinShortcut lnkpath
Push $0
Push $1
!insertmacro ComHlpr_CreateInProcInstance ${CLSID_StartMenuPin} ${IID_IStartMenuPinnedList} r0 ""
${If} $0 P<> 0
System::Call 'SHELL32::SHCreateItemFromParsingName(ws, p0, g "${IID_IShellItem}", *p0r1)' "${lnkpath}"
${If} $1 P<> 0
${IStartMenuPinnedList::RemoveFromList} $0 '(r1)'
${IUnknown::Release} $1 ""
${EndIf}
${IUnknown::Release} $0 ""
${EndIf}
Pop $1
Pop $0
!macroend
Section Uninstall
!insertmacro UnpinShortcut "$SMPrograms\MyApp.lnk"
SectionEnd
I want to create a dual installer for an application, which either installs it as portable or normal version.
For the portable version, I don't want to require admin rights. For the normal version, I need admin rights for adding the application to the start menu and other things.
Is there a way to prompt the user for admin rights when starting the actual installation? Maybe with a plug-in? I'm looking for something like RequestExecutionLevel admin inside a section.
RequestExecutionLevel highest will force members of the administrator group to elevate while normal users can run it with no UAC interaction. This example does not elevate for you because doing that is tricky, UAC is broken in certain scenarios and it would require more code to do it correctly...
RequestExecutionLevel highest
Var InstMode
!include nsDialogs.nsh
!include Sections.nsh
!include LogicLib.nsh
Page Custom InstallModePageInit InstallModePageLeave
Page InstFiles
Section "StartMenu shortcuts" SEC_SM
; CreateShortcut ...
SectionEnd
Section "" SEC_UNINST
; WriteUninstaller & registry
SectionEnd
Function InstallModePageInit
nsDialogs::Create 1018
Pop $0
${NSD_CreateRadioButton} 20u 30u 100% 12u "Normal install"
Pop $1
${NSD_CreateRadioButton} 20u 50u 100% 12u "Portable install"
Pop $2
${If} $InstMode = 0
${NSD_Check} $1
${Else}
${NSD_Check} $2
${EndIf}
nsDialogs::Show
FunctionEnd
Function InstallModePageLeave
${NSD_GetState} $2 $InstMode
${If} $InstMode = 0
!insertmacro SelectSection ${SEC_SM}
!insertmacro SelectSection ${SEC_UNINST}
UserInfo::GetAccountType
Pop $0
${If} $0 != "Admin"
MessageBox mb_iconstop "Administrator privileges required, please restart installer to continue..."
Abort
${EndIf}
${Else}
!insertmacro UnselectSection ${SEC_SM}
!insertmacro UnselectSection ${SEC_UNINST}
${EndIf}
FunctionEnd