Finding multiple applications

Does anybody know a way to get a list of all the applications installed on a Harddisk or getting a list from every application that has a certain creator?

All my scripts will only find the first application it can find or I have to specify the direct folder where the applications recide, to get multiple applications

What I need or want is a more global function for it.

Regards,

Casper Voortman


use AppleScript version "2.5"
use framework "Foundation"
use script "FileManagerLib" version "2.2.1"
use scripting additions

set theRootFolderPosixPath to POSIX path of (path to startup disk)

set folderContents to objects of theRootFolderPosixPath ¬
	searching subfolders true ¬
	include invisible items false ¬
	include folders true ¬
	include files true ¬
	result type urls array

set thePred to current application's NSPredicate's predicateWithFormat:"pathExtension IN[c] %@" argumentArray:{{"app"}}
set all_Applicatiions_List to (folderContents's filteredArrayUsingPredicate:thePred) as list

I don’t know yet how to filter the files in AppleScriptObjc with UTI. Can get AppleScriptObjc UTI of the files without applying repeat loop?

The following code throws the error “Unable to parse the format string "UTI-CONFORMS-TO %@"” number -10000:

set thePred to current application's NSPredicate's predicateWithFormat:"UTI-CONFORMS-TO %@" argumentArray:{{"public.image"}}
set all_Applicatiions_List to (folderContents's filteredArrayUsingPredicate:thePred) as list

That’s going to take a while, though – getting every file on the disk is a big ask. Hmm, I just did a test and it’s not as bad as I feared, taking just over a minute here (plus a while to present the result).

Anyway, if Casper is happy enough to rely on Spotlight indexing, this does it in less than a second on my Mac:

use AppleScript version "2.5" -- macOS 10.11 or later
use scripting additions
use script "Metadata Lib" version "2.0.2"

set theFolder to POSIX path of (path to startup disk)
set thePaths to perform search in folders {theFolder} predicate string "kMDItemFSName ENDSWITH[c] '.app'"

Either way, Casper will need to download and instal the relevant script library from here:

https://www.macosxautomation.com/applescript/apps/Script_Libs.html

(Strangely, the FileManagerLib returned 1816 entries, while Spotlight said 1808. :rolleyes: )

Maybe some applications Spotlight does not have access? It would be interesting to know what these applications are.

Most are within other apps or packages.

As this script relies on Spotlight indexing, as does mdfind, would this be expected to produce the same output as:

do shell script "mdfind 'kMDItemFSName == \"*.app\"'"

I’m not a massive fan of calling out to a shell from within an AppleScript, and would probably prefer to enumerate specific directories known to contain applications, but can’t deny that the return speed from the pre-indexed search is astounding.

To the OP: purely out of curiosity, what necessitates having to perform an exhaustive systemwide search for app bundles ? A lot of them living outside of the regular spots seem to be those residing inside other bundles, and wouldn’t seem to be of much concern —to me at least—in an immediately obvious way. I have my system maintain a text file containing a list of applications located inside /Applications and /System/Library/CoreServices, which are enumerated by a script semi-regularly to keep the file up-to-date. What sort of project are you working on ?

I believe the right-hand-side of the predicate string needs to evaluate to a unary string value in order to have each array element make a comparison against it. Your argument array contains a single-item list with a UTI string, which I’m imagining would lead to a non-sensical comparison by each array element against an array object, which would never return true if it got that far. See if it works or if your error message changes when you remove the UTI string from its list, i.e.

predicateWithFormat:"UTI-CONFORMS-TO %@" argumentArray:{"public.image"}

or simply:

predicateWithFormat:"UTI-CONFORMS-TO 'public.image'"

If you wanted to have comparisons made against multiple UTI strings, you might be able to do so using ANY, possibly like this:

predicateWithFormat:"UTI-CONFORMS-TO ANY %@" argumentArray:{{"public.image", "public.text", "public.data", ... }}

That said, I haven’t tested any of this so I may be wrong, or if I’m at least in the ball park, either Shane can correct me, or you can tweak it a bit more from there.

Yes (I didn’t check exactly, but the totals match here). There are two different APIs to do a metadata search, one C-based and one using Objective-C. The latter uses typical NSPredicate syntax, so there can be subtle differences in the predicate string. mdls presumably uses the C-based API, which was released before the Objective-C one.

I could have used “kMDItemFSName LIKE ‘*.app’”. I suppose I used ENDSWITH because my gut feeling is that avoiding wildcards is always going to be quicker, but it’s probably more superstition/hope, and irrelevant here.

Either way, both APIs presumably call exactly the same code.

I'm not a massive fan of calling out to a shell from within an AppleScript

For a moment I missed the not in there, and was about to mount an argument :slight_smile:

No. The UTI of a file is not a property, but a resource property. You can only avoid loops with properties (that is, where you can use methods that require no arguments).

And if it were a property, UTI-CONFORMS-TO is an operator, like CONTAINS or ENDSWITH, so the predicate would need to be of the form “ UTI-CONFORMS-TO %@”.

For a Spotlight search, you can use this:

set thePaths to perform search in folders {theFolder} predicate string "kMDItemContentTypeTree CONTAINS  %@" search arguments {"public.image"} 

You’re mostly right about the right-hand-side, although ANY is for use on the left-hand-side – you would probably need to use ORs to check on multiple UTIs. There’s just the small matter of having a left-hand-side :wink:

The OP is someone with a single post that formulated their question 16 years ago. Good luck with determining what works for them and why. :wink:

That is quite enough for me. This is even better, as probably faster in search speed. Thanks for the tip about UTI and for this snippet too.

Oops.

Maybe it’s related to what I described in : https://macscripter.net/viewtopic.php?id=47010

The lib return the aliases and the symbolic links which Spotlight doesn’t.
Here the lib return also Darktable.app and GIMP-2.10.app which Spotlight doesn’t.
I may understand for the aliases and symbolic links, not for the two named applications.

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) mardi 6 aout 2019 10:17:08

Some of it could be. Many of them were within the Xcode bundle, though, and I can understand that not being indexed. I didn’t investigate any further than that.

Thank you Shane.

I may understand for aliases and symlinks but I’m really puzzled for Darktable and GIMP.

May it be due to the fact than for these two applications the subfolder Contents/MacOS contain several files.

for Darktable:
darktable public.unix-executable
darktable-bin public.unix-executable
darktable-bin.dSYM com.apple.xcode.dsym
darktable-chart public.unix-executable
darktable-chart-bin public.unix-executable
darktable-chart-bin.dSYM com.apple.xcode.dsym
darktable-cli public.unix-executable
darktable-cli-bin public.unix-executable
darktable-cli-bin.dSYM com.apple.xcode.dsym
darktable-cltest public.unix-executable
darktable-cltest-bin public.unix-executable
darktable-cltest-bin.dSYM com.apple.xcode.dsym
darktable-generate-cache public.unix-executable
darktable-generate-cache-bin public.unix-executable
darktable-generate-cache-bin.dSYM com.apple.xcode.dsym
darktable-rs-identify public.unix-executable

for GIMP:
gegl public.unix-executable
gimp public.unix-executable
gimp-bin public.unix-executable
gimp-console dyn.ah62d4rv4ge8xcqa - a 17 bytes long alias pointing to gimp-console-2.10 (below)
gimp-console-2.10 dyn.ah62d4rv4ge8xcqa
gimp-debug-tool dyn.ah62d4rv4ge8xcqa - a 6 bytes long alias pointing to gimp-debug-tool-2.0 (below)
gimp-debug-tool-2.0 dyn.ah62d4rv4ge8xcqa
gimptool-2.0 dyn.ah62d4rv4ge8xa
python public.unix-executable
python2 public.unix-executable - a 6 bytes long alias pointing to python (above)
xdg-email public.unix-executable

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) mardi 6 aout 2019 16:18:15

I don’t know, to be honest. I downloaded Darktable, and couldn’t see anything problematic. But there’s nothing wrong with having multiple executables in Contents/MacOS – in fact, I’ve seen one Apple employee encouraging it only recently. It’s a bit of a mystery.