List all applications with a specific BundleId

Mac OS X

Hi guys,

I need to get a list of folderitems to all applications whose bundle id is xxx.xxxxx.xx. Can’t figure it out and felling lazy so I just ask the experts :slight_smile:

I want to present a nice popup menu for the user to choose which version of these applications to be used.

Thanks!

I can’t remember in which Thread this has been discussed… But I remember having written this example project :wink:

Edit:
Here are two Threads where this has come up. Well, it’s more about the application folder itself, which has changed in Catalina. But when looking for an .app by BundleIdentifier, that won’t matter.
https://forum.xojo.com/56837-specialfolder-applications-points-to-system-applications-in-mac
https://forum.xojo.com/56114-specialfolder-returns-wrong-path-in-10-15/

add this and call it with whatever bundle id it is you’re looking for
you’ll get back an array of folderitems (or an empty array)

Private Function FindAppsByBundleID(psBundleID As String) as FolderItem()
  Dim oResults() As FolderItem
  
  If (psBundleID = "") Then 
    Return oResults
  End If
  
  #If TargetMacOS Then
    //https://developer.apple.com/documentation/coreservices/1449290-lscopyapplicationurlsforbundleid?language=objc
    
    Declare Function LSCopyApplicationURLsForBundleIdentifier Lib "Foundation" (inBundleIdentifier As CFStringRef, outError As Ptr) As Ptr
    Declare Function NSArrayCount Lib "Foundation" selector "count" (ptrToNSArray As Ptr) As UInteger
    Declare Function NSArrayObjectAtIndex Lib "Foundation" selector "objectAtIndex:" (ptrToNSArray As Ptr, index As UInteger) As Ptr
    Declare Function CFURLCopyFileSystemPath Lib "Foundation" (anURL As Ptr, pathStyle As Int32) As CFStringRef
    
    Const kCFURLPOSIXPathStyle = 0
    Const kCFURLHFSPathStyle = 1
    
    Dim ptrToArray As Ptr = LSCopyApplicationURLsForBundleIdentifier(psBundleID, Nil)
    If (ptrToArray = Nil) Then Return Nil
    
    Dim iResultCount As UInteger = NSArrayCount(ptrToArray)
    If (iResultCount < 1) Then Return Nil
    
    For i As Integer = 0 To iResultCount - 1
      Dim ptrToNSURL As Ptr = NSArrayObjectAtIndex(ptrToArray, i)
      If (ptrToNSURL = Nil) Then Continue
      
      Dim sNativePath As String = CFURLCopyFileSystemPath(ptrToNSURL, kCFURLPOSIXPathStyle)
      
      Try
        Dim oResult As New FolderItem(sNativePath, FolderItem.PathTypeNative)
        oResults.Append(oResult)
      Catch UnsupportedFormatException
        'ignore
      End Try
    Next
    
    If (oResults.Ubound >= 0) Then 
      Return oResults
    End If
    Return oResults
  #EndIf
  
  Return oResults
  
  
End Function

#1 This is possible, App Wrapper and our other apps do it. We use the NSWorkspace API to do it.
#2 The functionality has been deprecated by Apple, they don’t want apps doing this anymore. I would suggest reconsidering this functionality as it may be removed as early as next summer, or worse, get broke and no fixes applied.

There is another possibility and that’s to use Spotlight to find applications for you. There is a spotlight control within Xojo, again I would caution against adding too much value to this feature as Apple is hiring more macOS “Security” engineers to lock down more of the OS. I expect that a future version of the macOS will not allow applications to read the contents of other applications, especially when those applications are in the Applications folder.

Currently you can use the NSWorkspace API from a Sandboxed application (in the Mac App Store) to get the bundle path, I’ve not tried reading the property list of the application & I suspect that it won’t work, although you may be able to use NSBundle API to read the bundle & obtain the version number.

Thank you all for your help :slight_smile: