Summary
When inspecting the FileReference in Gt for FileLocator>>#temp we get an error as indicating the path cannot be read.
Description
When a Windows user account has a long username (e.g. Marcus R. Greek), the TEMP and TMP environment variables contain the 8.3 shortened form (MARCUS~1.GRE) instead of the full username. WindowsResolver>>#temp returns the same shortened path via WinPlatform>>#getTempPath, which calls the Windows API GetTempPathW.
GtFileBrowserFolderTool class>>#forFolder: reported the FileReference returned by WindowsResolver>>#temp whose pathString was C:\Users\MARCUS~1.GRE\AppData\Local\Temp as "Not able to read the path to the given folder". This occurs because Gt's folder matching logic expects long-form paths and doesn't recognize the shortened path as matching any existing folder model.
Proposed Solution
A proposed solution has been posted to pharo-project/pharo#18961 to normalize paths to long-form format regardless of where they came from. This would resolve the issue at the WinPlatform level.
Alternative approach (not recommended)
GtFileBrowserFoldersModel>>#findFileBrowserFolderModel:ifFound:ifNone: could be modified to handle this edge case by comparing both long and shortened path forms. However, this approach degrades performance because it checks every path even though most paths are in long-form format.
Implementation details:
FileReference>>#shortenedName
shortenedName
"Return the shortened full path name of the receiver."
| platform buffer r |
platform := OSPlatform current.
buffer := Win32WideString new: platform defaultMaximumPathLength.
r := platform
getShortPathName: self pathString asWin32WideString
buffer: buffer
size: platform defaultMaximumPathLength.
r = 0
ifTrue: [ self error: 'Error while calling getShortPathName() for ' , self pathString ].
^ buffer asString
WinPlatform>>#getShortPathName:buffer:size:
getShortPathName: lpszLongPath buffer: lpszShortPath size: cchBuffer
self
ffiCall: #(long GetShortPathNameW #(Win32WideString lpszLongPath , void * lpszShortPath , ulong cchBuffer))
GtFileBrowserFoldersModel>>#findFileBrowserFolderModel:ifFound:ifNone:
findFileBrowserFolderModel: aFolder ifFound: aFoundBlock ifNone: aNoneBlock
"Find a child object based on the child model and evaluate aFoundBlock if such child was found,
aNoneBlock otherwise."
<return: #Object>
<generatedFrom: #'TGtRobocoderMetamodelChildrenForManyWithModelTemplate>>#findObjectIfFoundIfNoneTemplate'>
^ self fileBrowserFolderModels
detect: [ :eachFileBrowserFolderModel |
aFolder fileSystem isCaseSensitive
ifTrue: [ eachFileBrowserFolderModel fileReference = aFolder ]
ifFalse: [ OSPlatform current isWindows
ifTrue: [ (eachFileBrowserFolderModel fileReference pathString
sameAs: aFolder pathString)
or: [ eachFileBrowserFolderModel fileReference shortenedName
sameAs: aFolder shortenedName ] ]
ifFalse: [ eachFileBrowserFolderModel fileReference pathString
sameAs: aFolder pathString ] ] ]
ifFound: aFoundBlock
ifNone: aNoneBlock
History
Originally reported at https://discord.com/channels/729445214812504107/736333725788274819/1377959221395718185.
Summary
When inspecting the FileReference in Gt for
FileLocator>>#tempwe get an error as indicating the path cannot be read.Description
When a Windows user account has a long username (e.g.
Marcus R. Greek), the TEMP and TMP environment variables contain the 8.3 shortened form (MARCUS~1.GRE) instead of the full username.WindowsResolver>>#tempreturns the same shortened path viaWinPlatform>>#getTempPath, which calls the Windows API GetTempPathW.GtFileBrowserFolderTool class>>#forFolder:reported the FileReference returned byWindowsResolver>>#tempwhose pathString wasC:\Users\MARCUS~1.GRE\AppData\Local\Tempas "Not able to read the path to the given folder". This occurs because Gt's folder matching logic expects long-form paths and doesn't recognize the shortened path as matching any existing folder model.Proposed Solution
A proposed solution has been posted to pharo-project/pharo#18961 to normalize paths to long-form format regardless of where they came from. This would resolve the issue at the
WinPlatformlevel.Alternative approach (not recommended)
GtFileBrowserFoldersModel>>#findFileBrowserFolderModel:ifFound:ifNone:could be modified to handle this edge case by comparing both long and shortened path forms. However, this approach degrades performance because it checks every path even though most paths are in long-form format.Implementation details:
FileReference>>#shortenedNameWinPlatform>>#getShortPathName:buffer:size:GtFileBrowserFoldersModel>>#findFileBrowserFolderModel:ifFound:ifNone:History
Originally reported at https://discord.com/channels/729445214812504107/736333725788274819/1377959221395718185.