Page 1 of 3
CreateDirectory() recursively or CreatePath()
Posted: Fri Mar 10, 2017 3:53 pm
by Lunasole
For now CreateDirectory() works only if all parent path exists already, i.e. following code will not create folder "D:\1\2" if "D:\1" not created already:
Would be useful if CreateDirectory() had #PB_FileSystem_Recursive flag, or just add some separated function like following:
Code: Select all
; Walks through given path and creates directories on the way
; Path$ full folder path
; RETURN: 1 on success, 0 if failed to create directory
Procedure CreatePath (Path$)
Protected a, s$, t$
Path$ = ReplaceString(Path$, "/", "\")
Repeat
a + 1
t$ = StringField(Path$, a, "\")
If t$
s$ + t$ + "\"
If FileSize(s$) = -1 ; doesn't exists
If Not CreateDirectory(s$)
ProcedureReturn #false ; failed to recreate path
EndIf
EndIf
Else
Break
EndIf
Until s$ = ""
ProcedureReturn #true
EndProcedure
; usage
CreatePath("D:\1\2")
Re: CreateDirectory() recursively or CreatePath()
Posted: Fri Mar 10, 2017 4:09 pm
by davido
+1
Re: CreateDirectory() recursively or CreatePath()
Posted: Fri Mar 10, 2017 5:20 pm
by Fredi
+1
Re: CreateDirectory() recursively or CreatePath()
Posted: Fri Mar 10, 2017 5:36 pm
by Sicro
+1
Alternatively, the procedure "CreatePath()" can be taken from the CodeArchiv:
https://github.com/SicroAtGIT/PureBasic ... tePath.pbi
@Lunasole: Your Code doesn't support paths like that:
Re: CreateDirectory() recursively or CreatePath()
Posted: Sat Mar 11, 2017 1:06 am
by Dude
For Windows only:
Code: Select all
SHCreateDirectory_(0,"C:\Temp\A\B\C\")
Re: CreateDirectory() recursively or CreatePath()
Posted: Sat Mar 11, 2017 4:35 am
by collectordave
+1 for sicro
Take the procedure from the archive.
Re: CreateDirectory() recursively or CreatePath()
Posted: Sat Mar 11, 2017 5:08 am
by Fangbeast
Code: Select all
Procedure.s MakeSureDirectoryPathExists(Directory.s)
ErrorCode.i = SHCreateDirectory(#Null, Directory.s)
Select ErrorCode.i
Case #ERROR_SUCCESS : Message.s = "Okay" ; ResultCode = 0
Case #ERROR_BAD_PATHNAME : Message.s = "Bad directory path" ; ResultCode = 161
Case #ERROR_FILENAME_EXCED_RANGE : Message.s = "Directory path too long" ; ResultCode = 206
Case #ERROR_FILE_EXISTS : Message.s = "Directory already exists" ; ResultCode = 80
Case #ERROR_ALREADY_EXISTS : Message.s = "Directory already exists" ; ResultCode = 183
;Case #ERROR_CANCELLED : Message.s = "The user canceled the operation." ; ResultCode = ??. Not defined in compiler residents
EndSelect
ProcedureReturn Message.s
; Debug MakeSureDirectoryPathExists("c:\1\2\3\4\5\6")
EndProcedure
Re: CreateDirectory() recursively or CreatePath()
Posted: Sat Mar 11, 2017 11:14 am
by IdeasVacuum
Nice one Fangbeast
Windows Error Codes
#ERROR_CANCELLED = 1223 (0x4C7)
Re: CreateDirectory() recursively or CreatePath()
Posted: Sat Mar 11, 2017 11:58 am
by Fangbeast
Rightyho. I just pilfered this code from the forum somewhere years ago and cleaned it up:):)
Thanks for that:)
I really should be codign something useful but it's been far too hot lately.
Re: CreateDirectory() recursively or CreatePath()
Posted: Sat Mar 11, 2017 12:45 pm
by Dude
FangBeast's code is missing the underscore for the API call:
Code: Select all
Line 3: SHCreateDirectory() is not a function, array, list, map or macro.
Re: CreateDirectory() recursively or CreatePath()
Posted: Sat Mar 11, 2017 1:53 pm
by Fangbeast
Dude wrote:FangBeast's code is missing the underscore for the API call:
Code: Select all
Line 3: SHCreateDirectory() is not a function, array, list, map or macro.
That's strange, never noticed that before but it works here and doesn't give that error. Am I going mad??
Re: CreateDirectory() recursively or CreatePath()
Posted: Sat Mar 11, 2017 2:21 pm
by blueb
Another way...
Code: Select all
;==================================================================
;
; Author: ts-soft
; Date: March 5th, 2010
; Explain:
; modified version from IBSoftware (CodeArchiv)
; on vista and above check the Request for "User mode" or "Administrator mode" in compileroptions
; (no virtualisation!)
;==================================================================
Procedure ForceDirectories(Dir.s)
Static tmpDir.s, Init
Protected result
If Len(Dir) = 0
ProcedureReturn #False
Else
If Not Init
tmpDir = Dir
Init = #True
EndIf
If (Right(Dir, 1) = "\")
Dir = Left(Dir, Len(Dir) - 1)
EndIf
If (Len(Dir) < 3) Or FileSize(Dir) = -2 Or GetPathPart(Dir) = Dir
If FileSize(tmpDir) = -2
result = #True
EndIf
tmpDir = "" : Init = #False
ProcedureReturn result
EndIf
ForceDirectories(GetPathPart(Dir))
ProcedureReturn CreateDirectory(Dir)
EndIf
EndProcedure
Debug ForceDirectories("Z:\aaa\bbb\") ; returns true if directory created
Re: CreateDirectory() recursively or CreatePath()
Posted: Thu Jan 07, 2021 11:09 am
by AZJIO
It didn't work on Linux
For ForceDirectories() you need to change the line
Code: Select all
If (Right(Dir, 1) = "/") ; Linux, / instead of \
and in exceptional cases
since the shortest path is "/a", i.e. 2 symbols
Re: CreateDirectory() recursively or CreatePath()
Posted: Thu Jan 07, 2021 2:19 pm
by collectordave
Code: Select all
Procedure CheckCreatePath(Directory.s)
Define BackSlashs.i,iLoop.i,Path.s,Temp.s
BackSlashs = CountString(Directory, #PS$)
Path = ""
For iLoop = 1 To BackSlashs + 1
Temp = StringField(Directory.s, iLoop, #PS$)
If StringField(Directory.s, iLoop+1, #PS$) > ""
Path + Temp + #PS$
Else
Path + Temp
EndIf
CreateDirectory(Path)
Next iLoop
EndProcedure
Works on mac and windows and I think i tested it on linux as well
Re: CreateDirectory() recursively or CreatePath()
Posted: Thu Jan 07, 2021 2:32 pm
by Bisonte
Also from TS-Soft (this should work on all platforms) slightly modified :
Code: Select all
Procedure.i CreateDirectoryEx(DirectoryName.s, FileAttribute = #PB_Default) ; Erstellt Verzeichnis, inklusive Übergeordnete
Protected i, c, tmp.s
If Right(DirectoryName, 1) = #PS$
DirectoryName = Left(DirectoryName, Len(DirectoryName) -1)
EndIf
c = CountString(DirectoryName, #PS$) + 1
For i = 1 To c
tmp + StringField(DirectoryName, i, #PS$)
If FileSize(tmp) <> -2
CreateDirectory(tmp)
EndIf
tmp + #PS$
Next
If FileAttribute <> #PB_Default
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
SetFileAttributes_(DirectoryName, FileAttribute)
CompilerElse
SetFileAttributes(DirectoryName, FileAttribute)
CompilerEndIf
EndIf
If FileSize(DirectoryName) = -2
ProcedureReturn #True
EndIf
EndProcedure