Возможно ли выполнение сценариев JSX извне ExtendScript?

Обычно, когда вы пишете сценарий .jsx для автоматизации продукта Adobe (например, InDesign, Illustrator или Photoshop), вы пишете, отлаживаете и выполняете сценарий из IDE ExtendScript. Можно ли обойти ExtendScript и запустить скрипт из третьей программы?

Я думаю, что продукты Adobe имеют встроенный интерпретатор JavaScript, к которому ExtendScript может подключаться для доступа к объектным моделям Adobe и автоматизации их программного обеспечения. Я хотел бы иметь возможность подключиться напрямую к этому интерпретатору и запускать файлы jsx так же, как в ExtendScript.

Ответ 1

Вы на Mac? Если это так, вы можете использовать AppleScript с инструментом osascript для выполнения вашего JavaScript. Вот несколько примеров:

Запуск JSX и возврат значения

Сохраните это как ~/temp/foo.scpt:

tell application "Adobe Illustrator"
     -- 'do javascript' runs any arbitrary JS.
     -- We're using the #include feature to run another
     -- file. (That an Adobe extension to JS.)
     --
     -- You have to pass a full, absolute path to #include.
     --
     -- The documentation alleges that 'do javascript'
     -- can be passed an AppleScript file object, but
     -- I wasn't able to get that to work.
     do javascript "#include ~/temp/foo.jsx"
end tell

И сохраните это как ~/temp/foo.jsx:

var doc = app.activeDocument;
var numLayers = doc.layers.length;

// The last value in the JSX file will be printed out by
// osascript. 
numLayers;

Теперь из командной строки запустите osascript ~/temp/foo.scpt Он напечатает количество слоев в активном документе Illustrator.

Получение данных из JavaScript ограничено. Вы не можете печатать на stdout из JavaScript. Вместо этого поместите значение, которое вы хотите вернуть, в качестве последнего оператора JSX файла; он будет напечатан с помощью osascript. (Здесь почему: Последнее значение в файле JSX - это возвращаемое значение оператора do javascript AppleScript. Это также последнее значение в файле AppleScript, а osascript выводит окончательное значение.)

Значение, возвращаемое из JavaScript, может быть числом, строкой, массивом или чем-либо еще, что сохраняет свое значение при преобразовании в строку. Если вы хотите вернуть сложный объект, вам нужно будет # включить библиотеку JSON и вызвать .toJSONString() на объекте.

Передача аргументов в JSX

Чтобы передать аргументы в код JSX, выполните следующий пример:

Файл ~/temp/args.scpt:

on run argv
    tell application "Adobe Illustrator"
        set js to "#include '~/temp/args.jsx';" & return
        set js to js & "main(arguments);" & return
        do javascript js with arguments argv
    end tell
end run

Файл ~/temp/args.jsx

function main(argv) {
    var layer = app.activeDocument.activeLayer;
    app.defaultStroked = true; 
    app.defaultFilled = true;

    // Top, left, width, height (in points).
    // Note that parameters start at argv[0].
    layer.pathItems.rectangle(argv[0], argv[1], argv[2], argv[3]);
}

И затем запустите osascript args.scpt 50 30 10 80

Отладка

В команде do javascript также есть опции для запуска отладчика ExtendScript. Для получения дополнительной информации откройте словарь Illustrator в редакторе AppleScript.

Ответ 2

Для пользователей Windows вы можете использовать vbs script. Передайте аргументы в .jsx script, предоставив аргументы команде cscript следующим образом: cscript test.vbs "hello". test.vbs может выглядеть так:

Dim appRef
Dim javaScriptFile
Dim argsArr()

Dim fsObj : Set fsObj = CreateObject("Scripting.FileSystemObject")
Dim jsxFile : Set jsxFile = fsObj.OpenTextFile("C:\Users\path\test.jsx", 1, False)
Dim fileContents : fileContents = jsxFile.ReadAll
jsxFile.Close
Set jsxFile = Nothing
Set fsObj = Nothing

javascriptFile = fileContents & "main(arguments);"

Set appRef = CreateObject("Illustrator.Application")

ReDim argsArr(Wscript.Arguments.length-1)

For i = 0 To Wscript.Arguments.length-1
    argsArr(i) = Wscript.Arguments(i)
Next

Wscript.Echo appRef.DoJavaScript(javascriptFile, argsArr, 1)

Wscript.Echo вернет последнюю строку, возвращаемую файлом .jsx. Пример файла .jsx может быть:

function main(argv) {
    alert(argv[0]);
    return "test";
}

При запуске вы должны увидеть "Иллюстратор" (или любую другую программу adobe) "hello", а затем "test" будет возвращен в stdout (вы должны увидеть его в окне командной строки).

Ответ 3

Это работает в окнах:

"C:\Program Files (x86)\Adobe\Adobe Photoshop CS5\Photoshop.exe" C:\completeepathto\my.jsx

Обратите внимание на путь к Photoshop. Он должен быть указан, так как он содержит пробелы.

Существует множество трюков для выяснения загрузки Photoshop. Здесь вы найдете все места, где был загружен Photoshop, и помещает их в x.lst

@REM  The Presets\Scripts doesn't really restrict where the loop is looking, 
@REM  thus the "IF EXIST" is needed.  The FIND makes sure that the 
@for /R "%ProgramFiles(x86)%\Adobe" %%f in (Presets\Scripts) 
  DO @IF EXIST %%f 
     (echo %%f | FIND /I "Adobe Photoshop C" >> x.lst )

Затем вы можете обрабатывать каждую строку в x.lst. ПРИМЕЧАНИЕ. Все "@for" должны быть на одной линии, я разделяю их на несколько строк для удобства чтения.

Если вы считаете, что будет только один Photoshop (а не элементы), вы можете изменить "echo %% f" до

"%%f\..\..\Photoshop.exe" C:\completepathto\my.jsx 

Ответ 4

Прямой ответ ДА. Illustrator, InDesign и Photoshop могут быть написаны через COM. Любая программа, которую вы создаете для доступа к COM (например, язык .net, С++, BCX, Autohotkey или Powerpro), может показать Illustrator, InDesign или Photoshop, чтобы что-то делать.

Вот пример Powerpro (вам понадобится плагин powerpro com), и это работает в CS4 и CS5:

Function ComLoad() ;;MAKE SURE TO CALL [email protected] WHEN EXITING FUNCTION CALLS!
      static objname="Illustrator.Application"
      static com_status, com_type
      static appRef=com.create_object(objname)
      endfunction

Function ComUnload();;this is end the com calls and unload com
    com.unload
    endfunction

После использования функции ComLoad() вы запускаете любой метод или функцию, предлагаемые библиотекой COM. Вот как использовать Powerpro, чтобы показать Illustrator для запуска вашего jsx или js файла:

;Run a script from anywhere
Function RunOtherScript(whatscript)
    If (file.Validpath(whatscript) == 0)do
        messagebox("ok","Whoops! That script doesn't exist!","ILL Runscript")
        quit
    endif
    [email protected]()
    appRef.DoJavaScriptFile(whatscript)
    [email protected]()
    quit

Вот изображение плавающей панели инструментов, которую я создал с помощью Powerpro. Все кнопки подключены к функциям com. Большую часть времени я использую функции com для запуска внешних скриптов jsx.

enter image description here

[править]

Есть другой путь! Вы можете использовать Adobe Configurator для создания новых панелей, способных запускать скрипты. Вы можете проектировать панель так, как вам нравится, и результаты очень похожи по сравнению с панелью инструментов powerpro, описанной выше. Фактически, я перешел с панели инструментов powerpro на панель конфигурации Adobe.

Ответ 5

Если вы поместите файлы .jsx в нужное место

Photoshop
folder location:
/Applications/Adobe\ Photoshop\ CS5/Presets/Scripts
menu location:
File > Scripts

Illustrator
folder location:
/Applications/Adobe\ Illustrator\ CS5/Presets.localized/en_GB/Scripts
menu location:
File > Scripts

InDesign
folder location:
/Users/{user}/Library/Preferences/Adobe\ InDesign/Version\ 7.0/en_GB/Scripts/Scripts\ Panel
menu location:
Window > Utilities > Scripts

Это дорожки на OSX, легко найти эквивалент в Windows для Photoshop и Illustrator, но для InDesign было бы проще открыть панель сценариев и открыть папку сценариев с помощью контекстного меню панели.

Я знаю, что вы можете запускать сценарии .jsfl из командной строки, открыв Flash и передав путь к .jsfl script в качестве аргумента, но это, похоже, не работает для .jsx файлов с InDesign.

HTH