0

I'm using the following Swift code to limit my GUI app on macOS to a single instance:

func IsAnotherInstanceRunning() -> Bool
{
    let thisApp = NSRunningApplication.current
    let thisBundleID = thisApp.bundleIdentifier
    let thisPID = thisApp.processIdentifier
    
    let workspace = NSWorkspace.shared
    
    let apps = workspace.runningApplications.filter { (app) -> Bool in
        
        if(app.bundleIdentifier == thisBundleID &&
           app.processIdentifier != thisPID)
        {
            return true;
        }
        
        return false;
    };
    
    //Found any?
    if(apps.count > 0)
    {
        return true
    }
    
    return false
}

I also have a console application written in C++. How can I do the same in pure C++?

Mainly how do I call anything related to NSRunningApplication and NSWorkspace?

Willeke
  • 14,578
  • 4
  • 19
  • 47
c00000fd
  • 20,994
  • 29
  • 177
  • 400
  • 1
    By the way, there's a few things that could be simplified in your example. Don't use `if b` with `return true` and `return false`. Just return `b`. E.g. `return apps.count > 0`. Also, you don't need to filter just to check for emptiness. There's `contains(where:)`, which you can just use like: `return workspace.runningApplications.contains(where: { app in app.bundleIdentifier == thisBundleID && app.processIdentifier != thisPID })` – Alexander Dec 24 '22 at 15:12
  • @Alexander: Thank you. Swift is not my language. I just started working with it less than a month ago. – c00000fd Dec 24 '22 at 15:32
  • No worries, I figured it'd be good to know, which is why I chimed in. The part about not checking booleans only to `return true` or `return false` applies equally to C++. – Alexander Dec 24 '22 at 18:43

1 Answers1

1

I believe you can use named mutexes to achieve what you want. You create a mutex with a specific name. If mutex already exists you quit.

https://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_mutexattr_getpshared.html

For crossplatform implementation make sense to take a look on https://theboostcpplibraries.com/boost.interprocess-synchronization named_mutex.

AlexTheo
  • 4,004
  • 1
  • 21
  • 35
  • Thanks. But will macOS remove such mutex automatically if my process crashes? – c00000fd Dec 24 '22 at 10:38
  • 1
    The mutex object is destroyed when there are no more handles referencing it. Look here: https://stackoverflow.com/questions/20379817/boostinterprocessnamed-mutex-vs-createmutex – AlexTheo Dec 24 '22 at 10:40
  • I know that it is destroyed in Windows (like your link shows) but I'm not sure about macOS/BSD? – c00000fd Dec 24 '22 at 10:42
  • `pthread_mutexattr_get/setpshared` will require setting up some shared memory, but, yes, if your process crashes or terminates for any reason, macOS (or any POSIX compliant OS) should close/remove all resources your process requested of it. If it doesn't, it's a bug in the OS. – Chip Jarred Dec 24 '22 at 10:42
  • Look on this thread https://stackoverflow.com/questions/7808431/boost-interprocess-named-mutex-remains-acquired-after-a-crash – AlexTheo Dec 24 '22 at 10:48