Skip to content
⌘ NSIS Forum Archive

Directory browser window

5 posts

NhKPaNdA#

Directory browser window

Hello any and everyone.

Just recently I got into learning how to make installers with NSIS and I normally found answers to all my questions fairly quickly except for this one. I am making an installer for a little project and the guy in charge asked if there wasn't a way to make the install directory browser window into the more simplified windows explorer window.

The current window is as such:





And I want to ask if there is a way to make it appear as this instead:





The install only needs to choose the main folder and doesn't have to select a specific file.

Any help would be truly grateful in this matter and thanks in advance.
Anders#
The directory page uses the SHBrowseForFolder() Windows API function to choose a folder.

On Vista+ it is possible to use the newer IFileDialog with FOS_PICKFOLDERS but you would have to change the NSIS source and recompile or possibly use the button event plugin to do this. If you want to try the button event plugin then you would have to write the IFileDialog COM code with the system plugin. Seems like a lot of unnecessary work if you ask me...
NhKPaNdA#
So thanks a lot to Anders, I was somehow able to get the browse button to bring up the new browse window, but now when I choose a folder and accept it, it doesn't change the install directory path and I have no clue where I can get what was chosen from the browse window code to make it the new install directory. If you could kindly show me where I can find it that would help. Attached is the script of the installer.

Thanks in advance
Anders#
Try this:

!include LogicLib.nsh

Function BrowseForFolder
!define CLSID_FileOpenDialog {DC1C5A9C-E88A-4DDE-A5A1-60F82A20AEF7}
!define IID_IFileDialog {42F85136-DB7E-439C-85F1-E4075D135FC8}
!define CLSCTX_INPROC_SERVER 1
!define FOS_PICKFOLDERS 32
!define FOS_FORCEFILESYSTEM 64
!define SIGDN_FILESYSPATH 2147844096

Push $4
Push $3
Push $2
Push $1
Push $0

System::Call "ole32::CoCreateInstance(g '${CLSID_FileOpenDialog}', i 0, i ${CLSCTX_INPROC_SERVER}, g '${IID_IFileDialog}', *i .r0) i.r1"
${If} $1 == 0
StrCpy $4 "error"
System::Call "$0->9(i ${FOS_PICKFOLDERS}|${FOS_FORCEFILESYSTEM}) i.r1" ; IFileDialog::SetOptions
${If} $1 <> 0
System::Call "$0->2()" ; IFileDialog::Release
Goto end
${EndIf}
System::Call "$0->3(i 0) i.r1" ; IFileDialog::Show
${If} $1 <> 0
System::Call "$0->2()" ; IFileDialog::Release
Goto end
${EndIf}
System::Call "$0->20(*i .r2) i.r1" ; IFileDialog::GetResult
System::Call "$0->2()" ; IFileDialog::Release
${If} $1 == 0
System::Call "$2->5(i ${SIGDN_FILESYSPATH}, *i .r3) i.r1" ; IShellItem::GetDisplayName
${If} $1 == 0
System::Call "*$3(&w${NSIS_MAX_STRLEN} .r4)"
System::Call "ole32::CoTaskMemFree(i $3)"
${EndIf}
System::Call "$2->2()" ; IShellItem::Release
${EndIf}
${Else} ; fallback for pre-Vista Windows version
nsDialogs::SelectFolderDialog "" ""
Pop $4
${EndIf}
end:

Pop $0
Pop $1
Pop $2
Pop $3
Exch $4
FunctionEnd

!include WinMessages.nsh
Function BrowseForAndApplyFolder
Call BrowseForFolder
Pop $0
${If} $0 != "error"
FindWindow $1 "#32770" "" $HWNDPARENT ; Find inner dialog
FindWindow $1 "EdiT" "" $1 ; Find edit box
SendMessage $1 ${WM_SETTEXT} 0 "STR:$0"
${EndIf}
FunctionEnd


Function DirectoryShow
GetFunctionAddress $R0 BrowseForAndApplyFolder
ButtonEvent::AddEventHandler 1201 $R0
FunctionEnd

Page Directory "" DirectoryShow
Page Instfiles

Section
DetailPrint $InstDir
SectionEnd
NhKPaNdA#
I would have never gotten to that in a million years. It works perfectly, thanks a lot for all your help Anders.