This is something I’ve done before with php shell scripts, as a way of making them multi-threaded. The script calls a copy of itself with a command line argument, and that argument tells the script to run as a child process rather than a parent. Then the two scripts can communicate via messages in an sql database, reading and writing files in a folder, or any other way.
I’m wondering if something like this would work in applescript? Just out of curiosity, I don’t currently have any need to do anything like this. I’m just wondering if I could?
use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
on run argv
path to me
path to current application
name of me
if class of argv is list then
if (count of argv) > 0 then
if (item 1 of argv) is in {"clean", "CLEAN"} then
clearError((item 2 of argv) as integer)
end if
else
main()
end if
else -- no arguments passed so it is main app
main()
end if
end run
on main()
local i, j, myPrefs, pid, cPath, temp, pcs, pm, tid
set pid to do shell script "echo $PPID"
set cPath to POSIX path of (path to me)
set pid to do shell script "osascript '" & cPath & "' " & " CLEAN " & pid & " &>/dev/null & echo $!" -- this runs the thread
try
tell application "loginwindow"
set myres to display dialog "Sample dialog text?" buttons {"Cancel", "Mount", "Skip"} cancel button 1 default button 1 with title "Thread Dialog…"
end tell
on error
set myres to {button returned:"Cancel"}
end try
delay 1
try
tell application "loginwindow" to display alert "Button \"" & (button returned of myres) & "\" was clicked!" giving up after 3
end try
end main
on clearError(pid as integer)
local i
tell application "System Events" to tell application process "loginwindow" -- do GUI stuff here
repeat with i from 10 to 1 by -1
tell me to delay 1
if window "Thread Dialog…" exists then exit repeat
try
do shell script ("ps -ax -o pid= " & pid)
on error -- calling script is not running
return
end try
end repeat
if i = 1 then return -- timeout
tell window "Thread Dialog…" to click button (some item of buttonList)
end tell
end clearError
** EDIT ** – I added more logic to the clearError to test if calling script still running and a better timeout
I have a script that auto mounts shares that are saved in a preference file. I do this so the shares don’t start with an open window after being mounted. If an error occurs when mounting one of the shares, the OS shows an error dialog, which can’t be auto closed by the main script. So I have it run a second copy of itself to monitor if the error dialog appears. I do this using GUI scripting.
You can also create separate instances of script objects from text or a file.
@Piyomaru wrote a sample parallel application about 15 years ago, although it seems to have fallen off the end of Apple’s mailing list and his site archives. It basically created copies of an application’s bundle for use as separate processes. I have some pieces, but maybe he has archives that go further back.
I have done something like this, but with handlers, not scripts.
I do this when I am searching a folder tree of undetermined and unequal depth.
I usually start my script or application by setting up a few global variables, initializing properties and setting up script libraries.
Then I call what I call the execution handler whose job is to call the handlers which actually do the work. This strategy isolates the handlers from each other and from the run handler, except as specifically designated.
For a script searching the folder tree, I typically have a handler:
searchFolder(FolderReference, searchTarget, etc)
This returns searchResult, typically a list of records, each record is one search result.
If searchFolder() identifies any subfolders, it calls “searchFolder()” (itself) on each subfolder, and concatenates each result to its own searchResult list.