Page 1 of 1

CreateDirectory -> CreateFile

Posted: Wed Mar 21, 2018 1:01 am
by IdeasVacuum
PB5.62 x86 Win7 x64

Something I have not seen before - Create a new file path (4 to 6 folders), all returning success, then create a file with that path - first attempt fails.

Workaround:

Code: Select all

iCreate = CreateFile(#FileIO, sFileFullPath, #PB_UTF8) : CloseFile(#FileIO)
iCreate = CreateFile(#FileIO, sFileFullPath, #PB_UTF8)
Anyone else seen this?

Re: CreateDirectory -> CreateFile

Posted: Wed Mar 21, 2018 9:10 am
by RSBasic
Do you mean like this?

Code: Select all

EnableExplicit

#FileIO = 1

Define sFileFullPath.s = "D:\Folder1\Folder2\Folder3\Folder4\MyFile.txt"

Debug CreateDirectory("D:\Folder1\")
Debug CreateDirectory("D:\Folder1\Folder2\")
Debug CreateDirectory("D:\Folder1\Folder2\Folder3\")
Debug CreateDirectory("D:\Folder1\Folder2\Folder3\Folder4\")
Debug CreateFile(#FileIO, sFileFullPath, #PB_UTF8)
CloseFile(#FileIO)
I can't confirm that.

Have you tried it yet?

Code: Select all

SetCurrentDirectory(GetPathPart(ProgramFilename()))
It could be that your file is created in the virtual directory. Check this: %localappdata%\VirtualStore\

And have you tested without anti-virus software?

Re: CreateDirectory -> CreateFile

Posted: Wed Mar 21, 2018 1:24 pm
by IdeasVacuum
Hello RSBasic

Thanks for your input.

The path is created correctly, that can be observed. It's not however starting at root, it is a temporary path in appdata (FOLDERID_RoamingAppData) constructed to ensure a subsequent zip file creation holds the correct paths, and the files are created at run time (always different). I would have the path pre-created by the installer usually, but in this case some of the folder names are dynamic (user project dependent).

So, tested this morning and without any code changes other than commenting out the work-around (AV still on too), I cannot get it to fail!

Going to test it on some other PCs/Windows OS and see what happens there. It's almost as though the path is created a fraction too late so the file creation fails - but if I add a Delay(), that theory is trashed.

Re: CreateDirectory -> CreateFile

Posted: Wed Mar 21, 2018 1:33 pm
by RSBasic
IdeasVacuum wrote:It's almost as though the path is created a fraction too late so the file creation fails
Hm, you can try this:

Code: Select all

EnableExplicit

Procedure.s GetLastError()
  Protected ErrorBufferPointer.L
  Protected ErrorCode.L
  Protected ErrorText.S
  Protected ferr
  
  ErrorCode = GetLastError_()
  ferr = FormatMessage_(#FORMAT_MESSAGE_ALLOCATE_BUFFER | #FORMAT_MESSAGE_FROM_SYSTEM, 0 , ErrorCode, GetUserDefaultLangID_(), @ErrorBufferPointer, 0, 0)
  If ErrorBufferPointer <> 0
    ErrorText = PeekS(ErrorBufferPointer)
    LocalFree_(ErrorBufferPointer)
    ProcedureReturn RemoveString(ErrorText, #CRLF$)
  EndIf
  
EndProcedure

#FileIO = 1

Define sFileFullPath.s = "D:\Folder1\Folder2\Folder3\Folder4\MyFile.txt"

Debug CreateDirectory("D:\Folder1\")
Debug CreateDirectory("D:\Folder1\Folder2\")
Debug CreateDirectory("D:\Folder1\Folder2\Folder3\")
Debug CreateDirectory("D:\Folder1\Folder2\Folder3\Folder4\")
If CreateFile(#FileIO, sFileFullPath, #PB_UTF8)
  CloseFile(#FileIO)
Else
  Debug GetLastError() ; <<<
EndIf
The function GetLastError() returns the last error. E.g. "System cannot find the path specified.", if the directory does not yet exist.

Re: CreateDirectory -> CreateFile

Posted: Wed Mar 21, 2018 2:00 pm
by Marc56us
There are many cases, and not only in PB, where system operations on file accesses fail because it goes too fast. Often a simple 1, 100 or 500 ms delay is enough to solve the problem and will be invisible to the user.
I often had cases where a Delay(1) solved my problem (without me understanding why) ?

And, as a precaution, it is often necessary to construct the operations (systems) in cascade

Not

Code: Select all

CreateDirectory("D:\Folder1\")
CreateDirectory("D:\Folder1\Folder2\")
CreateDirectory("D:\Folder1\Folder2\Folder3\")
CreateDirectory("D:\Folder1\Folder2\Folder3\Folder4\")
But

Code: Select all

If CreateDirectory("D:\Folder1\")
  If CreateDirectory("D:\Folder1\Folder2\")
    If CreateDirectory("D:\Folder1\Folder2\Folder3\")
      If CreateDirectory("D:\Folder1\Folder2\Folder3\Folder4\")
(With Delay() and Break inside each if /EndIf)

:wink:

Re: CreateDirectory -> CreateFile

Posted: Sun Mar 25, 2018 1:36 pm
by kvitaliy

Code: Select all

int SHCreateDirectory(
  _In_opt_ HWND   hwnd,
  _In_     PCWSTR pszPath
);
This function creates a file system folder whose fully qualified path is given by pszPath. If one or more of the intermediate folders do not exist, it creates them.

Code: Select all

SHCreateDirectory_(0, "D:\Folder1\Folder2\Folder3\Folder4")
Returns ERROR_SUCCESS if successful. If the operation fails, other error codes can be returned, including those listed here.

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

  EndSelect
 
  ProcedureReturn Message.s
  
EndProcedure