Skip to content
⌘ NSIS Forum Archive

CreateDirectory relative path in NSIS v3

10 posts

jooseng#

CreateDirectory relative path in NSIS v3

In my macro it include the following:

${If} "${_PortableDir}" != ""
CreateDirectory "${_PortableDir}"
${EndIf}

When I defind _PortableDir = "", NSIS v3.04 will give an error massage that it is not support relative path but there is no error if I use v2.46 to compile the code.
Will the above code valid in v3.04?
Thanks.
Anders#
NSIS 3 does not allow relative paths there but you can just use the full path because you always know the full path.

Use $ExeDir if you need something relative to the installer .exe.
jooseng#
Thanks for reply.
I always use full path. The if statement is use to check if an empty string is input to ${_PortableDir} mean do not create the directory. However NSIS v3.04 treat the empty string as a relative path.
Anders#
If you want to check at compile-time then you must use !if:

!define _PortableDir ""
...
!if "${_PortableDir}" != ""
CreateDirectory "${_PortableDir}"
!endif
jooseng#
If I use a dummy directory z:\temp~, nsis has no complain.

${If} "${_PortableDir}" != "z:\temp~"
CreateDirectory "${_PortableDir}"
${EndIf}
Anders#
Originally Posted by jooseng View Post
If I use a dummy directory z:\temp~, nsis has no complain.

${If} "${_PortableDir}" != "z:\temp~"
CreateDirectory "${_PortableDir}"
${EndIf}
That will complain if _PortableDir is "".

_PortableDir should probably be "$ExeDir\Something" or "$Temp\Something".

${_PortableDir} is a define so you can check it at compile-time to see if it is empty or not.
jooseng#
This is the full code of the macro:

!define DirectoryMove::Post "!insertmacro DirectoryMove::Post"

!macro DirectoryMove::Post _PortableDir _LocalDir
${If} "${_PortableDir}" == "" ;restore local only
RMDir /r "${_LocalDir}"

;=== If the parent directory we put the directory in locally didn't exist before, delete it if it's empty. ===
${GetParent} "${_LocalDir}" $4
${ReadRuntimeData} $2 DirectoriesMove "RemoveIfEmpty:$4"
${If} $2 == true
RMDir "$4"
${EndIf}

Rename "${_LocalDir}.BackupByPortableApp" "${_LocalDir}"
${Else}
;=== Backup portable ===
;~~~ Is the target inside the package? ~~~
ExpandEnvStrings $0 "$EXEDIR"
ExpandEnvStrings $1 "${_LocalDir}"
StrLen $R0 $0
StrCpy $R0 $1 $R0
${If} $R0 == $0 ;<<< in-package >>>
${GetParent} "${_PORTABLEDIR}" $4
${IfNot} ${FileExists} "$4"
CreateDirectory "$4"
${EndIf}
Rename "${_LOCALDIR}" "${_PORTABLEDIR}"
${Else} ;<<< not in-package >>>
;~~~ Is the target in the same dirve? ~~~
ExpandEnvStrings $1 "${_LocalDir}"
StrCpy $1 "$1" 2 ;Get drive letter +:
${If} "$1" == "$CurrentDrive" ;<<< in same drive >>>
${GetParent} "${_PORTABLEDIR}" $4
${IfNot} ${FileExists} "$4"
CreateDirectory "$4"
${EndIf}
Rename "${_LocalDir}" "${_PortableDir}"
${Else}
RMDir "${_LocalDir}"
RMDir /r "${_PortableDir}"
CreateDirectory "${_PortableDir}"

!ifdef UseFastCopy
ExecWait `"$PLUGINSDIR\fastcopy.exe" /cmd=move /speed=full /error_stop=FALSE /force_close /acl=FALSE /verify=FALSE /log=FALSE "${_LocalDir}" /to="${_PortableDir}"`
!else
CopyFiles /SILENT "${_LocalDir}\*.*" "${_PortableDir}"
!endif
RMDir /r "${_LocalDir}"
${EndIf}

;=== If the parent directory we put the directory in locally didn't exist before, delete it if it's empty. ===
${GetParent} "${_LocalDir}" $4
${ReadRuntimeData} $2 DirectoriesMove "RemoveIfEmpty:$4"
${If} $2 == true
RMDir "$4"
${EndIf}

;=== Restore Local ===
Rename "${_LocalDir}.BackupByPortableApp" "${_LocalDir}"
${EndIf}
${EndIf}
!macroend

There is no problem in all other parts of the code if ${_PortableDir} == "". Error occur only on CreateDirectory "${_PortableDir}".
When I change

CreateDirectory "${_PortableDir}"

to

${If} "${_PortableDir}" != ""
StrCpy $0 "${_PortableDir}"
CreateDirectory "${_PortableDir}"
${EndIf}

No error show.

It seems that there is bug in the command "CreateDirectory" in v3.04. The same code has no error in v2.46.
Anders#
I know 2.x does not act the same but I'm not seeing any bugs. 3.x was changed to specifically prevent you from using relative paths.

Take
Section
!define _PortableDir "$ExeDir\Something"
${If} "${_PortableDir}" != "" ; This should really be !if and if _PortableDir can be "" then you MUST use !if
CreateDirectory "${_PortableDir}"
${EndIf}
SectionEnd
and modify it so that reproduces the problem