There are some methods that you can used to check whether or not an installation path is valid for your installer.
1. .onVerifyInstDir function
This will be called every time the user changes the install directory.
2.Write a function for MUI_PAGE_CUSTOMFUNCTION_LEAVE and can then check for GetInstDirError withing that function to
check wether it is valid.
Function .onVerifyInstDir
IfFileExists $INSTDIR\<your exe> PathGood
Abort ; if $INSTDIR is not a winamp directory, don't let us install there
PathGood:
FunctionEnd
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE MUIDirectoryPageLeave
Function MUIDirectoryPageLeave
GetInstDirError $0
${Switch} $0
${Case} 1
MessageBox MB_OK "Invalid installation directory!"
Abort
${Break}
${Case} 2
MessageBox MB_OK "Not enough free space!"
Abort
${Break}
${EndSwitch}
FunctionEnd
Both the above functions has some issues.
1 will only let you to continue if there is a folfer exists as described in "$INSTDIR" path.
2 will not recognize foledr names which ends with spaces or dots as invalid
eg
C:\Abc\Your Family \your product ; invalid since it contains space after Your Family
C:\Abc\Your Family.\your product ; invalid since it contains a dot after Your Family
C:\Abc\Your Family\your product ; valid
Therefore we have to write our own functions to test wether a path is valid.
Following is sample codes that you can use. (Hope you have bettr understaning of NSIS functions and macros)
!define IndexOfDef "!insertmacro IndexOfMac"
!define IsContainsDotOrSpaceAtEndDef "!insertmacro IsContainsDotOrSpaceAtEndMac"
!define IsContainsInvalidCharactersDef "!insertmacro IsContainsInvalidCharactersMac"
;;;;; Utility Macros ;;;;;;;;;;;;
!macro IndexOfMac resVar String Char
Push "${Char}"
Push "${String}"
Call IndexOfFun
Pop "${resVar}"
!macroend
!macro IsContainsDotOrSpaceAtEndMac resVar String
Push "${String}"
Call IsContainsDotOrSpaceAtEnd
Pop "${resVar}"
!macroend
!macro IsContainsInvalidCharactersMac resVar String
Push "${String}"
Call IsContainsInvalidCharacters
Pop "${resVar}"
!macroend
!macro IsValidPathMacro resString String
StrCpy $R1 ${String}
StrCpy ${resString} True
StrCpy $R4 0 ; loop counter
loop:
IntOp $R4 $R4 + 1 ; increment the count
;;;; Split string to two parts ;;;;;;
${IndexOfDef} $R0 $R1 "\"
${If} $R0 > -1
StrCpy $R2 $R1 $R0 0 ;first part o fthe string
IntOp $R0 $R0 + 1 ;length
StrCpy $R3 $R1 "" $R0 ;second part of the string
StrCpy $R1 $R3 ;update R1
${Else}
Goto endOfMac
${EndIf}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
${If} $R4 != 1 ; since first part is the disk drive (eg C:, D:) wich is handleed by nsis itself we can omit this
check for count = 1
${IsContainsDotOrSpaceAtEndDef} $R0 $R2
${If} $R0 == True
MessageBox MB_OK "Path should not contain dots or spaces at the end"
Goto errFound
${EndIf}
${IsContainsInvalidCharactersDef} $R0 $R2
${If} $R0 == True
MessageBox MB_OK 'Path should not contain any of these characters: ?, *, < , >,", \, /, :, |'
Goto errFound
${EndIf}
${EndIf}
Goto loop
errFound:
StrCpy ${resString} False
endOfMac:
!macroend
;;;;;;;Utility Macros End;;;;;;;;;;;;;;
;;;;; Utility Functions ;;;;;;;;;;;;;;;;
Function IndexOfFun
Exch $R0
Exch
Exch $R1
Push $R2
Push $R3
StrCpy $R3 $R0
StrCpy $R0 -1
IntOp $R0 $R0 + 1
StrCpy $R2 $R3 1 $R0
StrCmp $R2 "" +2
StrCmp $R2 $R1 +2 -3
StrCpy $R0 -1
Pop $R3
Pop $R2
Pop $R1
Exch $R0
FunctionEnd
Function IsContainsDotOrSpaceAtEnd
Exch $R0
Push $R1
Push $R2
Push $R3
StrCpy $R3 False ; contain the results
StrLen $R1 $R0
IntOp $R1 $R1 - 1
StrCpy $R2 $R0 1 $R1 ; last character of the string
${If} $R2 == "."
StrCpy $R3 True
${Else}
${If} $R2 == " "
StrCpy $R3 True
${EndIf}
${EndIf}
StrCpy $R0 $R3
Pop $R3
Pop $R2
Pop $R1
Exch $R0
FunctionEnd
Function IsContainsInvalidCharacters
Exch $R0
Push $R1
Push $R2
StrCpy $R2 True ; contain the results
${IndexOf} $R1 $R0 "\"
IntCmp $R1 -1 0 invalidFound invalidFound
${IndexOf} $R1 $R0 "/"
IntCmp $R1 -1 0 invalidFound invalidFound
${IndexOf} $R1 $R0 "*"
IntCmp $R1 -1 0 invalidFound invalidFound
${IndexOf} $R1 $R0 "?"
IntCmp $R1 -1 0 invalidFound invalidFound
${IndexOf} $R1 $R0 "<"
IntCmp $R1 -1 0 invalidFound invalidFound
${IndexOf} $R1 $R0 ">"
IntCmp $R1 -1 0 invalidFound invalidFound
${IndexOf} $R1 $R0 ":"
IntCmp $R1 -1 0 invalidFound invalidFound
${IndexOf} $R1 $R0 "$\""
IntCmp $R1 -1 0 invalidFound invalidFound
${IndexOf} $R1 $R0 "|"
IntCmp $R1 -1 0 invalidFound invalidFound
StrCpy $R2 False
invalidFound:
StrCpy $R0 $R2
Pop $R2
Pop $R1
Exch $R0
FunctionEnd
Usage
Replace the code based on GetInstDirError on above MUIDirectoryPageLeave function with the macro we have defined.
The example code would looks like
Function MUIDirectoryPageLeave
!insertmacro IsValidPathMacro $R0 "$INSTDIR"
${If} $R0 == False
Abort
${EndIf}
FunctionEnd
No comments:
Post a Comment