Hi All.
I’m just starting with Xojo and although over all I’m finding it pretty accessible, I’m totally stuck on a probably trivial problem. I’m on Mac Big Sur 11.3.
I’m retrieving a file path which is stored in an plist file as xml style tag. I fetch this with a shell script - “plutil -p '” + filePath + “.plist’”, which works just fine. The path is returned as text in the form :
Macintosh HD:System:Volumes:Data:Volumes:My files HD:My Folder:My File.txt
This is actually new to the last couple of systems. I need it to be in “Posix” format, as they would say in Applescript like this :
/Volumes/My files HD/My Folder/My File.txt
to use it in Xojo. In AppleScript, this would be a piece of cake !
I can’t seem to find any easy way to do this in Xojo. I can add a slash in front and do a “ReplaceAl(”:","/")" but that’s not enough !
Could any kind soul help me out here please ? TIA.
If the filepath is stored in a file why not store it as a posix path in the first place?
It’s deprecated, but you can call:
var f = new folderitem(myOldColonsPath)
to create a folderitem initialized with the old-style Mac path you have, and then access the folderitem’s .NativePath
property to get it in the POSIX form.
Ahh ! That’s because it’s stored by other software. I just need to recover the value. It’s also a string as such and that’s how I need it ! See my answer to Mathew.
Thanks for your answers.
Thanks for your answer. I’m not sure if I want to use a solution based on deprecated functions, as I don’t think the colon path format is going to disappear anytime soon on Mac. The other thing is that I’m using the conversion as a string, as I need to place different suffixes on it according to which file I’m addressing wit it after… .txt, .xml, .plist all based on the same root path.
Use
dim f as new folderitem(myOldColonsPath, Folderitem.PathModes.Native)
Thanks for your reply.
My as yet sparse understanding of Xojo leads me to believe that this would return a folderItem and not a string, which is what I need, to be able to use it in the command line after. How could I then convert this back to a string ?
I have solved it temporarily by incorporating an AppleScript 1 liner (well 3 if you count the “On Run” and “End Run” !), which does the job perfectly, but I was really trying to see if there was a simple native Xojo solution…
If you need to convert between path types then you need a folderitem.
I have an old declare to make a folderitem out of an absolute path (yes, this is still necessary with paths that come from AppleScript):
Protected Function AbsolutePath(hasAbsolutePath As String) As Folderitem
Dim theNativePath As String
#If TargetMacOS Then
Declare Function CFURLCopyFileSystemPath Lib "Foundation" (anURL As Ptr, pathStyle As Int32) As CFStringRef
Declare Function CFURLCreateWithFileSystemPath Lib "Foundation" (CFURLCreateWithFileSystemPath As Ptr, filePath As CFStringRef, pathStyle As Int32) As Ptr
Const kCFURLPOSIXPathStyle = 0
Const kCFURLHFSPathStyle = 1
Dim ptrNSURL As Ptr = CFURLCreateWithFileSystemPath(nil, hasAbsolutePath, kCFURLHFSPathStyle)
theNativePath = CFURLCopyFileSystemPath(ptrNSURL, kCFURLPOSIXPathStyle)
#Else
'Windows, Linux: NativePath is the same as Xojo's deprecated AbsolutePath
theNativePath = hasAbsolutePath
#EndIf
Return New FolderItem(theNativePath, folderItem.PathModes.Native)
End Function
You would then use this function first and then call the NativePath function of the resulting Folderitem.
Thanks a lot for that. I’ll try it out as soon as I have a moment.
I guess my dream of a one-liner in Xojo is ephemeral then !
Ah well. I’ll still opt for the Xojo native solution if it works for me
Perhaps all you need to add to:
is:
mypath = f.NativePath
This doesn’t work. PathModes.native is the POSIX path. If you just provide the old-style path as a string, the FolderItem constructor still knows what to do.
For the code in a button:
var f as folderitem
f = new FolderItem("Macintosh HD:Applications", Folderitem.PathModes.Native)
msgbox f.NativePath
The result is: /Users/yourname/Development/Macintosh HD:Applications
However,
var f as folderitem
f = new FolderItem("Macintosh HD:Applications")
msgbox f.NativePath
The result is: /Applications
Yes, it returns a folderitem pointing the the file of interest. Then you just use the .NativePath or .ShellPath to get the version of the path you want back. it converts it for you. Two lines of code.
Wow ! Now that IS cool
I’ll test this, and be back with my verdict
Mmmm… I’m obviously doing something very wrong, as this doesn’t work for me at all
If I take your code as is, when my test app is on my desktop, it returns :
/Users/me/Desktop/Macintosh HD/Applications
If I change the path to something on an external disk
f = new FolderItem(“Misc:Test Folder:some picture.png”)
it returns :
/Users/me/Desktop/Misc/Test Folder/some picture.png
… so it appears to be adding the path to my test app in front of the actual path that I’m asking for !
I’m going to try Beatrix’s proposal to see if I have any more luck with the more complex solution…
I’ll be back !
Well, despite what Mathew says, your solution works just fine for me, just as it is !
Feeding it “Misc:Test Folder:some picture.png” as a path returns :
/Volumes/Misc/Test Folder/some picture.png
… which is exactly what I was expecting, and hoping for ! OK, so Mathew’s solution seemed sooo much simpler, but too good to be true apparently.
I’ll wait to see if I get anymore feedback on this, but short of anything else, I’ll have to accept your solution as the working one.
Thanks again for your help
Not sure… just tried it with a new project, placing a single button on the Window with the code:
var f as folderitem
f = new FolderItem("Macintosh HD:Applications")
msgbox f.NativePath
It returns /Applications.
But glad you found a workable solution.
Perhaps this is something to do with Big Sur… ? I did exactly what you say here, new project, single button on the window with your exact code copy/pasted and it returns :
/Users/me/Desktop/Macintosh HD/Applications
… when my new project is on on the desktop. If I do the same thing before saving the new project anywhere, it adds some very obscure path full of numbers and unknown subfolder names, before adding “/Macintosh HD/Applications” on the end. Really weird Some temporary folder or something ?
Thanks very much for your efforts anyway. Really appreciated.
Update :
I built the little app and put it on a virtual MacOSX 10.15 Catalina and it works just as you said !!
It does tend to point towards a Big Sur thing, but I’ll try to confirm. I have access to another machine with Big Sur on it so I’ll give it a try. If it works there, then there’s something on my own computer making it go pear shaped !
Update 2 :
Just tried with different paths on my virtual Catalina, and it ONLY works with “Macintosh HD:Applications”. Any other path adds the bits in front Still no joy then. I don’t know if you tried with any other paths than the Applications folder, but it’s the only one that works with your code for me.
Interesting; I was wondering about that. I’m not on BS.
It sounds like an OS-level change, but you could also try forcing the old (deprecated) syntax with
f = new FolderItem("Macintosh HD:Applications",0)
I also did try it with some other paths such as Macintosh HD:Users:me:Documents, and it worked.
As I understood it, you were reading a string with an old-style path and wanted to get the POSIX path. I took your path, /System/Volumes/Data/Volumes/My files HD/My Folder/My File.txt
– which, BTW, doesn’t even exist on my computer, ran this code:
var f as folderitem
f = new FolderItem("Macintosh HD:System:Volumes:Data:Volumes:My files HD:My Folder:My File.txt",0)
msgbox f.NativePath
And got:
/System/Volumes/Data/Volumes/My files HD/My Folder/My File.txt
Anyway, glad Beatrix’s more robust solution works universally. Thanks for checking it out on Catalina… thought I might be going crazy.
… which would work just fine ! It seems that on BS, the directory catalogues are kept on the new “Data Volume” which now gets greated by the system on APFS. They have separated the system itself from the data for “added security” supposedly ! I’ll try the deprecated format for the hell of it, but I’m not crazy about using deprecated stuff in general, as you know it’s going to stop working at some point !
Thanks again for your help and tenacity