Old 24th February 2007, 22:38   #1
sagaci0us
Junior Member
 
Join Date: Feb 2007
Posts: 3
locate file & change default output path

Ok, I have just wasted over 5 hours of my life on this. I'm obviously not a programmer.

Can someone please provide me a sample or point me in the correct direction as I have been through countless samples and forumn postings and I'm still lost.

Our company needs to send a .dll file to our already installed application. Our install paths differ from ver to ver, so I'm doing a search the main file: filename.exe and using the path.

However, for a user that specified thier own custom directory at during the original install, I have to provide them a way for specifying the directory.

I'd like to have the install script automatically search for the path and make it's best guess. The path it guesses should be displayed as the default path to isntall to. They still have the option of specifying a directory with the browse button.

I've been using the locate function to find the path, but I can't seem to get it to show up on the installdir dialog that pops up.


Section

${Locate} "c:\program files\<path>\" "/M=<filename.exe>" "Found1"


SectionEnd


Function "Found1"
; $R9 "path\name"
; $R8 "path"
; $R7 "name"
; $R6 "size" ($R6="" if directory, $R6="0" if file with /S=)

; $R0-$R5 are not used (save data in them).
; ...

MessageBox MB_OK $R8
SetOutPath $R8

#Push $var ; If $var="StopLocate" Then exit from function
FunctionEnd


SetCompress off
Name "${APP_NAME}"
Caption "${APP_NAME}"
OutFile "${INSTALLER_NAME}"
BrandingText "${APP_NAME}"
XPStyle on
InstallDirRegKey "${REG_ROOT}" "${UNINSTALL_PATH}" "UninstallString"





######################################################################

!include "MUI.nsh"

!define MUI_ABORTWARNING
!define MUI_UNABORTWARNING

!insertmacro MUI_PAGE_WELCOME

!ifdef LICENSE_TXT
!insertmacro MUI_PAGE_LICENSE "${LICENSE_TXT}"
!endif

!insertmacro MUI_PAGE_DIRECTORY

!insertmacro MUI_PAGE_INSTFILES

!insertmacro MUI_PAGE_FINISH

!insertmacro MUI_UNPAGE_CONFIRM

!insertmacro MUI_UNPAGE_INSTFILES

!insertmacro MUI_UNPAGE_FINISH

!insertmacro MUI_LANGUAGE "English"

######################################################################

Section -MainProgram
${INSTALL_TYPE}
SetOverwrite ifnewer
#SetOutPath "$INSTDIR"
SetOutPath "c:\"
File "C:\918988_HOTFIX\riched20.dll"
SectionEnd

######################################################################

Section -Icons_Reg
SetOutPath "$INSTDIR"
WriteUninstaller "$INSTDIR\uninstall.exe"

WriteRegStr ${REG_ROOT} "${UNINSTALL_PATH}" "DisplayName" "${APP_NAME}"
WriteRegStr ${REG_ROOT} "${UNINSTALL_PATH}" "UninstallString" "$INSTDIR\uninstall.exe"
WriteRegStr ${REG_ROOT} "${UNINSTALL_PATH}" "DisplayVersion" "${VERSION}"
WriteRegStr ${REG_ROOT} "${UNINSTALL_PATH}" "Publisher" "${COMP_NAME}"

!ifdef WEB_SITE
WriteRegStr ${REG_ROOT} "${UNINSTALL_PATH}" "URLInfoAbout" "${WEB_SITE}"
!endif
SectionEnd

######################################################################

Section Uninstall
${INSTALL_TYPE}
Delete "$INSTDIR\riched20.dll"
Delete "$INSTDIR\uninstall.exe"
!ifdef WEB_SITE
Delete "$INSTDIR\${APP_NAME} website.url"
!endif

RmDir "$INSTDIR"

DeleteRegKey ${REG_ROOT} "${UNINSTALL_PATH}"
SectionEnd

######################################################################
sagaci0us is offline   Reply With Quote
Old 24th February 2007, 23:29   #2
Instructor
Major Dude
 
Join Date: Jul 2004
Posts: 671
code:
Function "Found1"
; $R9 "path\name"
; $R8 "path"
; $R7 "name"
; $R6 "size" ($R6="" if directory, $R6="0" if file with /S=)

; $R0-$R5 are not used (save data in them).
; ...

MessageBox MB_OK $R8
SetOutPath $R8

Push $0; If $var="StopLocate" Then exit from function
FunctionEnd

Instructor is offline   Reply With Quote
Old 25th February 2007, 07:57   #3
Red Wine
Forum King
 
Red Wine's Avatar
 
Join Date: Mar 2006
Location: Ath. GR
Posts: 2,078
Quote:
Our company needs to send a .dll file to our already installed application. Our install paths differ from ver to ver, so I'm doing a search the main file: filename.exe and using the path.

However, for a user that specified thier own custom directory at during the original install, I have to provide them a way for specifying the directory.

I'd like to have the install script automatically search for the path and make it's best guess. The path it guesses should be displayed as the default path to isntall to. They still have the option of specifying a directory with the browse button.
Unless I miss something here, this is exactly what InstallDirRegKey does.
However, if you want to ${Locate} a file and pass the current location as $INSTDIR, you need to do it in function .onInit instead of a section while sections executed when users hit the Install button.

Quick AVI Creator - Quick and easy convert from DVD/MPEG/AVI/MKV to AVI/MP4/MKV
Quick AVI Creator entirely edited with NSIS and entirely upgraded to Unicode NSIS
Red Wine is offline   Reply With Quote
Old 25th February 2007, 19:04   #4
sagaci0us
Junior Member
 
Join Date: Feb 2007
Posts: 3
Thank you! I am now able to get the code to execute before the pages are displayed and not after the user hits the install button.

I'm still not able to change the path displayed on the installation directory screen.

I'm using SetOutPath "$R8" to have it display the path that was just located. I can't get it to actually work though. Any suggestions?

Much appreciation.

Function .onInit
${Locate} "c:\program files\seagull\" "/M=bartend.exe" Found1
FunctionEnd




Function "Found1"
; $R9 "path\name"
; $R8 "path"
; $R7 "name"
; $R6 "size" ($R6="" if directory, $R6="0" if file with /S=)

; $R0-$R5 are not used (save data in them).
; ...

MessageBox MB_OK $R8
SetOutPath $R8

Push $0 ; If $var="StopLocate" Then exit from function
FunctionEnd


FunctionEnd
sagaci0us is offline   Reply With Quote
Old 25th February 2007, 19:36   #5
Red Wine
Forum King
 
Red Wine's Avatar
 
Join Date: Mar 2006
Location: Ath. GR
Posts: 2,078
I don't quite understand what you're trying to do...
You know the path "c:\program files\seagull\" or not?

Anyway, something like this I hope would help,
code:
Function .onInit
${Locate} "$PROGRAMFILES" "/L=F /M=bartend.exe" Found1
FunctionEnd

Function "Found1"
MessageBox MB_OK "$R8"
StrCpy "$INSTDIR" "$R8"
StrCpy $0 StopLocate
Push $0
FunctionEnd


Quick AVI Creator - Quick and easy convert from DVD/MPEG/AVI/MKV to AVI/MP4/MKV
Quick AVI Creator entirely edited with NSIS and entirely upgraded to Unicode NSIS
Red Wine is offline   Reply With Quote
Old 25th February 2007, 20:30   #6
sagaci0us
Junior Member
 
Join Date: Feb 2007
Posts: 3
Thanks a lot! it's working! I really appreciate it. I'm not used to this programming syntax.

I actually started reading through the programming manual to understand the syntax and I see that I wasn't updating the value of the $INSTDIR. I was using something like $INSTDR = "whatever". I now understand the use of StrCpy and how it copies a value from one variable to another variable. ie. StrCpy (var1) (var2).

It's pretty rewarding to get this thing to actually work!

Thanks for your help, much appreciated.
sagaci0us is offline   Reply With Quote
Old 20th February 2010, 09:41   #7
jezzer100
Junior Member
 
Join Date: Feb 2010
Posts: 4
Hi,

I am new to NSIS and this is my first post here. Over the last few days I have successfully built my first installer and I have spent a great amount of time Googling solutions to the various problems that I have encountered along the way.

In that respect, I have already found this thread extremely useful, as it contains an example of how to locate an unknown path which will vary from user to user.

If possible, I would now like to expand on this, as I would like my application by default to copy its files into multiple directories, the exact paths of which will vary. Users should be presented with a list of all available installation directory paths and should be able to add or remove directories to or from the list as they choose.

I have been able to use the Locate function to identify the first path it finds, but I'm not sure how to locate subsequent directories and what to do with the results to get them presented into a list.

I'm hoping that somebody can either point me in the right direction of where to look, or provide a specific example.

The attached screenshot of an example of the sort of end result that I'm ultimately looking to achieve.

jezzer100 is offline   Reply With Quote
Old 3rd March 2010, 12:48   #8
jezzer100
Junior Member
 
Join Date: Feb 2010
Posts: 4
Can anybody help with my last post above? Please, as I'm really stuck.

I'm currently using the following code:

PHP Code:
Function .onInit

nxs
::Show /NOUNLOAD "${PRODUCT_NAME} ${PRODUCT_VERSION} Setup" /top "Searching for suitable installation folders ....."          
${Locate"$PROGRAMFILES" "/L=F /M=MetaEditor.exe"  FindPath          
nxs
:: Destroy    

FunctionEnd    


Function "FindPath"
   
StrCpy "$INSTDIR" "$R8"           
MessageBox MB_YESNO|MB_ICONQUESTION "The ${PRODUCT_NAME} Installer has found the following suitable installation directory$\n$\n        $INSTDIR$\n$\nClick YES if you would like to install ${PRODUCT_NAME} to the selected directory.$\n$\nClick NO to continue searching for a different installation directory." IDNO +2           
StrCpy 
$0 StopLocate           
Push 
$0  

FunctionEnd 
This code allows the user to scroll through the suitable installation folders one by one until he finds one that he likes. This is OK, but users will need to run the installer again if they want to install to another folder.

I would like to locate and present all suitable installation folders to the user and, by default, install to all of those folders, giving the user an option to deselect any folder that he doesn't wish to install to.

I know it can be done, but how?
jezzer100 is offline   Reply With Quote
Old 3rd March 2010, 13:29   #9
MSG
Major Dude
 
Join Date: Oct 2006
Posts: 1,892
You'll have to populate a list somehow. You can use some delimited string, or maybe an array, or save to a temp file.
MSG is offline   Reply With Quote
Old 3rd March 2010, 13:58   #10
jpderuiter
Major Dude
 
Join Date: Feb 2007
Posts: 672
You'll need a multiselect listbox.

The following should get you started (Assuming you're using NSDialogs):
code:
${NSD_AddStyle} $Listbox LBS_MULTIPLESEL

|
|

${NSD_LB_GetCount} $Listbox $itemCount

;allocate memory for $itemCount integers
IntOp $0 $itemCount * 4
System::Alloc $0
Pop $address

;place indices of selected items in the allocated memory
SendMessage $Listbox ${LB_GETSELITEMS} $itemCount $address $selItemCount

${If} $selItemCount > 0

; Calculate the address of last item
IntOp $5 $selItemCount - 1
IntOp $5 $5 * 4
IntOp $address $address + $5

; Loop through all selected items.
${For} $R1 1 $selItemCount

;get current index
System::Call "*$address(i .r0)"
System::Call user32::SendMessage(i$Listbox,i${LB_GETTEXT},i$0,t.r1)
; Selected item is in $1

;move to next index
IntOp $address $address - 4

${Next}
${Endif}

(Most from: http://blog.csdn.net/pkrobbie/archiv...3/4403992.aspx)
jpderuiter is offline   Reply With Quote
Old 3rd March 2010, 14:37   #11
jezzer100
Junior Member
 
Join Date: Feb 2010
Posts: 4
Thanks for the quick replies, it's much appreciated.

Multiselect Listbox isn't something that I've encountered before, so at least I can start to do some research into it. A Google search is returning lots of reading material with examples, so I should be able to get going on it.
jezzer100 is offline   Reply With Quote
Reply
Go Back   Winamp & Shoutcast Forums > Developer Center > NSIS Discussion

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump