GetTrueFolderItem returns Nil

I have the following code in a program in a Windows 10 environment:

fSourceFile = GetTrueFolderItem (ThisSourcePathFileName) IF fSourceFile = Nil THEN IF app.gConfig.LogError THEN CALL CopyLog ("Error: File Handle for Source File: " + ThisSourcePathFileName ) END IF ErrorCount = ErrorCount + 1 END IF

The code works, in that it properly traps instances where GetTrueFolderItem returns Nil. However when I examine the log the code creates, GetTrueFolderItem returns Nil for files that do exist. By referencing the log that the code generates, I can use Windows Explorer to navigate to the offending files, and I can open them. Based on the resulting log file, I suspect the offending files have path names that are too long for earlier Windows versions, however I have configured Windows 10 to handle long path names.

I have two questions:

  1. How do I get more meaningful information on why GetFolderItem returns Nil (obviously I can not use FolderItem.LastError) that I can put into the log? Right now the log declares a bad file handle (Nil FolderItem), which is not useful to the user. I suspect the long file name is the issue, but I am only guessing.

  2. If the long filename is the culprit, how do I retrieve long filenames using GetFolderItem or GetTrueFolderItem, understanding that many users will not have configured their Windows 10 environment to handle long file names (but the code can test for that environment configuration).

Thanks in advance,

Alex

First of all (and if you want, consider that as a debug way), test each and every level contained in ThisSourcePathFileName istead of counting (guess) on luck.

Then, you will certainly have clues to why sometimes you have troubles.

[quote=443709:@Emile Schwarz]First of all (and if you want, consider that as a debug way), test each and every level contained in ThisSourcePathFileName istead of counting (guess) on luck.

Then, you will certainly have clues to why sometimes you have troubles.[/quote]

Emile - for brevity, I only included the relevant segment code. There is a tremendous amount of error checking that occurred before this point. At this point in the code, we know for certain that the file already exists, and yet GetFolderItem returns Nil.

To paraphrase my original question: When Xojo GetFolderItem returns Nil on a file that exists, how do I get more information on why Xojo returned Nil?

A quick test of GetTrueFolderItem shows that it doesn’t work with long file names/paths, neither does folderitem but xojo.io.folderitem does. Maybe @William Yu can shed some light on that, and confirm if its a bug or not?

If you just want to check if a file exists without creating loads of xojo.io.folderitem’s then you can use the following, note the \\?\ at the start of the path. This code will not follow symbolic links.

[code]Dim path As String = “\\?\C:\Users\Julian\Desktop\012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789.txt”

Declare Function CreateFileW Lib “Kernel32.dll” Alias “CreateFileW” ( _
lpFileName As WString, _
dwDesiredAccess As UInt32, _
dwShareMode As UInt32, _
lpSecurityAttributes As Ptr, _
dwCreationDisposition As UInt32, _
dwFlagsAndAttributes As UInt32, _
hTemplateFile As Ptr _
) As Integer

Const FILE_FLAG_OPEN_REPARSE_POINT = &h00200000
Const FILE_READ_ATTRIBUTES = &h80
Const FILE_SHARE_READ = &h00000001
Const OPEN_EXISTING = 3
Const FILE_FLAG_BACKUP_SEMANTICS = &h02000000

Dim hFile As Integer

hFile = CreateFileW(path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ, Nil, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS Or FILE_FLAG_OPEN_REPARSE_POINT, Nil)

Dim fileExists As Boolean = False

If hFile <> -1 Then fileExists = True

Declare Function CloseHandle Lib “Kernel32.dll” Alias “CloseHandle” ( _
hObject As Integer _
) As Int32

Call CloseHandle(hFile)

system.DebugLog(“exists=” + str(fileExists))

[/code]

Julian:
Thanks for that. I already have an excellent routine that I obtained from this forum that very quickly lists all files from a directory (and all sub-directories), so I already know the file exists. That routine also uses the ‘\\?\’ notation before calling FindFirstFile and FindNextFile.