Windows Vista Folder Selection

From NSIS Wiki
Jump to navigationJump to search
!include "LogicLib.nsh"
 
Name "test"
OutFile "test.exe"
XPStyle on
ShowInstDetails show
RequestExecutionLevel user
 
Page instfiles
 
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
 
Section ""
  Call BrowseForFolder
  Pop $0
  DetailPrint $0
SectionEnd