How to tell an applet from an application

Using NSMetadataQuery, is it possible to distinguish between an applescript applet and a “real” application?

You can detect same or not by calculating checksum from each app’s runtime.

スクリーンショット 2023-05-27 16.53.35

スクリーンショット 2023-05-27 16.53.24

Thanks Takaaki, you gave me an idea.

This script is testing the executable name for scripts with the ‘app’ extension:

use framework "Foundation"
use scripting additions

set theQuery to "((kMDItemContentType == %@) OR (kMDItemContentType == %@) OR (kMDItemContentType == %@))"
set theArgs to {"com.apple.application-bundle", "com.apple.applescript.script-bundle", "com.apple.applescript.script"}
my filterQuery:{"/Applications", "/System/Applications"} pattern:theQuery arguments:theArgs

on filterQuery:theTargets pattern:thePred arguments:theArgs
	set theQuery to current application's NSMetadataQuery's new()
	theQuery's setPredicate:(current application's NSPredicate's predicateWithFormat:thePred argumentArray:theArgs)
	theQuery's setSearchScopes:theTargets
	theQuery's startQuery()
	repeat while theQuery's isGathering() as boolean
		delay 0.01
	end repeat
	theQuery's stopQuery()
	set theCount to theQuery's resultCount()
	set theResults to current application's NSMutableArray's new()
	repeat with iQuery from 0 to (theCount - 1)
		set thePath to ((theQuery's resultAtIndex:iQuery)'s valueForAttribute:(current application's NSMetadataItemPathKey))
		set theURL to (current application's NSURL's fileURLWithPath:thePath)
		if (theURL's pathExtension()'s isEqualToString:"app") then
			set theApplet to (theURL's URLByAppendingPathComponent:"/Contents/MacOS/applet")
			set theDroplet to (theURL's URLByAppendingPathComponent:"/Contents/MacOS/droplet")
			set theFancy to (theURL's URLByAppendingPathComponent:"/Contents/MacOS/FancyDropletFat")
			set theTest to (theApplet's checkResourceIsReachableAndReturnError:(missing value)) or (theDroplet's checkResourceIsReachableAndReturnError:(missing value)) or (theFancy's checkResourceIsReachableAndReturnError:(missing value))
			if theTest then (theResults's addObject:theURL)
		else
			(theResults's addObject:theURL)
		end if
	end repeat
	
	return theResults as list
end filterQuery:pattern:arguments: