简体   繁体   中英

Creating an empty directory (NSIS)

How can I do it by NSIS 2.46?

I know this is probably a dumb question, but how the heck do I create an empty directory and check for errors?

I do so:

ClearErrors
CreateDirectory $R1
${If} ${Errors} 
  DetailPrint "failed"
  MessageBox mb_IconStop|mb_TopMost|mb_SetForeground "Can not create folder $R1"
  Abort
${Else}
  DetailPrint "done"
${EndIf}

if the variable $R1 is

  • "c:\\test" - done
  • "c:\\con" - failed ("con" - reserved on Windows)
  • "qwer:\\test2" - done
  • "qwer\\test3" - done (without ":")

why "test2" and "test3" without errors?

UPDATE: How to make that it was an error?

I decided:

ClearErrors
CreateDirectory $R1
${If} ${Errors} 
${OrIfNot} ${FileExists} "$R1\*.*"
  DetailPrint "failed"
  MessageBox mb_IconStop|mb_TopMost|mb_SetForeground "Can not create folder $R1"
  Abort
${Else}
  DetailPrint "done"
${EndIf}

have more ideas?

In order to check for errors you should check the error flag, which you're doing right. I think the problem is you should use quotes:

CreateDirectory "$R1"

NSIS does some unfortunate (IMHO) path mangling and only accepts : as the 2nd character, otherwise it is silently stripped. This means that "qwer\\test2" and "qwer:\\test2" are treated the same at run-time. You can verify this by copying it to one of the special path registers:

!macro TestNsisPathMangling p
Push $InstDir
StrCpy $InstDir "${p}"
DetailPrint "Old=${p}"
DetailPrint "New=$InstDir"
Pop $InstDir
!macroend

!insertmacro TestNsisPathMangling "qwer\test2"
!insertmacro TestNsisPathMangling "qwer:\test2"

This leaves us with "qwer\\test2" and this is a relative path and those are officially not supported when calling CreateDirectory. If you try this in NSIS 3 you should get:

CreateDirectory: Relative paths not supported

Edit:

If the path is entered by the user you can call the Windows function GetFullPathName to get a absolute/full path:

Push "qwer\test3"
System::Call 'KERNEL32::GetFullPathName(ts,i${NSIS_MAX_STRLEN},t.r1,t)i.r0'
${If} $0 <> 0
    DetailPrint "GetFullPathName=$1"
${Else}
    DetailPrint "GetFullPathName failed"
${EndIf}

The documentation for CreateDirectory -- rather irresponsibly -- plainly says error flag is set leaving ambiguity to an occasional NSIS scripter as to what this means.

To no surprise, error handling in NSIS is documented very sparsely as well... but fortunately they do explain how to catch errors if you read the comments thoroughly.

if it is set, it will goto [first param] , otherwise it will goto [second param]

Take special note of the word goto in the docs which is a throwback to GOTO line jumping .

ClearErrors
CreateDirectory $R1
IfErrors 0 +2
Call ErrorHandler

What's not immediately obvious is that +2 JUMPS OVER the error handler. And now one can deduce that 0 will goto the NEXT LINE -- the error handler.

The above example should properly handle an error, given that :ErrorHandler is defined somewhere in your script, which can be replaced with any logic you like.

I recommended ; Commenting heavily ; Commenting heavily as this scripting language can be difficult to read if you don't work with it daily.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM