I am currently in the process of building an AppleScript application. (Note that this is a plain AppleScript “application” created by using AppleScript Editor to create an AppleScript and then saving that script as an application). For this app, I need to know the filepaths of the recently opened files for the current user. I’ve tried many different methods so far, but none seem to be giving me the information that I need.
I’ve tried the following:
- I’ve tried the
com.apple.recentitems.plistfile, however the filepath information contained inside this file seems to be in Hex format, which when converted into ASCII is full of a lot of mumbo-jumbo, and the format of the mumbo-jumbo seems to change for different files and on different computers. - I’ve tried using the unix
findcommand to filter files opened in the past day, however here I can only choose between recently modified and recently accessed, not recently opened. Recently modified files won’t include opened files which aren’t modified (like an image that is opened but not edited), and recently accessed files seems to show all files which have been visible in Finder in thumbnail view, even if they haven’t been opened by the user. - I’ve tried venturing into Objective-C and the
LaunchServices/LSSharedFileList.hfile for gettingkLSSharedFileListRecentDocumentItems(similar to this answer), however I’ve never used Objective-C before so I’ve not been able to get anything to work properly with this.
Any help that anyone could provide to help me to get a list of the recently opened files for the current user would be very much appreciated. Furthermore, any help with being able to write the list of recently changed files to a text file would be great.
Your solution probably works, but perhaps what I came up with might be more workable.
Of the proposed 3 options you came up with, indeed the
LSSharedFile*commands are the best solution.With the advent of AppleScript script bundles (.scptd) and scripts that can be saved as application bundles (.app), you can quite easily include custom executables inside the bundle. As a result, you can make use of these executables to accomplish what you need to do if you couldn’t accomplish it with AppleScript alone or the default BSD subsystem tools.
So, in Xcode I created a new “Foundation Tool” project which used the following code:
While this code is similar to yours, instead of having to write the results to an intermediary file, it simply prints the file paths to standard out. This should allow dramatically-simplified coding on the AppleScript end of things. The result of building this Xcode project is a single “Unix Executable File” named
recentItemsFinaglerinstead of an application bundle.To make use of this built executable in an AppleScript, you first need to make sure the script is saved as a Script Bundle or Application and then the
Bundle Contentstoolbar item should be enabled like in the image below:Clicking that toolbar item shows the drawer which shows the contents of the script bundle or application bundle. To add your custom executable, just drag and drop it from the Finder like in the image below:
This will copy it into the script bundle like shown:
To locate this executable at runtime, you can use the
path to resourceAppleScript command which is part of theStandardAdditions.osax. (Note that depending on how you try to make use of thepath to resourcecommand in your script, you may encounter “Resource not found” errors when you run the script from within AppleScript Editor as opposed to running it by double-clicking on it in the Finder. If you encounter this type of an error, first make sure you’ve saved all of your changes to the script, then quit out of AppleScript Editor, then launch the script application by double-clicking on it in the Finder, after the script finishes running, re-open AppleScript Editor, then re-open the script application, then try running from within AppleScript Editor and see if it works).So, to make use of this
recentItemsFinaglerin your AppleScript, you could do something like the following:I’ll go through this AppleScript line by line to explain what it’s doing. We first create a global property
recentItemsFinagler, and set its initial value tomissing value. (missing valueis the AppleScript equivalent to Objective-C’snil).In case you’re not aware of it, global properties in AppleScript are like global variables in other languages with one important addition: when you run the script and assign a value to the property, that value is actually saved in the script file itself, and will persist to the next time you run the script.
The script first checks to see if
recentItemsFinagleris equal tomissing value, and if it is, sets it to the result of(path to resource "recentItemsFinagler"), which is an AppleScriptaliasreference. This is similar to an alias in the Finder in that it is able to successfully track changes like renames, and moving from one folder to another. If I had instead stored it as a simple string, and then moved this AppleScript application bundle from my Documents folder to my Desktop, the path would no longer be valid, and the property would have to be updated each time the script was run.Anyway, we then set
recentItemsStringto the result of the AppleScriptdo shell scriptrecentItemsFinaglertool, which is a string. To turn this into an AppleScript list of strings which represent paths, you use theparagraphs ofcommand.So by including the executable inside the script or AppleScript application’s bundle, you can get the desired result in less than 10 lines of code.
Sample project: RecentItemsFinagler.zip