Hello,
in the Directory Page, I would start from a specified folder when clicking the Browse button instead to start from the User directory and would also keep the directory structure tree completely so setup user can choose among all disk directories instead from only the tree of the specified folder.
How to make it ? Which is the code ?
To start from a specified folder by Browse button in Directory Page
32 posts
bland NSIS, use...Originally Posted by Maxim30 View Postin the Directory Page, I would start from a specified folder when clicking the Browse button instead to start from the User directory
MUI2, use...
Var myDirVar
Function .onInit
StrCpy $myDirVar "$PROGRAMFILES\NSIS\"
FunctionEnd
PageEx directory
DirVar $myDirVar
PageExEnd
nsDialogs (manually calling the code), use...
myDirVar
Function .onInit
StrCpy $myDirVar "$PROGRAMFILES\NSIS\"
FunctionEnd
!define MUI_DIRECTORYPAGE_VARIABLE $myDirVar
!insertmacro MUI_PAGE_DIRECTORY
nsDialogs::SelectFolderDialog "Title" "$PROGRAMFILES\NSIS\"
Not sure what you mean by that - but if you mean 'expand all the folders and subfolders on the user's entire drive'... bad idea 😉 Just let the user expand if they desire to install to a specific location.Originally Posted by Maxim30 View Postand would also keep the directory structure tree completely so setup user can choose among all disk directories instead from only the tree of the specified folder.
I mean to show to user the starting folder I preset and from there he/she can choose (expanding or not) any other directory.
The MUI2 version code works as I want.
But additionaly in my script I have the following code:
this first functon to determine whether a previous installation was made and then whether the system is 32 or 64 bit ...
Function MyGUIInit
ReadRegStr $0 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${Nome}" "NSIS:InstallDir"
${If} $0 != ""
StrCpy $INSTDIR $0
${ElseIf} ${RunningX64}
StrCpy $INSTDIR "$PROGRAMFILES64\${Nome}"
${Else}
StrCpy $INSTDIR "$PROGRAMFILES32\${Nome}"
${EndIf}
Function End
and this second function to append always the string ${Nome} to the choosen path ...
Function .onVerifyInstDir
${WordAdd} "$INSTDIR" "\" "+${Nome}" $INSTDIR
FunctionEnd
And instead with my two functions above the MUI2 code you proposed does not work, starting the installation folder still always from User directory; if I write only $PROGRAMFILES64 (and $PROGRAMFILES32) instead of $PROGRAMFILES64\${Nome} (and $PROGRAMFILES32\${Nome}) then the code works as I want.
How to fix my code above with yours ?
The MUI2 version code works as I want.
But additionaly in my script I have the following code:
this first functon to determine whether a previous installation was made and then whether the system is 32 or 64 bit ...
Function MyGUIInit
ReadRegStr $0 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${Nome}" "NSIS:InstallDir"
${If} $0 != ""
StrCpy $INSTDIR $0
${ElseIf} ${RunningX64}
StrCpy $INSTDIR "$PROGRAMFILES64\${Nome}"
${Else}
StrCpy $INSTDIR "$PROGRAMFILES32\${Nome}"
${EndIf}
Function End
and this second function to append always the string ${Nome} to the choosen path ...
Function .onVerifyInstDir
${WordAdd} "$INSTDIR" "\" "+${Nome}" $INSTDIR
FunctionEnd
And instead with my two functions above the MUI2 code you proposed does not work, starting the installation folder still always from User directory; if I write only $PROGRAMFILES64 (and $PROGRAMFILES32) instead of $PROGRAMFILES64\${Nome} (and $PROGRAMFILES32\${Nome}) then the code works as I want.
How to fix my code above with yours ?
the reason that doesn't work is because the folder selection dialog can only be pointed to folders that exist. So when you append ${Nome} (let's say its value is 'myDir'), then $PROGRAMFILES\myDir\ must be a folder that exists for the browser to open in that location.
The simplest solution would be to browse to the main folder (in this case, $PROGRAMFILES), and append the ${Nome} at a later point.
The simplest solution would be to browse to the main folder (in this case, $PROGRAMFILES), and append the ${Nome} at a later point.
Or alternatively I could append the string ${Nome} only when the Directory Page Browse button is clicked.
How can I add/modify actions when the Browse button is clicked ?
How can I add/modify actions when the Browse button is clicked ?
I don't think there are specific callbacks for the user pressing the browse button or having selected a folder in MUI2. You could easily set something up using a custom dialog, though.
And do they exist for normal MUI ?
You could have a peek at the .onVerifyInstDir callback - that gets called whenever the user changes the installation directory; should be able to use that with MUI2 as well, come to think of it.
Ok. If I use the instructions FindWindow and GetDlgItem on the Browse button, how can I write the code to have the installer to open the $PROGRAMFILES32 (or $PROGRAMFILES64) folder instead of preset $PROGRAMFILES32\${Nome} (or $PROGRAMFILES64\${Nome}) every time user click on the Browse button ?
You don't use that - you just use the $myDirVar (or $INSTDIR if you're not using the custom dir var ).
For example:
For example:
!include "nsDialogs.nsh"
!include "MUI2.nsh"
OutFile "test.exe"
Section
SectionEnd
!define Nome "NSIS"
Var myDirVar
!define MUI_DIRECTORYPAGE_VARIABLE $myDirVar
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE myFunction
!insertmacro MUI_PAGE_DIRECTORY
Function .onInit
; Default install location / install location read from registry
StrCpy $myDirVar "$PROGRAMFILES\"
FunctionEnd
Function myFunction
StrCpy $INSTDIR "$myDirVar\${Nome}"
MessageBox MB_OK "User selected install location: '$myDirVar'$\r$\nActually installing to: '$INSTDIR'"
FunctionEnd
!insertmacro MUI_LANGUAGE "English"
In any case how can I write a code to perform an action after clicking the Browse button in the Directory Page ?
But that is a hack.. .onVerifyInstDir gets a message for every folder change within the dialog (and the user typing in the main field); it assumes that the first folder opening when the user presses the browse button is the Desktop folder.
!include "LogicLib.nsh"
!include "nsDialogs.nsh"
!include "MUI2.nsh"
OutFile "test.exe"
Section
SectionEnd
!define Nome "NSIS"
Var myDirVar
!define MUI_DIRECTORYPAGE_VARIABLE $myDirVar
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE myFunction
!insertmacro MUI_PAGE_DIRECTORY
Function .onInit
; Default install location / install location read from registry
StrCpy $myDirVar "$PROGRAMFILES\"
FunctionEnd
Function .onVerifyInstDir
${If} "$myDirVar" == "$DESKTOP"
MessageBox MB_OK "User clicked browse button (or manually entered desktop location"
${EndIf}
FunctionEnd
Function myFunction
StrCpy $INSTDIR "$myDirVar\${Nome}"
MessageBox MB_OK "User selected install location: '$myDirVar'$\r$\nActually installing to: '$INSTDIR'"
FunctionEnd
!insertmacro MUI_LANGUAGE "English"
If you want better control, you'd want to use nsDialogs to build your own dialog.
But, again, you're not going to be able to manipulate much in the browse dialog.
I have tried this code but it does not work as I want:
!define MUI_PAGE_CUSTOMFUNCTION_SHOW MyDirPage
...
Function MyGUIInit
GetFunctionAddress $3 MyNewFolder ; get address of MyNewFolder function
FunctionEnd
Function MyDirPage
FindWindow $1 "#32770" "" $HWNDPARENT
GetDlgItem $2 $1 1001 ; Get Browse button Dialog Item
nsDialogs::OnClick $2 $3 ; checks clicks on Browse button and calls MyNewFolder function
FunctionEnd
Function MyNewFolder
; appropriate instructions here
MessageBox MB_OK "Browse button clicked" ; test by now
FunctionEnd
Function .onVerifyInstDir
${WordAdd} "$INSTDIR" "\" "+${Nome}" $INSTDIR ; appends string ${Nome} to the choosen path by Browse button
FunctionEnd
The GetDlgItem instruction works because I tested it with the instruction "EnableWindow $2 0" (disable Browse button). But the function MyNewFolder seems to not work because the MessageBox test is never shown:
are the variables $2, $3 and the instructions GetFunctionAddress, nsDialogs::OnClick correct ?
!define MUI_PAGE_CUSTOMFUNCTION_SHOW MyDirPage
...
Function MyGUIInit
GetFunctionAddress $3 MyNewFolder ; get address of MyNewFolder function
FunctionEnd
Function MyDirPage
FindWindow $1 "#32770" "" $HWNDPARENT
GetDlgItem $2 $1 1001 ; Get Browse button Dialog Item
nsDialogs::OnClick $2 $3 ; checks clicks on Browse button and calls MyNewFolder function
FunctionEnd
Function MyNewFolder
; appropriate instructions here
MessageBox MB_OK "Browse button clicked" ; test by now
FunctionEnd
Function .onVerifyInstDir
${WordAdd} "$INSTDIR" "\" "+${Nome}" $INSTDIR ; appends string ${Nome} to the choosen path by Browse button
FunctionEnd
The GetDlgItem instruction works because I tested it with the instruction "EnableWindow $2 0" (disable Browse button). But the function MyNewFolder seems to not work because the MessageBox test is never shown:
are the variables $2, $3 and the instructions GetFunctionAddress, nsDialogs::OnClick correct ?
I don't think you can use nsDialogs' event handlers on existing buttons.
I'm also somewhat confused by what you're actually trying to do.
You want the Browse dialog to open in a specific location, in this case $PROGRAMFILES. Then when the user has selected a folder, you want to append ${Nome}. Is that correct? If so - then the example two posts back should be all that you need.
If you also want to -show- the user that you appended ${Nome}, then you'd have to check if the text on the directory input field has changed, append ${Nome} if it's not already appended, etc. etc.
( all of which is a lot easier with a custom dialog )
I'm also somewhat confused by what you're actually trying to do.
You want the Browse dialog to open in a specific location, in this case $PROGRAMFILES. Then when the user has selected a folder, you want to append ${Nome}. Is that correct? If so - then the example two posts back should be all that you need.
If you also want to -show- the user that you appended ${Nome}, then you'd have to check if the text on the directory input field has changed, append ${Nome} if it's not already appended, etc. etc.
( all of which is a lot easier with a custom dialog )
Yes, I want to append the string ${Nome} at end of the path choosen by user, and I have realized it.
Furtherly when user clicks on Browse button I want to show to him/her the $PROGRAMFILES32 or $PROGRAMFILES64 folder (and then its subfolders branch too) instead to show to him/her the default User folder, but I have not realized it: how to make it ?
Furtherly when user clicks on Browse button I want to show to him/her the $PROGRAMFILES32 or $PROGRAMFILES64 folder (and then its subfolders branch too) instead to show to him/her the default User folder, but I have not realized it: how to make it ?
As far as I can see (at least on Windows 7) the Browse dialog never opens to the currently chosen install directory. Is this not the case on XP? I suggest you post a feature request or add the feature yourself.
Stu
Stu
Really clicking on the Browse button the current install folder is opened (with its subfolders branch) if it is existing, and this is I want.
Instead if it is not existing then the User folder is opened (default), and this is not I want; I am seaching to open at least the $programfiles32 or $programfiles64 folders in this case, and perhaps it is possible using the nsDislogs::OnClick instruction: is it ?
Instead if it is not existing then the User folder is opened (default), and this is not I want; I am seaching to open at least the $programfiles32 or $programfiles64 folders in this case, and perhaps it is possible using the nsDislogs::OnClick instruction: is it ?
you're pretty much going to have to edit/make some code to do what you're wanting - it's relatively simple as the callback function to the SHBrowseForFolder just needs to be adjusted to change to a different folder path if the first isn't valid though i've no idea where in NSIS that is being done (which probably doesn't help) but it's a trivial thing to do in response to the BFFM_INITIALIZED message in the OS api's callback function.
-daz
-daz
Or you can just change the folder passed to the browse dialog when the folder doesn't exist - you can check all of this with NSIS -before- you open the dialog.
( This works fine in Windows 7 as well )
Expanding that folder or the nodes in the tree below that folder, however, is another matter entirely; in theory it can be done, but you'd probably have to change the code (unless a tricky nsDialogs timer could send the command to expand the currently selected item in the tree).
( This works fine in Windows 7 as well )
Expanding that folder or the nodes in the tree below that folder, however, is another matter entirely; in theory it can be done, but you'd probably have to change the code (unless a tricky nsDialogs timer could send the command to expand the currently selected item in the tree).
!include "LogicLib.nsh"
!include "nsDialogs.nsh"
!include "MUI2.nsh"
OutFile "test.exe"
Section
SectionEnd
Var myDirVar
!define MUI_DIRECTORYPAGE_VARIABLE $myDirVar
!insertmacro MUI_PAGE_DIRECTORY
Function .onInit
${If} ${FileExists} "$PROGRAMFILES\SomeFolder\*.*"
StrCpy $myDirVar "$PROGRAMFILES\SomeFolder\"
${Else}
StrCpy $myDirVar "$PROGRAMFILES\"
${EndIf}
FunctionEnd
!insertmacro MUI_LANGUAGE "English"
or that approach 🙂 (had thought it had already been tried though i did only skim through to the end of the thread).
-daz
-daz
I reexplain the situation:
at setup start I have as shown in attached screenshot 1: what I have and also wanted.
After clicking on the Browse button I would as shown in attached screenshot 2: what wanted.
After clicking on Browse button I have instead as shown in attached screenshot 3: what I get now instead and to avoid.
at setup start I have as shown in attached screenshot 1: what I have and also wanted.
After clicking on the Browse button I would as shown in attached screenshot 2: what wanted.
After clicking on Browse button I have instead as shown in attached screenshot 3: what I get now instead and to avoid.
Yeh we get it. Did you try Animaether's code?
Stu
Stu
No. Which of the last three should I try ?Originally Posted by Afrow UK View PostYeh we get it. Did you try Animaether's code?
Stu
The statement
${If} ${FileExists} "$PROGRAMFILES\SomeFolder\*.*"
is always false because my prompted folder is new non existent so there is not a special in the code, it does nothing.
${If} ${FileExists} "$PROGRAMFILES\SomeFolder\*.*"
is always false because my prompted folder is new non existent so there is not a special in the code, it does nothing.
Did you try it or not? There's an ELSE statement in the code in case you didn't see it.
Edit: I have tried it and it works.
Stu
Edit: I have tried it and it works.
Stu
However, it is the same as just using InstallDir $PROGRAMFILES. This is what I said initially: whatever is in the directory box AND IT EXISTS will cause the Browse dialog to open to it. If the path does not exist then Browse will go to the default (root/user). So the only thing you can do is set InstallDir $PROGRAMFILES and then perhaps add:
I think if you want to do this properly you need to change NSIS itself or post a feature request - i.e. get Browse to open in the parent folder of the current install directory if that exists, or go to the parent of that if it exists etc
Stu
This will ensure your app name is appended to the end (use if you need that to happen). Notice that when you click Browse again you are back to root!Function .onVerifyInstDir
StrCpy $INSTDIR `$INSTDIR\${Name}`
FunctionEnd
I think if you want to do this properly you need to change NSIS itself or post a feature request - i.e. get Browse to open in the parent folder of the current install directory if that exists, or go to the parent of that if it exists etc
Stu
Yes, I think it is better to post a feature request to make Browse to open in the parent folder of the current install directory if the last path portion is not existent.Originally Posted by Afrow UK View PostHowever, it is the same as just using InstallDir $PROGRAMFILES. This is what I said initially: whatever is in the directory box AND IT EXISTS will cause the Browse dialog to open to it. If the path does not exist then Browse will go to the default (root/user). So the only thing you can do is set InstallDir $PROGRAMFILES and then perhaps add:
This will ensure your app name is appended to the end (use if you need that to happen). Notice that when you click Browse again you are back to root!Function .onVerifyInstDir
StrCpy $INSTDIR `$INSTDIR\${Name}`
FunctionEnd
I think if you want to do this properly you need to change NSIS itself or post a feature request - i.e. get Browse to open in the parent folder of the current install directory if that exists, or go to the parent of that if it exists etc
Stu
!include "LogicLib.nsh"
!include "nsDialogs.nsh"
!include "MUI2.nsh"
!include "FileFunc.nsh"
OutFile "test.exe"
Section
SectionEnd
Var myDirVar
!define MUI_DIRECTORYPAGE_VARIABLE $myDirVar
!insertmacro MUI_PAGE_DIRECTORY
Function .onInit
StrCpy $myDirVar "$PROGRAMFILES\NSIS\ExampleZ\"
${GetRoot} "$myDirVar" $0
${DoUntil} ${FileExists} "$myDirVar"
${GetParent} "$myDirVar" $myDirVar
${Loop}
${If} "$myDirVar" == "$0"
/* Installation would end up in ROOT. Switching to default instead. */
StrCpy $myDirVar "$PROGRAMFILES"
${EndIf}
StrCpy $myDirVar "$myDirVar\"
FunctionEnd
!insertmacro MUI_LANGUAGE "English"