Getfolderitem Volume(i).name error (":" replaced by "/")

Hi,

I am having a problem with a cd-player I programmed a few years ago. I think the problem started when I upgraded from 10.8.5 to Sierra and only affects a few cd:s. If there is a “:” in the cd name it is changed to “/” (here and there…)

One example of failure is a cd named “Ives: An American Journey” (double checked in the terminal and other cd playing softwares)

f=GetFolderItem("/Volumes/"+Volume(i).name, FolderItem.PathTypeShell)
says that the name is “Ives/ An American Journey” (":" is replaced by “/”, which is wrong)

Consequently when I later do: If f.exists
it crashes because it tests for “Ives/ An American Journey” (which is wrong)

This is obviously an MacOS bug, because on the desktop the CD-icon is named “Ives/ An American Journey”,
but if I open it, the window is named “Ives: An American Journey”-
All the songs in the window are named Ives/xxxxxx, but if I drag one of them into VLC it says it’s Ives:xxxxxx
In the terminal the “:” used for both album name and song name.

Shouldn’t I be able to get the correct album and song names with Getfolderitem and Volume(i).name (without the “:” getting replaced by “/”)?
Is this something the Xojo developers should fix or is it about waiting for Apple to fix it? (10.12.4 - same problem)

No.

There is a difference between a WINDOWname and a FILEname.

After all the Finder is just another app, and what you see is how the finder shows you the underlying file information.

Accessing that file information is a different cattle of fish.

It is the same in your apps: a document shown in a window has a Title, but the file name is not necessarily the same.

And there is a good reason for that.

Read up on file delimiter in the folderitem documentation.

I don’t believe “:” is a valid filename character on Mac.

I think it was long ago… NativePath vs Shellpath vs AbsolutePath or something like that…

I played this particular folder/album before, sometimes it has every played on Sierra, so it seems to me something is fishy!

If Volume(i).name returns “Ives/ An American Journey” (Shellpath)
then why does If f.exists not accept it?

If I manually change it to “Ives: An American Journey” it passes the If f.exists test and everything works (for this particular folder/album). But that was not the filename given by Volume(i).name. Why is this?

Maybe related, I found this on SuperUser (https://superuser.com/questions/326103/what-are-invalid-characters-for-a-file-name-under-os-x)

Perhaps try sticking with NativePath?

post the EXACT code you are attempting to use

I’m doing things through shell so from what I remember I there were problems using native path.

Code (the content of a timer):’
I am scanning the volumes one by one to find out if there is an audio cd.
When I manually replace “/” with “:” this particular audio cd plays without problems.

[code]Dim f as FolderItem
Dim a,b as integer
StreamInitialized=0

'f=GetFolderItem("/Volumes/Ljud-CD", FolderItem.PathTypeShell)
Textfield5.text=“No Cd”
for b=0 to VolumeCount-1
f=GetFolderItem("/Volumes/"+Volume(b).name, FolderItem.PathTypeShell)

If f.exists then 'kollar om foldern Ljud-CD finns
f=GetFolderItem("/Volumes/"+Volume(b).name+"/"+".TOC.plist", FolderItem.PathTypeShell) '.TOC.plist shows that is the Audio-CD-folder

If f.exists then
  NrOfCdVolume=b
  Textarea1.text="Volume" +str(NrOfCdVolume)+" .TOC.plist available. This should be an audio cd."+endofline
  Textfield5.text="Found CD"
  me.mode=me.modeoff
  BevelPlay.Enabled=True
  BevelPause.Enabled=True
  
  For a=1 to 100
    f=GetFolderItem("/Volumes/"+Volume(b).name+"/"+str(a)+" track.aiff", FolderItem.PathTypeShell)
    If f.exists then 
  
    else
     
     Tracksavailable=a-1    
    
      If Tracksavailable <10 then
        LabelTrack.text="0"+str(Tracksavailable)
      else
        LabelTrack.text=str(Tracksavailable)
      end if
      TrackNoRead=1 
      SensePreemphasis
      exit
    end if
    
  Next a
  
  exit   
  
else
  Textarea1.text="Volume" +str(b)+" .TOC.plist not available, probably not an audio cd."+endofline
end if

else
Textarea1.text=“Volume”+str(b)+" File does not exist. Not an audio cd." +endofline
end if
'Textarea1.text=Textarea1.text+" volume nummer: "+str(b)+EndOfLine
next b
[/code]

So, is it not safe to use GetFolderItem and Volume(i).name for shell paths, since MacOS and its UNIX parts handles some signs differently? But if I use it in PathTypeShell mode, shouldn’t I get a shell compatible path?

It’s several years since I wrote this program, so I will take some time to figure out how everything is ticking… But I guess the only thing I need to get things working again is the shellpath with compatible signs.

Also, when I played this album/folder yesterday, I can swear that it was named with a “:” on the desktop, so maybe there is a bug that sometimes lets this slip right through sometimes. Another bug is that this cd is named “Audio CD” if the cd was in the drive when the computer was started (like in the old days, when all audio CDs were named “Audio CD”…).

And if I cant use GetFolderItem and Volume(i).name to get a path that is correct in the shell, I need to learn how to do the scanning of the volumes (to find the audio cd) in the shell?

[quote=323144:@Markus Winter]No.

There is a difference between a WINDOWname and a FILEname.
[/quote]
But the same goes for the single audiofiles of that window. They are named 1. Ives/ XXXXX etc, but if I open the file with VLC its Ives: XXXXXX
I accept the fact that MacOS and UNIX does this differently, but I do not understand why the very same files works sometimes and sometimes not in my Xojo program.
Also I do not understand why GetFolderItem and Volume(i).name (PathTypeShell) returns something that is not accepted by If f.exists (the first making a MacOS version and the latter only accepting the UNIX version file name).

I believe I’m kind of an expert on this subject, having dealt with file system drives and apps that browse all files on a Mac (such as File Any File).

Here’s the thing:

Mac OS has originally used “:” to separate directories and files names in a path. That’s the format you still get when using “FolderItem.AbsolutePath”. With the introduction of Unix based files systems to the Mac, where POSIX APIs define the “/” as the path separator (what you get with ShellPath and NativePath), Apple has simply switched “/” and “:”.

What this means:

You may create a file using the older (FSRef based) APIs, which allow “/” but not “:” in a name. Then, if you read it back using the new (POSIX) APIs, you’ll get any “/” replaced by “:”.

Now you need to know that FolderItem.Name uses the OLD API, as does the Finder when showing a file’s name. That’s why you can name a file in the Finder “a/b” but not “a:b”. And FolderItem.Name will give you “a/b”.

This all comes down to this:

You can put a “:” into a name if you use the right APIs, but it’ll be shown as “/” in Finder and other OSX apps, usually, unless they show you the entire POSIX (Unix) path, where “/” is instead the delimiter and names with “/” get them replaced with “:”.

Does that make sense?

Thank you. It makes sense. -And Xojo is not handling this difference, but it could?

Anyway. Would it be safe to swap “:” for “/” to make my program work with this signs?
Can the “/” or “:” be used for something else in the file name, making a swap problematic?

Short version, which crashes when if.exist is fed a filname with a “/”:
Dim f as FolderItem
Dim b as integer
for b=0 to VolumeCount-1
f=GetFolderItem("/Volumes/"+Volume(b).name, FolderItem.PathTypeShell)

swap “/” for “:” here, would that be a resonably safe solution?<<<<
If f.exists then
msgbox(str(b))
end if
next b

Roger,
not sure what you want to achieve there. What good does it do if you can plug a “:” into a file name if the Finder (and a FileOpen dialog) shows it as a “/”, then?

You’ll have to accept that you cannot have a “:” in a file name that’s shown to the user. You could however, use a similar-looking character instead, by replacing all “:” with “?” or “?”, for instance. It looks almost the same but has a different code and is not causing problems in file names. (I found this by using the Keyboard Preferences’ “Character Viewer”, google it).

BTW, putting together a path like you do is a bad style and can lead to other problems if you don’t know exactly what you do (and you don’t apparently).

So, change this line:

f=GetFolderItem("/Volumes/"+Volume(b).name, FolderItem.PathTypeShell)

to:

f = Volume (b)

That already gives you the path to /Volumes/volname, or to “/” for the root volume. Your construct is wrong.

And what you get when you use your code is not a crash. A crash means that the app quits without your control. But in your case, you can an Exception from Xojo, and you can handle that, so you have control over it. What you get is a NilObjectException because f become nil, and then you reference f, which is not allowed.

Now, how did you check that a CD is really named “Ives: An American Journey”, and how did you check that in Terminal, by which command, and what did you see there? Let me guess:

You did “ls /Volumes” in Terminal and saw the CD volume there, with a “:” in its name?

That would directly relate to what I wrote previously: In POSIX (Unix, Shellpath) file names, a “:” may be in a file name, and that’s what the CD is using. But if you look at it in the Finder, the name will be instead “Ives/ An American Journey”, right? Because “:” gets switched with “/”. And the same happens in Xojo: You see the names the Finder sees. Same thing if you get the Name from “Volume(b)”.

You can’t do anything about this naming rule.

But if you want to show the CD name in your program, you can simply replace any “/” in a name with “:”, which is probably what is originally meant, anyway. Then you’re displaying the name correctly.

Hi,

I scan the volumes for a hidden file to determine which one is the audio CD. I must use a shellpath for that, since Xojo (as far as I know) otherwise does not show hidden files. At least it didn’t back in 2014.

f=GetFolderItem("/Volumes/"+Volume(b).name+"/"+".TOC.plist", FolderItem.PathTypeShell) '.TOC.plist shows that is the Audio-CD-folder
I tried replacing “/” for “:” before “if f.exists” and I can see if the “.TOC.plist” is in there or not. After this all CD:s I tried plays fine (including this one).

So the question is, would a swap “/” for “:” in the right place be an acceptable workaround? It seems to work well , but I am not sure if there are problems that I haven’t thought of?

Ok. I see. I just figured “else” would take care of it. It seems that I need to read up on that and see if I can grasp how to do it.

This does not let me see if the hidden file is in there, right?

Reading up on the colon thingy, it seems Apple made changes over time swapping delimiters and allowing characters depending on context (a mess) and one last(?) change in El Capitan.
My problems probably started when I upgraded from 10.8.5 directly to Sierra couple of months ago. Before I upgraded to Sierra to the latest 10.12.4 this CD would sometimes play and sometimes not and it is too late to find out why.
I inserted this cd in OSX 10.10.2 and it is named Audio-CD there, which explains why it works with my program there.

If I restart my Mac with Sierra 10.12.4 with this CD in the drive it gets named Audio-CD, which works. But if I eject and insert it is “Ives/ An American Journey”. The cd-text thingy is not so consistent it seems and is different over OSX versions too it seems.

Anyway, reading on I see no problem (yet) in just changing the “/” into “:” to make it work in a shellpath (for finding that hidden file). If it is a bad idea, please tell.

Obviously with Folder.Item and folderitem.name I can find the hidden .TOC file.
I was looking for a way to do that back in 2014, but from what was said Xojo could not list hidden files…
I guess I do not have to fiddle with the shellpath anymore.