I want determine path to applications without using path to command, because it launches the applications, and I want avoid this behaviour.
I found on the net 1 solution, but it is really slow. And I can’t understand why:
posixPathTo("TextEdit.app") of me
on posixPathTo(appName)
set launchServicesPath to "/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister"
-- get the path to all executables in the Launch Service Registry that contain that appName
set appPaths to paragraphs of (do shell script launchServicesPath & " -dump | grep --only-matching \"/.*\\" & appName & "\"")
return appPaths
end posixPathTo
Update:
I found very faster solution, but maybe someone still has better suggestion:
my posixPathTo:"Image Events"
on posixPathTo:appName
set bundleID to id of application appName
tell application "Finder" to return POSIX path of (application file id bundleID as alias)
end posixPathTo:
I was interested as well if this solution will return Posix path for slightly renamed copy of app, but it returns posix path to original application:
my posixPathTo:"Atom copy"
on posixPathTo:appName
set bundleID to id of application appName
tell application "Finder" to return POSIX path of (application file id bundleID as alias)
end posixPathTo:
--> /Applications/Atom.app/ <-- SHOULD BE /Applications/Atom copy.app/ instead
KniazidisR. I had both of the following in my notebook. The first is deprecated but works in my testing. Both take a millisecond or less to run.
use framework "Foundation"
use framework "AppKit"
set theWorkspace to current application's NSWorkspace's sharedWorkspace()
set thePath to (theWorkspace's fullPathForApplication:"TextEdit") as text
--> "/System/Applications/TextEdit.app"
--OR--
set bundleID to id of application "System Events"
set theWorkspace to current application's NSWorkspace's sharedWorkspace()
set thePath to ((theWorkspace's URLForApplicationWithBundleIdentifier:bundleID)'s |path|()) as text
--> "/System/Library/CoreServices/System Events.app"
Update to post #2:
As I checked, the script returns proper Posix path after verifying of slightly renamed application copy.
It seems to me, this is why path to command of Standard Additions firstly opens the application. That is, to be able to verify it in the case it is not verified by system.
Maybe, I am wrong, and launching the applications is due to the bad path to command design.
Thank you, @peavine, for this. Your suggestion is ultra fast and useful. I will use it in the future:
use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
my posixPathTo:"Atom copy"
--> "/Applications/Atom copy.app"
on posixPathTo:appName
set bundleID to id of application appName
set theWorkspace to current application's NSWorkspace's sharedWorkspace()
set thePath to ((theWorkspace's URLForApplicationWithBundleIdentifier:bundleID)'s |path|()) as text
end posixPathTo:
This previous post has a routine that returns more info
https://macscripter.net/viewtopic.php?id=47903
Here is a more detailed but shortened version of the script in the link above
use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
my appInfo:"TextEdit.app"
on appInfo:appName
local bundleIdentifier, currInfoPlistDictionary, currIsRunning, currProcessID
--, bundleURL, posixPath, hfsPath, appName, executableName, versionString, isAppleScriptEnabled, allowsUserInteraction, isBackgroundOnly, isRunning, processID, processIDs
set bundleID to id of application appName
set theWorkspace to current application's NSWorkspace's sharedWorkspace()
set currPOSIXPath to ((theWorkspace's URLForApplicationWithBundleIdentifier:bundleID)'s |path|()) as text
set currInfoPlistDictionary to (current application's NSDictionary's dictionaryWithContentsOfFile:(currPOSIXPath & "/Contents/Info.plist")) as record
set {currProcessIDs, currProcessID} to {{}, missing value}
tell ((current application's NSRunningApplication's runningApplicationsWithBundleIdentifier:bundleID) as list)
repeat with currObj in it
try
set end of currProcessIDs to currObj's processIdentifier() as integer
end try
end repeat
if currProcessIDs = {} then
set currIsRunning to false
else
set {currIsRunning, currProcessID} to {true, currProcessIDs's last item} -- Save the newest running instance of the application in a separate return property from the property containing the full list of running application instances
end if
end tell
tell currInfoPlistDictionary to return {appName:its CFBundleName, executableName:its CFBundleExecutable, bundleIdentifier:its CFBundleIdentifier, posixPath:currPOSIXPath, hfsPath:currPOSIXPath as POSIX file as text, versionString:its CFBundleVersion, isAppleScriptEnabled:its NSAppleScriptEnabled, isRunning:currIsRunning, processID:currProcessID, processIDs:currProcessIDs}
end appInfo: