This workaround is better for me, as I don’t like manual operations. So, thanks for your script. It goes to my Scripts library in this form:
use AppleScript version "2.5"
use framework "Foundation"
use scripting additions
property |⌘| : a reference to current application
set {item1, item2, item3} to {"Documents", "Applications", "Choose an application"}
set whatToDo to choose from list {item1, item2, item3} default items {item3}
if whatToDo is false then error number -128
set whatToDo to whatToDo's item 1
if whatToDo is item3 then
set appName to name of (choose application)
if appName is in {"Keynote", "Numbers", "Pages"} then set appName to "Iwork." & appName
set recentDocumentsPath to POSIX path of ((path to application support from user domain as text) & "com.apple.sharedfilelist:com.apple.LSSharedFileList.ApplicationRecentDocuments:com.apple." & ¬
appName & ".sfl2")
else
set recentDocumentsPath to POSIX path of ((path to application support from user domain as text) & "com.apple.sharedfilelist:com.apple.LSSharedFileList.Recent" & whatToDo & ".sfl2")
end if
set plistData to |⌘|'s NSData's dataWithContentsOfFile:recentDocumentsPath
set recentDocuments to |⌘|'s NSKeyedUnarchiver's unarchiveObjectWithData:plistData
set documentPaths to {}
if recentDocuments ≠ missing value then
repeat with aDocument in (recentDocuments's objectForKey:"items")
set documentBookmark to (aDocument's objectForKey:"Bookmark")
set {documentURL, resolveError} to (|⌘|'s NSURL's URLByResolvingBookmarkData:documentBookmark ¬
options:0 relativeToURL:(missing value) bookmarkDataIsStale:(missing value) |error|:(reference))
if resolveError is missing value then
set end of documentPaths to documentURL's |path|() as string
else
display dialog resolveError's localizedDescription as text
end if
end repeat
end if
documentPaths
I edited the script in message #4 so that it treat some non-standard Apple naming and show how to complete with non Apple products (I coded three examples).
I would be glad to know why many applications aren’t proposed by choose application.
It’s the case for many applications which I bought from the App Store and which are stored in a subfolder named “Applications_MAS” . Xcode or Stuffit Expander are proposed but EasyDraw or EasyFind aren’t.
Same behavior which many applications stored in a subfolder named “Applications perso”. BBEdit or Script Debugger are proposed but Libre Office isn’t.
Some applications stored in the Applications folder are missing too: Data Rescue.app, DiskMaker X 7 for High Sierra.app, GIMP-2.10.app, Malwarebytes.app are some of them
For info, here is a list of the sfl2 files dedicated to applications which are available on my SSD:
The list above without extensions is list of CFBundleIdentifier. I don’t know how, but is seems, this maybe used for automated getting required by system names.
How can I convert application name to its CFBundleIdentifier?
set appName to name of (choose application)
set appName to id of application appName
I applyed this and… Hm, it works:
use AppleScript version "2.5"
use framework "Foundation"
use scripting additions
property |⌘| : a reference to current application
set {item1, item2, item3} to {"Documents", "Applications", "Choose an application"}
set whatToDo to choose from list {item1, item2, item3} default items {item3}
if whatToDo is false then error number -128
set whatToDo to whatToDo's item 1
if whatToDo is item3 then
set appName to name of (choose application)
set appName to id of application appName
set recentDocumentsPath to POSIX path of ((path to application support from user domain as text) & "com.apple.sharedfilelist:com.apple.LSSharedFileList.ApplicationRecentDocuments:" & ¬
appName & ".sfl2")
else
set recentDocumentsPath to POSIX path of ((path to application support from user domain as text) & "com.apple.sharedfilelist:com.apple.LSSharedFileList.Recent" & whatToDo & ".sfl2")
end if
set plistData to |⌘|'s NSData's dataWithContentsOfFile:recentDocumentsPath
set recentDocuments to |⌘|'s NSKeyedUnarchiver's unarchiveObjectWithData:plistData
set documentPaths to {}
if recentDocuments ≠ missing value then
repeat with aDocument in (recentDocuments's objectForKey:"items")
set documentBookmark to (aDocument's objectForKey:"Bookmark")
set {documentURL, resolveError} to (|⌘|'s NSURL's URLByResolvingBookmarkData:documentBookmark ¬
options:0 relativeToURL:(missing value) bookmarkDataIsStale:(missing value) |error|:(reference))
if resolveError is missing value then
set end of documentPaths to documentURL's |path|() as string
else
display dialog resolveError's localizedDescription as text
end if
end repeat
end if
documentPaths
Here is a new version which trigger only existing files.
use AppleScript version "2.5"
use framework "Foundation"
use scripting additions
property |⌘| : a reference to current application
Germaine()
on Germaine()
set begOfPath to (path to application support from user domain as text) & "com.apple.sharedfilelist:"
set begOfPathLong to begOfPath & "com.apple.LSSharedFileList.ApplicationRecentDocuments:"
set specialCases to {"Applications", "Documents"}
tell application "Finder"
set theChoices to specialCases & name of files of folder begOfPathLong
end tell
set appName to choose from list theChoices
if appName is false then error number -128
set appName to appName's item 1
if appName is in specialCases then
set recentDocumentsPath to POSIX path of (begOfPath & "com.apple.LSSharedFileList.Recent" & appName & ".sfl2")
else
set recentDocumentsPath to POSIX path of (begOfPathLong & appName)
end if
try
set plistData to |⌘|'s NSData's dataWithContentsOfFile:recentDocumentsPath
set recentDocuments to |⌘|'s NSKeyedUnarchiver's unarchiveObjectWithData:plistData
set documentPaths to {}
repeat with aDocument in (recentDocuments's objectForKey:"items")
set documentBookmark to (aDocument's objectForKey:"Bookmark")
set {documentURL, resolveError} to (|⌘|'s NSURL's URLByResolvingBookmarkData:documentBookmark options:0 relativeToURL:(missing value) bookmarkDataIsStale:(missing value) |error|:(reference))
if resolveError is missing value then
set end of documentPaths to documentURL's |path|() as string
end if
end repeat
documentPaths as list
on error
error "The selected application is not treated or has no sfl2 associated file"
end try
end Germaine
I built another version in which I use a list of apps derived manually from the list of available files.
I feel that a version which doesn’t require some duty from the user is better.
Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) mardi 10 septembre 2019 09:07:24
Thanks, Yvan. I tried your last version too. I liked it. Now, with our last posts your code has not 1 but 2 extremely cool solutions. Thanks again to Stefan for starting point.
As I am pig headed, I repeat what I already wrote:
I would be glad to know why many applications aren’t proposed by choose application.
It’s the case for many applications which I bought from the App Store and which are stored in a subfolder named “Applications_MAS” . Xcode or Stuffit Expander are proposed but EasyDraw or EasyFind aren’t.
Same behavior which many applications stored in a subfolder named “Applications perso”. BBEdit or Script Debugger are proposed but Libre Office isn’t.
Some applications stored in the Applications folder are missing too: Data Rescue.app, DiskMaker X 7 for High Sierra.app, GIMP-2.10.app, Malwarebytes.app are some of them
And I add a question: where is iBooks storing its list of recents items?
It has its own Recent items menu but I see no file storing such infos and the Recents Items > Documents menu doesn’t display books open in iBooks.
Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) mardi 10 septembre 2019 13:57:58
“The choose application dialog initially presents a list of all applications registered with the system. To choose an application not in that list, use the Browse button, which allows the user to choose an application anywhere in the file system.”
As I understand, on Mac system registered apps is those from identified by Apple developers… It is intresting,were on Mac is registered apps path… It should be managed by Gatekeeper
So, my answer is: no, all applications are proposed by choose application, with Browse button in this dialog.
I suspect that’s well out of date — the dialog changed quite a long time ago (when script apps moved to bundles, I suspect — it was the move to bundles with Info.plist scriptability entries that made it feasible to easily check which are scriptable).
Go into Script Editor and choose File → Open Dictionary. The list will obviously only show scriptable apps and libraries. Click on the Kind column so applications are sorted before script libraries.
Leave the dialog open and go into Script Debugger and run this script:
choose application
Compare the lists in the two dialogs. I think you’ll find they’re identical.
You are right. I ran your scripts, Shane. The dialogs are almost same for Open dictionary and for Choose application.
But this may again be a coincidence, based on Apple’s policy, to highlight the programs of those developers who pay. In any case, the user can select any application in the choose application through the “Browse” button, and this is important for this topic.
And, is one important difference: press Browse in Open dictionary, go to Applications folder. You can’t choose nonscriptable app. But doing this with Browse in Choose application dialog you can choose any application. So, I think, all is related to money and not to scriptability.
I don’t know, Shane, may be one scriptable app non registered to work on Mac?
Thank you Shane.
It makes sense.
I don’t believe that it’s a problem of money because most of the applications bought thru MacAppStore aren’t proposed although they came from registered developers. The proposed ones are : Amphetamine, Aperture, JSON Helper, Omnigrafle, SiteSucker, Stuffit Expander, The Unarchiver, XCode, Instruments and Simulator which belong to Xcode and iBooks Author. All of them are scriptable.
Being forced to click Browse is really annoying so I will stay with the script which offer only the applications which have a related sfl file.
So now the remaining question is : where is iBook storing it’s list of recent items?
It’s curious that an application made by Apple doesn’t apply the standard scheme.
Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) mardi 10 septembre 2019 16:47:05
You’re a hard man to convince. Save an applet in /Applications. See that it doesn’t show up in choose application. Now open its Info.plist file and add:
<key>NSAppleScriptEnabled</key>
<true/>
Open the script in an editor, make a change and save. Now try choose application again.
Yes it’s true. But you convinced me with the last test. It is very rare for a knowledgeable person to share his knowledge so easily. Thank you, Shane, for the great help on this site. I always read your posts with interest.
I rarely leave a script as is more than 5 days so don’t be surprised if I post a new version.
I understood that I may ask the system to make the link between an apple ID and the name of the application.
Given that I was able to allow us to choose among a list of true applications names.
Here I have one case of file which have no available application name so I treat this sort of case but most of us will never see that at work.
use AppleScript version "2.5"
use framework "Foundation"
use scripting additions
property |⌘| : a reference to current application
Germaine()
on Germaine()
set begOfPath to (path to application support from user domain as text) & "com.apple.sharedfilelist:"
set begOfPathLong to begOfPath & "com.apple.LSSharedFileList.ApplicationRecentDocuments:"
tell application "Finder" to set theFiles to name of files of folder begOfPathLong
set theApps to {}
repeat with anItem in theFiles
set appID to text 1 thru -6 of anItem
try
set appName to name of (application id appID)
on error
set appName to appID
end try
set end of theApps to appName
end repeat
# I disabled FavoriteVolumes because selecting it urged the system to open numerous dmg files.
set specialCases to {"RecentApplications", "RecentDocuments", "FavoriteItems"} # , "FavoriteVolumes"
set theChoices to specialCases & theApps
set appName to choose from list theChoices
if appName is false then error number -128
set appName to appName's item 1
if appName is in specialCases then
set recentDocumentsPath to POSIX path of (begOfPath & "com.apple.LSSharedFileList." & appName & ".sfl2")
else
repeat with i from 1 to count theApps
if appName = item i of theApps then
set recentDocumentsPath to POSIX path of (begOfPathLong & item i of theFiles)
exit repeat
end if
end repeat
end if
try
set plistData to |⌘|'s NSData's dataWithContentsOfFile:recentDocumentsPath
set recentDocuments to |⌘|'s NSKeyedUnarchiver's unarchiveObjectWithData:plistData
set documentPaths to {}
repeat with aDocument in (recentDocuments's objectForKey:"items")
set documentBookmark to (aDocument's objectForKey:"Bookmark")
set {documentURL, resolveError} to (|⌘|'s NSURL's URLByResolvingBookmarkData:documentBookmark options:0 relativeToURL:(missing value) bookmarkDataIsStale:(missing value) |error|:(reference))
if resolveError is missing value then
set end of documentPaths to documentURL's |path|() as string
end if
end repeat
documentPaths as list
on error
error "The selected application is not treated or has no sfl2 associated file"
end try
end Germaine
Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) mercredi 11 septembre 2019 21:17:06
Hi! I came across this thread because I am looking for a way to parse the recent items of Affinity Designer 2. There seems to be a bug that deletes the items from the sfl2 file. But there is a very similar-looking file located here:
The script in post #9 of this thread doesn’t list the .sfl or .sfl2 file for your application? Are you sure? This file has binary data and your .dat file has text (XML) format.
.dat files are created by applications for use by the application itself and will not be easily decrypted. Especially not having this paid app on your computer. Perhaps one of the experienced users has it to help with the problem.
It does list the file for Affinity Designer 2. But due to a bug that file does not have any recent bookmarks once you quit the application. The bug has been reported several months ago. No fix yet.
Here is the error I get when running the script for the .dat file:
**error** "*** -[NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class (RecentDocumentInfo) for key (NS.objects) because no class named \"RecentDocumentInfo\" was found; the class needs to be defined in source code or linked in from a library (ensure the class is part of the correct target). If the class was renamed, use setClassName:forClass: to add a class translation mapping to NSKeyedUnarchiver" number -2700