Opening external storage in Finder is not working

I am trying to open external/mounted storage in Finder. I simply just want to show the root directory. I have tried multiple things, none worked.

NSWorkspace.shared.open()

Does work when opening the user's disk (e.g. Macintosh HD), but when comes to any of the external storages a warning appears: "The application "ABC" does not have permission to open "Folder Name".

Now, the app ha been granted all permissions in the preferences (Full Disk Access + Files and Folders). Furthermore, I don't even need or care of accessing this directory from within my app. I want the Finder to open it.

I am using com.apple.security.files.user-selected.read-only and testing on MacOS: 14.6.1

Answered by DTS Engineer in 805243022

I am trying to open external/mounted storage in Finder. I simply just want to show the root directory. I have tried multiple things, none worked.

First off, please file a bug on this, specifically asking for an API that will ask the Finder to open a new window that shows the contents of a folder/directory without taking any other action, then post the feedback number back here.

We have an API that is ALMOST what you want, but we really need to expand it some to cover all cases.

Moving to this option:

Though deprecated, the following is working for me in 14.6.1 (23G93):

NSWorkspace.shared.openFile("/Applications", withApplication: "Finder")

and (using a usb drive)

NSWorkspace.shared.openFile("/Volumes/NO NAME", withApplication: "Finder")

This code does NOT work in the general case, nor is it necessary to use the deprecated API. The modern equivalent here is "open(_:withApplicationAt...)" and if you compare the behavior of "openFile...", you'll find they behave the same. More specifically, unless you app has it's own access right to the directory:

  1. Certain directories work fine, with "/Applications/" being one example. Those are directories where the app sandbox has an implicit extension to allow apps access to those directories. Similarly, it should work if you app has valid access to the directory through some kind of security scoped resource.

  2. Most directories will fail.

  3. A few directories may SOMETIMES work, which is probably why this worked:

NSWorkspace.shared.openFile("/Volumes/NO NAME", withApplication: "Finder")

Volumes are the complicated edge case here as apps have an extension for "/Volumes/", but they don't have an extension for individual volumes. I'd need to play with the case above to be sure, but my guess is that this particular case was probably an ExFAT disk image, which ended up creating an extension that would otherwise not have existed.

Regardless, this isn't something you can rely on.

In any case, the correct API for this is actually "NSWorkspace.activateFileViewerSelecting()". That API was designed to be as "sandbox safe" as possible and, in fact, does not require your app to have ANY access or entitlement to the target file. You can actually pass in an arbitrary path and the Finder will happily show it, even if your app doesn't have any file system access at all.

Internally, it uses the same basic code path as the "Show In Finder" service, which basically just passes a string to the Finder which the Finder then presents. Unfortunately, that's where the limitation comes from. It selects an object "inside" it's parent folder, but it doesn't provide any way to simply open a directory "directly". That means you can use it to:

  • Open "/Volumes/" and select a particular Volume

OR

  • Open a volume and select an object inside it, assuming you happen to know the name of an object inside the volume.

...but you CAN'T use it to open and show a volume contents or the contents of an empty directory.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Though deprecated, the following is working for me in 14.6.1 (23G93):

NSWorkspace.shared.openFile("/Applications", withApplication: "Finder")

and (using a usb drive)

NSWorkspace.shared.openFile("/Volumes/NO NAME", withApplication: "Finder")

Also working for me on macOS 15.0 (24A335).

...

I am trying to open external/mounted storage in Finder. I simply just want to show the root directory. I have tried multiple things, none worked.

First off, please file a bug on this, specifically asking for an API that will ask the Finder to open a new window that shows the contents of a folder/directory without taking any other action, then post the feedback number back here.

We have an API that is ALMOST what you want, but we really need to expand it some to cover all cases.

Moving to this option:

Though deprecated, the following is working for me in 14.6.1 (23G93):

NSWorkspace.shared.openFile("/Applications", withApplication: "Finder")

and (using a usb drive)

NSWorkspace.shared.openFile("/Volumes/NO NAME", withApplication: "Finder")

This code does NOT work in the general case, nor is it necessary to use the deprecated API. The modern equivalent here is "open(_:withApplicationAt...)" and if you compare the behavior of "openFile...", you'll find they behave the same. More specifically, unless you app has it's own access right to the directory:

  1. Certain directories work fine, with "/Applications/" being one example. Those are directories where the app sandbox has an implicit extension to allow apps access to those directories. Similarly, it should work if you app has valid access to the directory through some kind of security scoped resource.

  2. Most directories will fail.

  3. A few directories may SOMETIMES work, which is probably why this worked:

NSWorkspace.shared.openFile("/Volumes/NO NAME", withApplication: "Finder")

Volumes are the complicated edge case here as apps have an extension for "/Volumes/", but they don't have an extension for individual volumes. I'd need to play with the case above to be sure, but my guess is that this particular case was probably an ExFAT disk image, which ended up creating an extension that would otherwise not have existed.

Regardless, this isn't something you can rely on.

In any case, the correct API for this is actually "NSWorkspace.activateFileViewerSelecting()". That API was designed to be as "sandbox safe" as possible and, in fact, does not require your app to have ANY access or entitlement to the target file. You can actually pass in an arbitrary path and the Finder will happily show it, even if your app doesn't have any file system access at all.

Internally, it uses the same basic code path as the "Show In Finder" service, which basically just passes a string to the Finder which the Finder then presents. Unfortunately, that's where the limitation comes from. It selects an object "inside" it's parent folder, but it doesn't provide any way to simply open a directory "directly". That means you can use it to:

  • Open "/Volumes/" and select a particular Volume

OR

  • Open a volume and select an object inside it, assuming you happen to know the name of an object inside the volume.

...but you CAN'T use it to open and show a volume contents or the contents of an empty directory.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Thanks a lot for your reply. I have tried all APIs you mentioned before I even posted this question (see also my reply for the 1st answer). When comes to disk images, I have tried it with a few types and none worked. Currently I'm testing it with APFS.

To be clear, I don't think you'll find anything useful/workable by trying different volume types/etc. What's actually relevant here is the specific way the volume mounted (this only matter if your app is going to do the mounting) and the broader access your app has. Note that this second factor is what can make testing this stuff tricky, primarily due to #1 below.

The same about .activateFileViewerSelecting(). As you already stated I have to select a particular file in order to get inside the dir (volume) - this unfortunately won't work for me.

Again, if you haven't already, please file a bug on this and then post the bug number back here. This is the kind of functionality that really only gets added because enough developers ask for it. If/when you have filed a bug, please post the bug number back here. I'd like us to provide a solution for this, but that's hard to justify unless there are bugs from developers asking for this functionality.

Returning back to your immediate issue:

My app lets users click on a volume which should open Finder

There isn't any truly reliable solution to this without new API, however, it's possible that you may be able to get some level of solution working, depending on exactly what you need. There are basically two options:

  1. Having the user select "/Volumes/" for your app will let you open volumes in the Finder while your app is running. However, a security scoped bookmark will NOT perserve this broader access.

  2. Security scoped bookmarks to specific volumes work fine, but that does mean that the user needed to grant your app access to that volume at some "earlier" point.

Note that, in the second case, you can validate whether or not the sandbox will block access to the directory by calling "startAccessingSecurityScopedResource" on the URL you're sending to the Finder. Success doesn't necessarily mean the Finder will be able to open the directory (for example, this doesn't check Unix permission), but failure does mean it won't work. However, this check does NOT work in the first case. startAccessingSecurityScopedResource will actually fail when #1 above is working.

I'm not sure how useful either of those approaches are, but those are the only options aside from activateFileViewerSelecting.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Opening external storage in Finder is not working
 
 
Q