Issue opening a new instance of my app on Mac

Greetings All:

I seem to be having an issue on macOS with my desktop app. I have it coded such that when the user right-clicks a file, and selects open with myapp, then my desktop app will launch and open that file.

On Mac, Windows, and Linux this works fine, with a notable exception:

On Windows and Linux, while my app is still running, I can go to the file explorer, right click on a different file and open it in a “new” instance of my application. On the Mac, however, as long as I have an instance of my app already running, nothing happens. It simply won’t launch a new instance.

Here’s the code I use to open a new instance.

// Launching another instance of the current running app
#If TargetMacOS Then
  var exe As FolderItem = App.ExecutableFile
  var appBundle As FolderItem = exe.Parent.Parent.Parent
  var s As New Shell
  
  s.Execute("open -n " + appBundle.NativePath)
#ElseIf TargetWindows Or TargetLinux Then
  App.ExecutableFile.Open
#EndIf

I am using the DocumentOpened Event within the App Object as well, which populates this folderitem: f = New FolderItem(App.LoadFileReferenced, FolderItem.PathModes.Native)

App.LoadFileReferenced is a public property that holds the Folderitem passed in via the DocumentOpened event. Then in the open event of my Window, is where I have code that loads the file into memory.

Like I said earlier, it only works on the Mac as long as no instance of my app is already open. Am I missing some setting for the Mac that will allow multiple instances of a desktop app to open?

I know that it’s going to be a ‘duh’ moment.

The line "s.Execute(“open -n " + appBundle.NativePath)” has the same effect as going to the App in the Finder and double-clicking on the App. An open app in this case just comes to the front.

DocumentOpened event only sends the app “item” which is the FolderItem for the document on disk. Treat that inside your app like you would treat “item” from “Var item As FolderItem = dlg.ShowModal”.

If you want multiple instances of your app open, you can have your main app open more copies of itself via shells.

s.Execute(App.ExecutableFile.ShellPath + " " + i.Tostring + " """ + name + """")

You just have to be sure to keep references to those shells around or the instances will close.

In this case, I’m passing in an index and a filename as arguments, but you could pass in a path to a file or whatever you would like.

macOS does not normally launch a new instance for each opened file. Your app is expected to handle multiple files within the same instance, so using a public property on App is less than ideal. I normally handle this by passing the FolderItem received in DocumentOpened into the constructor of new window instance. That window instance is then the one solely responsible for that file. If the window is closed, the file is too. For a single window application, the same concept is still usable, but needs some extra consideration.

Don’t try to make macOS behave like Windows and Linux in this regard. You’ll get multiple icons for your app in the dock, and Mac users will be pissed off.