|
|
#1 |
|
Junior Member
Join Date: Apr 2009
Posts: 33
|
Start Menu Folder displays "0" in UAC plug in sample
Hi All,
I downloaded the UAC plugin from NSIS' site and along with the plug in are some samples for it, I came across "UAC_GetUserShellFolderPath.nsi." It works great but there seems to be a small problem with it. When you get to the installation page that says "Choose Start Menu Folder," the destination folder for the start menu by default is "0" when you select "user" for install type, and "1" when you select "admin" for install type. It's suppose to display the name of your application by default, not a number. Please help... Here's the script of the sample. /* This sample supports two modes, installing as a normal user (single user install) AND as admin (all users install) This sample uses the registry plugin, so you need to download that if you don't already have it */ !define APPNAME "UAC_RealWorldFullyLoadedDualMode" !define ELEVATIONTITLE "${APPNAME}: Elevate" ;displayed during elevation on our custom page !define SMSUBDIR "${APPNAME}" !define UNINSTALLER_NAME "Uninstall ${APPNAME}.exe" !define UNINSTALLER_REGSECTION "${APPNAME}" !define RegPath.MSUninstall "Software\Microsoft\Windows\CurrentVersion\Uninstall" Name "${APPNAME}" OutFile "${APPNAME}.exe" ShowInstDetails show SetCompressor LZMA RequestExecutionLevel user /* RequestExecutionLevel REQUIRED! */ !include MUI.nsh !include UAC.nsh !include LogicLib.nsh !include Registry.nsh !include nsDialogs.nsh ;for our custom page !include FileFunc.nsh ;we need to parse the command line !insertmacro GetParameters !insertmacro GetOptions !define MUI_CUSTOMFUNCTION_ABORT onAbort !define MUI_CUSTOMFUNCTION_GUIINIT onGuiInit !define MUI_COMPONENTSPAGE_NODESC !define MUI_FINISHPAGE_NOAUTOCLOSE !define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\llama-blue.ico" !define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\llama-blue.ico" !define MUI_WELCOMEPAGE_TITLE_3LINES var InstMode # 0: Single user, 1:All users, >1:elevated instance, perform page jump var hKey # Reg hive var hSelModeAdminRadio /*!define MUI_CUSTOMFUNCTION_ABORT onUserAbort Function onUserAbort messagebox mb_ok onUserAbort FunctionEnd */ !macro SetMode IsAdmin !if "${IsAdmin}" > 0 SetShellVarContext all StrCpy $InstMode 1 StrCpy $hKey HKLM !else SetShellVarContext current StrCpy $InstMode 0 StrCpy $hKey HKCU !endif !macroend Function .OnInit !insertmacro SetMode 0 ${GetParameters} $R9 ${GetOptions} "$R9" UAC $0 ;look for special /UAC:???? parameter (sort of undocumented) ${Unless} ${Errors} UAC::IsAdmin ${If} $0 < 1 SetErrorLevel 666 ;special return value for outer instance so it knows we did not have admin rights Quit ${EndIf} !insertmacro SetMode 1 StrCpy $InstMode 2 ${EndIf} FunctionEnd Function onGuiInit ${If} $InstMode >= 2 ${UAC.GetOuterInstanceHwndParent} $0 ${If} $0 <> 0 System::Call /NOUNLOAD "*(i,i,i,i)i.r1" System::Call /NOUNLOAD 'user32::GetWindowRect(i $0,i r1)i.r2' ${If} $2 <> 0 System::Call /NOUNLOAD "*$1(i.r2,i.r3)" System::Call /NOUNLOAD 'user32::SetWindowPos(i $hwndParent,i0,ir2,ir3,i0,i0,i 4|1)' ${EndIf} ShowWindow $hwndParent ${SW_SHOW} ShowWindow $0 ${SW_HIDE} ;hide outer instance installer window System::Free $1 ${EndIf} ${EndIf} FunctionEnd Function Un.OnInit !insertmacro SetMode 0 ReadRegDWORD $0 HKLM "${RegPath.MSUninstall}\${UNINSTALLER_REGSECTION}" InstMode ;We saved the "mode" in the installer ${If} $0 U> 0 ; If it was installed for all users, we have to be admin to uninstall it ${UAC.U.Elevate.AdminOnly} "${UNINSTALLER_NAME}" !insertmacro SetMode 1 ${EndIf} FunctionEnd Function onAbort ${UAC.Unload} FunctionEnd ${UAC.AutoCodeUnload} 1 ;Auto-generate .OnInstFailed and .OnInstSuccess functions !define MUI_PAGE_CUSTOMFUNCTION_PRE SkipPageInElvModePreCB !insertmacro MUI_PAGE_WELCOME Page Custom ModeSelectionPageCreate ModeSelectionPageLeave !define MUI_PAGE_CUSTOMFUNCTION_PRE CmpntsPreCB !insertmacro MUI_PAGE_COMPONENTS !define MUI_PAGE_CUSTOMFUNCTION_PRE DirPreCB !insertmacro MUI_PAGE_DIRECTORY !insertmacro MUI_PAGE_STARTMENU 1 $9 !insertmacro MUI_PAGE_INSTFILES !define MUI_FINISHPAGE_TITLE_3LINES !define MUI_FINISHPAGE_RUN !define MUI_FINISHPAGE_RUN_FUNCTION FinishRunCB !insertmacro MUI_PAGE_FINISH !define MUI_WELCOMEPAGE_TITLE_3LINES !insertmacro MUI_UNPAGE_WELCOME !insertmacro MUI_UNPAGE_INSTFILES !insertmacro MUI_LANGUAGE "English" Function CmpntsPreCB GetDlgItem $0 $hwndparent 3 ${IfThen} $InstMode >= 1 ${|} EnableWindow $0 0 ${|} ;prevent user from going back and selecting single user so noobs don't end up installing as the wrong user FunctionEnd Function SkipPageInElvModePreCB ${IfThen} $InstMode > 1 ${|} Abort ${|} ;skip this page so we get to the mode selection page FunctionEnd Function ModeSelectionPageCreate ${If} $InstMode > 1 StrCpy $InstMode 1 Abort ;skip this page and contine where the "parent" would have gone ${EndIf} !insertmacro MUI_HEADER_TEXT_PAGE "Select install type" "Blah blah blah blah" nsDialogs::Create /NOUNLOAD 1018 Pop $0 ${NSD_CreateLabel} 0 20u 75% 20u "Blah blah blah blah select install type..." Pop $0 System::Call "advapi32::GetUserName(t.r0, *i ${NSIS_MAX_STRLEN}r1) i.r2" ${NSD_CreateRadioButton} 0 40u 75% 15u "Single User ($0)" Pop $0 ${IfThen} $InstMode U< 1 ${|} SendMessage $0 ${BM_SETCHECK} 1 0 ${|} ${NSD_CreateRadioButton} 0 60u 75% 15u "All users" Pop $hSelModeAdminRadio ${IfThen} $InstMode U> 0 ${|} SendMessage $hSelModeAdminRadio ${BM_SETCHECK} 1 0 ${|} nsDialogs::Show FunctionEnd !macro EnableCtrl dlg id state push $0 GetDlgItem $0 ${dlg} ${id} EnableWindow $0 ${state} pop $0 !macroend Function ModeSelectionPageLeave SendMessage $hSelModeAdminRadio ${BM_GETCHECK} 0 0 $9 UAC::IsAdmin ${If} $9 U> 0 ${AndIf} $0 U< 1 System::Call /NoUnload 'user32::GetWindowText(i $HwndParent,t.R1,i ${NSIS_MAX_STRLEN})' ;get original window title System::Call /NoUnload 'user32::SetWindowText(i $HwndParent,t "${ELEVATIONTITLE}")' ;set out special title StrCpy $2 "" ;reset special return, only gets set when sub process is executed, not when user cancels !insertmacro EnableCtrl $HWNDParent 1 0 ;Disable next button, just because it looks good ![]() ${UAC.RunElevatedAndProcessMessages} !insertmacro EnableCtrl $HWNDParent 1 1 System::Call 'user32::SetWindowText(i $HwndParent,t "$R1")' ;restore title ${If} $2 = 666 ;our special return, the new process was not admin after all MessageBox mb_iconExclamation "You need to login with an account that is a member of the admin group to continue..." Abort ${ElseIf} $0 = 1223 ;cancel Abort ${Else} ${If} $0 <> 0 ${If} $0 = 1062 MessageBox mb_iconstop "Unable to elevate, Secondary Logon service not running!" ${Else} MessageBox mb_iconstop "Unable to elevate, error $0 ($1,$2,$3)" ${EndIf} Abort ${EndIf} ${EndIf} Quit ;We now have a new process, the install will continue there, we have nothing left to do here ${EndIf} FunctionEnd Function DirPreCB ${If} $InstDir == "" ${If} $InstMode U> 0 StrCpy $InstDir "$PROGRAMFILES\${APPNAME}" ${Else} StrCpy $InstDir "$APPDATA\${APPNAME}" ${EndIf} ${EndIf} FunctionEnd Function FinishRunCB UAC::Exec "" "Notepad.exe" "$Windir\Win.INI" "$InstDir" FunctionEnd Function CreateSMShortcuts CreateDirectory "$SMPrograms\${SMSUBDIR}" CreateShortcut "$SMPrograms\${SMSUBDIR}\${APPNAME}.lnk" "$Windir\Notepad.exe" CreateShortcut "$SMPrograms\${SMSUBDIR}\Uninstall ${APPNAME}.lnk" "$InstDir\${UNINSTALLER_NAME}" FunctionEnd Function CreateDeskShortcuts CreateShortcut "$Desktop\${APPNAME}.lnk" "$Windir\Notepad.exe" FunctionEnd Section "!Required files" SectionIn RO SetOutPath - !insertmacro _UAC.DbgDetailPrint ;some debug info, useful during testing ;Install files here... WriteUninstaller "$InstDir\${UNINSTALLER_NAME}" ${registry::Write} "$hKey\${RegPath.MSUninstall}\${UNINSTALLER_REGSECTION}" DisplayName "${APPNAME}" REG_SZ $0 ${registry::Write} "$hKey\${RegPath.MSUninstall}\${UNINSTALLER_REGSECTION}" UninstallString "$InstDir\${UNINSTALLER_NAME}" REG_SZ $0 ${registry::Write} "$hKey\${RegPath.MSUninstall}\${UNINSTALLER_REGSECTION}" InstMode $InstMode REG_DWORD $0 ${registry::Unload} SectionEnd ; CREATING SHORTCUTS FOR THE INTERACTIVE USER IN A "ALL USERS" TYPE INSTALL IS BAD PRACTICE, ; BUT WE DO IT HERE FOR DEMONSTRATION PURPOSES Section "Startmenu Shortcuts" ${UAC.CallFunctionAsUser} CreateSMShortcuts SectionEnd Section "Desktop Shortcut" ${UAC.CallFunctionAsUser} CreateDeskShortcuts SectionEnd Section Uninstall Delete "$InstDir\${UNINSTALLER_NAME}" Delete "$SMPrograms\${SMSUBDIR}\${APPNAME}.lnk" Delete "$SMPrograms\${SMSUBDIR}\Uninstall ${APPNAME}.lnk" RMDir "$SMPrograms\${SMSUBDIR}" Delete "$Desktop\${APPNAME}.lnk" RMDir "$InstDir" ${registry: eleteKey} "$hKey\${RegPath.MSUninstall}\${UNINSTALLER_REGSECTION}" $0${registry::Unload} SectionEnd |
|
|
|
|
|
#2 |
|
Moderator
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 2,777
|
you should not use $9 as the startmenu variable, make a new var and define SMSUBDIR as that var (That code is just a example, and the startmenu folder name was hardcoded, it will be fixed in the next version)
IntOp $PostCount $PostCount + 1 |
|
|
|
|
|
#3 |
|
Junior Member
Join Date: Apr 2009
Posts: 33
|
My other question is that !insertmacro MUI_STARTMENU_GETFOLDER 1 $9 uses "1" before the variable $9. Usually what I see is !insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuFolder. What's the difference? thanks...
|
|
|
|
![]() |
|
|||||||
| Thread Tools | Search this Thread |
| Display Modes | |
|
|