GetFolderItem Exists don't work

Latest Xojo, API 2.
I’m parsing a list of items in a string that that path and when I reach the second one, the g,exists is returning false. Why?? I checked g.nativepath and it’s correct path. The app exist at this location

Items = "/Applications/Safari.app;/Applications/TextEdit.app;/Applications/Calendar.app;"
PathFile = Checkprefs.NthField(";", ItemList)

g = New FolderItem(PathFile, FolderItem.PathModes.Native)

if g.Exists Then
  MessageBox(g.NativePath)
end if

I hadn’t looked at folder items in the /Applications directory before, but on Ventura at least, TextEdit and Calendar are in /System/Applications and Safari in /Applications is an alias to a deeper level in /System/Applications/. I don’t know how they do it in previous Mac versions. Do a Get Info on the app in Finder and it will show you where it is.

1 Like

You’re going to face a few different problems with this.

The first issue is that once you package up your app, sign it, notarize it, and send it off to another machine, GetFolderItem no longer works. Apple security restricts your application to accessing only files it’s given permission to and SpecialFolder.ApplicationData until your app is released from quarantine. My tip of advice has always been to develop as if GetFolderItem does not exist.

The next issue, which is what you may be facing on your development machine, is that some system utilities are in a different location. While it may look like they’re in /Applications/ they are in fact elsewhere. TextEdit and Calendar are in /System/Applications now, a read-only directory to protect the user from malicious software.

There are ways to acquire a FolderItem for these applications, but you’ll need MBS or declares, and to use their bundle identifiers. What are you trying to accomplish?

1 Like

I want the user to launch an app from a list. So I guess, my default list was just wrong locations.

So how to get the correct location if it’s just an Alias?

Xojo resolves it (for me at least). Your code shows me the real location:

var g as FolderItem
pathfile = "/Applications/safari.app"
g = New FolderItem(PathFile, FolderItem.PathModes.Native)
if g.Exists Then
  MessageBox(g.NativePath)
end if
1 Like

The correct way to do so would be using Bundle Identifiers NSWorkspace. I rely on MBS plugins to help me:

// Get the bundle
var oApp as NSBundleMBS = NSBundleMBS.bundleWithPath(NSWorkspaceMBS.fullPathForApplication("TextEdit"))

// oApp will be nil if the bundle identifier is not found,
// so we use this in lieu of a FolderItem.Exists check
if oApp <> nil then
  // Launch the app, returns a boolean of success but this code ignores the response
  call NSWorkspaceMBS.launchAppWithBundleIdentifier(oApp.BundleIdentifier)
  
end

Update: I misunderstood the NSBundleMBS documentation originally and have had to make an update to the code so that you may fetch an application by name.

References: NSBundleMBS, NSWorkspaceMBS

2 Likes