Appending InstallDir to browsed path ...sometimes
I have taken a journey today, and I would like to share the story of that journey, so that it may enrich the lives of others for many years to come.
OK, seriously. I wrote a little block of code, but I think its really, really cool. So here tis:
;--------------------------------
; Verify the Install Dir
Function .onVerifyInstDir
IfFileExists $INSTDIR\..\Appname.exe "" PathGood
GetFullPathName $INSTDIR $INSTDIR\..
FindWindow $R0 "#32770" "" $HWNDPARENT
GetDlgItem $R0 $R0 1019
SendMessage $R0 ${WM_SETTEXT} 0 "STR:$INSTDIR"
PathGood:
FunctionEnd
Here's a little background. Our app uses one install for both new installs and updates. Most of the time, InstallDirRegKey works like a charm, so when the user installs an update, setup remembers where it was installed originally.We use InstallDir without quotes, so the default directory name gets appended from the browse dialog. I personally like this, because it encourages my users to keep a consistent environment. Occasionally, some users change the install directory to something they like better.
Here's the kicker. Many (actually most) of our users install our app on a network drive. This means that more than one user can do installs, and that a user doing an update won't necessarily have the InstallDirRegKey value in their registry.
When InstallDirRegKey is not found, and the user has to browse for the directory, and the directory name is not the default, then the default name gets appended to the existing path as a subdirectory. The user then starts the app in the original location using the original shortcut, and they still see the previous version of the app, and my phone rings. This is a problem.
The code sample above is the solution. I found it was easy to modify the $INSTDIR variable, but while the dialog is visible, $INSTDIR is not the primary source. The primary source is the text in the edit box of the dialog. So to really change the install dir in .onVerifyInstDir, you need to update the text box with WM_SETTEXT.
Note that this will also prevent a user from browsing to a directory below a directory with Appname.exe in it. The browse button will work, but the directory in the text box will still be the parent. A more stringent method would be check $INSTDIR before modifying it to see if the end of the path is equal to the default directory name, which is left as an exercise.
Enjoy!