It is sometimes desirable to pass arguments to an AppleScript application at launch time. While there is no direct way to accomplish this, several workarounds have been used. Here are some options:
- Save the application as a stay-open application, launch the application, wait until it is finished launching, then call a handler within the application with the argument values as the handler's argument. Drawbacks to this approach include the need for the application to be a stay-open application and the need to wait for the application to finish launching before sending it the argument values.
- Save the argument values to a temporary file on disk, launch the application, then have the application read then delete the temporary file. A drawback to this approach is the overhead involved in saving the file to disk and then deleting it after it is read.
- Execute the application via a [i]run script[/i] command in the calling script of the form: [i]run script file ...HFS path to application... with parameters ...argument values...[/i], then capture the argument values in the application with an explicit run handler of the form: [i]on run myArgs[/i] A significant drawback to this approach is that the application is not actually launched; rather, the code is executed as a script in the context of the [i]run script[/i] command.
The following method passes the argument values directly to the application at launch time and avoids the above limitations:
- In the calling script, serialize the argument value, or list or record of argument values if multiple values are to be passed, into a text representation of the argument. This is accomplished through the time-tested technique of forcing an error message on the argument value and extracting the text representation from the message. Then launch the application with an open shell command, and pass the serialized argument value to the application via the open command’s –args option. Place the following code in your calling script:
set myArgs to {1, 2.2, "three", true, missing value, null, path to home folder, current date, {1, 2, 3}, {aa:1, bb:2, cc:3}} -- or whatever value or values you wish to pass to the application
set myAppPath to "/path/to/MyApp.app" -- place the POSIX path to your application here
set serializedValue to my serializeValue(myArgs)
do shell script ("open -a " & myAppPath's quoted form & " --args " & serializedValue's quoted form)
on serializeValue(val)
-- Returns the text representation of the input value
set tid to AppleScript's text item delimiters
try
|| of {val} -- embedding the object in a list allows proper handling of certain object types (e.g., script objects)
on error m
try
set AppleScript's text item delimiters to "{"
set m to m's text items 2 thru -1 as text
set AppleScript's text item delimiters to "}"
set valAsText to m's text items 1 thru -2 as text
on error
try
{||:{val}} as null -- backup solution if "|| of {val}" fails
on error m
try
set AppleScript's text item delimiters to "{"
set m to m's text items 3 thru -1 as text
set AppleScript's text item delimiters to "}"
set valAsText to m's text items 1 thru -3 as text
on error
set AppleScript's text item delimiters to tid
error "Could not get a text representation of the object."
end try
end try
end try
end try
set AppleScript's text item delimiters to tid
return valAsText
end serializeValue
- In the application, capture the serialized argument that was passed from the calling script using ASObjC’s NSProcessInfo class, then deserialize the serialized argument into its original value using a run script command. Note that the first item of the processInfo’s arguments list is the POSIX path to the application itself, whereas the second item is the serialized argument value, which is the item of interest. Place the following code in your AppleScript application:
use framework "Foundation"
use scripting additions
set myArgs to run script ((current application's NSProcessInfo's processInfo's arguments as list)'s second item)
-- myArgs now contains the original argument values
One limitation to this approach (and to the other approaches listed above) is that only native AppleScript values may be passed. Complex objects (e.g., script objects) and non-AppleScript application objects generally cannot be passed.
Addendum: I jumped the gun with the last paragraph. It is possible to pass some non-AppleScript application objects. See the next post for a description of how to accomplish this.
Edit note: I made a slight cosmetic change from my original post to the calling script code above to make it a bit clearer to read.