Compile AppleScript into application with parameters
Asked Answered
D

1

3

There is an AppleScript method:

on displayError(theErrorMessage)
    display dialog theErrorMessage
    return "done"
end displayError

I wanna compile this script with passing parameter into (not run it with osascript!)My_Application.app

something like

osacompile - o My_Application.app My_Script.applescript "This is error message as parameter" 

In this case, I will have compiled app which I can run. Looking for a command on how exactly to compile the script with passing parameters. As compilation takes a lot of time - I wanna do it only ones. After run My_Application.app what is in times faster than do it via osascript. If input parameters changed - just recompile the application.

A good option is to collect somehow return value from running app, but it is a little bit another question

Doglike answered 28/8, 2019 at 10:41 Comment(6)
How is this different from your previous question?Bondman
the different is compile script to app, not run - just compileDoglike
If you are wanting to compile a script using some parameters, you can just use a regular script (or editor) to replace some placeholder text with your arguments. If you are wanting to run a compiled script application, you can use NSProcessInfo to get the arguments.Bondman
could you please explain how to compile it? I did not face successDoglike
You can use the osacompile shell utility, for example: osacompile -o /path/to/output.app /path/to/input.applescriptBondman
my answer here #3489797Singhalese
B
8

To get command line arguments for an AppleScript application, you can use NSProcessInfo via some AppleScriptObjC. The main issue is that there isn't a handy way to return a result to the command line, so you will need to do something else such as write to a file.

The process info arguments include the executable path, but that can be skipped. Getting the arguments this way also works with osascript, although its path is also added to the arguments.

The following will work as a script or an application:

use framework "Foundation"
use scripting additions

on run
    set arguments to (current application's NSProcessInfo's processInfo's arguments) as list
    if first item of arguments contains "osascript" then set arguments to rest of arguments -- skip osascript path
    if (count arguments) is 1 then set end of arguments to "no arguments"
    repeat with anItem in rest of arguments -- skip the main executable path
        displayError(anItem)
    end repeat
    # osascript still returns the last result
end run

on displayError(theErrorMessage)
    display dialog theErrorMessage
    return "done"
end displayError

From the Terminal, you can use a variety of commands:

/path/to/application.app/Contents/MacOS/applet "this is a test" "Another test"
open /path/to/application.app --args "this is a test" "Another test"
osascript /path/to/script.scpt "this is a test" "another test"

To use arguments to a script for compiling an AppleScript application, you can use placeholder text in a source file, then use a script or text editor to replace it. The osacompile shell utility can then be used to compile the source into an application. It takes a text or script file, with the result based on the extension of the output file (the -o option).

For a complete example:

The Test.applescript file (this will be used as a template - the placeholder text will be replaced in an edited output file):

display dialog "This is a test.
It is only a test.

The date is ##DATE##
Some name: ##NAME##
An Identifier: ##ID##

End of test."

The application script:

use framework "Foundation"
use scripting additions

global arg1 -- this will be the replacement for the NAME parameter
global arg2 -- this will be the replacement for the ID parameter

on run -- example
    try
        set arguments to (current application's NSProcessInfo's processInfo's arguments) as list
        if first item of arguments contains "osascript" then set arguments to rest of arguments
        set arguments to rest of arguments
        if (count arguments) < 2 then set arguments to getArguments()
        set {arg1, arg2} to arguments
        processFile(choose file with prompt "Choose the AppleScript source text file:" of type "com.apple.applescript.text")
    on error errmess
        display alert "Error" message errmess
    end try
end run

to getArguments()
    set theName to text returned of (display dialog "Enter 'Name' parameter:" default answer "Jane Scripter")
    set theID to text returned of (display dialog "Enter 'Identifier' parameter:" default answer "42")
    return {theName, theID}
end getArguments

to processFile(theFile) -- get a list of file items for fixPlaceholders
    set outputFile to (((path to desktop) as text) & "edited.applescript")
    set datePlaceholder to "##DATE##"
    set namePlaceholder to "##NAME##"
    set idPlaceholder to "##ID##"
    set _date to " -e \"s/" & datePlaceholder & "/`date '+%m-%d-%y'`/g\" "
    set _name to " -e \"s/" & namePlaceholder & "/" & arg1 & "/g\" "
    set _id to " -e \"s/" & idPlaceholder & "/" & arg2 & "/g\" "
    set theFile to theFile as text
    set output to (do shell script "cat " & quoted form of ((POSIX path of theFile)) & " | sed " & _date & _name & _id)
    (my output:output toFile:outputFile)
    do shell script "osacompile -o " & quoted form of POSIX path of (((path to desktop) as text) & "Finished.app") & space & quoted form of POSIX path of outputFile
end processFiles

to output:someThing toFile:someFile
    try
        set fileRef to (open for access someFile with write permission)
        set eof of fileRef to 0 -- clear any existing
        write someThing to fileRef -- overwrite
        close access fileRef
    on error errmess
        log errmess
        try -- make sure file is closed on any error
            close access fileRef
        end try
    end try
end output:toFile:

From the Terminal, the above application can be run by using the following, where the first argument will be used for the "NAME" parameter and the second for the "ID" parameter:

open /path/to/application.app --args "First, Last" "Yep, looks like you."

The application will ask for the source file ("Test.applescript", above) and then output an edited source file and an application built from it onto your desktop.

Bondman answered 28/8, 2019 at 21:54 Comment(4)
Dear, this is exactly what I am looking for - your example is amazing - thank you!)Doglike
dear, there is another issue - application is running in another thread. In another word, I ran in Terminal, command finished (Terminal is ready to accept new line/code), but the application is still running. The goal is to wait when the app will finish and only after allow to run next command. Any thought?Doglike
I don't know what your workflow is doing - what are you running this from?Bondman
The conversion to JavaScript is ObjC.import("Foundation"); $.NSProcessInfo.processInfo.argumentsAvis

© 2022 - 2024 — McMap. All rights reserved.