是否可以从 ExtendScript 外部执行 JSX 脚本?

IT技术 javascript adobe extendscript indesign-server
2021-03-06 18:11:32

通常,当您编写 .jsx 脚本以自动化 Adob​​e 产品(如 InDesign、Illustrator 或 Photoshop)时,您可以从 ExtendScript IDE 编写、调试和执行脚本。是否可以绕过 ExtendScript 并从第三个程序运行脚本?

我认为 Adob​​e 产品有一个内置的 JavaScript 解释器,ExtendScript 可以连接到它来访问 Adob​​e 对象模型并自动化他们的软件。我希望能够像在 ExtendScript 中一样直接连接到该解释器并运行 jsx 文件。

6个回答

你在 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's 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 中获取数据是有限制的。您无法从 JavaScript 中打印到标准输出。相反,将要返回的值作为 JSX 文件的最后一条语句;它将由osascript. (原因如下:JSX 文件中的最后一个值是do javascriptAppleScript 语句的返回值。这也是 AppleScript 文件中的最后一个值,并osascript打印最终值。)

您从 JavaScript 返回的值可以是数字、字符串、数组或任何其他在转换为字符串时仍保留其值的内容。如果要返回复杂对象,则需要#include 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 调试器的选项。有关详细信息,请在 AppleScript 编辑器中打开 Illustrator 词典。

窗户呢?有任何想法吗?
2021-04-28 18:11:32
亚历山大:你能发布一个新问题,更详细地说明你想做什么吗?
2021-05-12 18:11:32
您知道 AppleScript 中的结果值是否可以以任何方式重用吗?我希望 AppleScript 根据 JavaScript 返回的值做出不同的反应。谢谢。
2021-05-14 18:11:32
这是运行文件目录的方式:在运行时 argv tell 应用程序“Adobe Illustrator”将 f 设置为 POSIX 文件“#{file}”作为别名 do javascript f with arguments argv end tell end run
2021-05-19 18:11:32
@David 查看我对 windows 的回答
2021-05-19 18:11:32

对于 Windows 用户,您可以使用 vbs 脚本。通过提供参数的参数传递给.jsx脚本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";
}

运行时,您应该看到 Illustrator(或任何 adobe 程序)警报“hello”,然后“test”将返回到 stdout(您应该在命令提示符窗口中看到它)。

如果您安装了多个版本的 Adob​​e 应用程序,请使用 Illustrator.Application.xx,其中 xx 是版本号(十进制)以获取您想要的版本。
2021-04-21 18:11:32
仅供参考,对于那些喜欢坚持使用所有 javascript 的人,这里的解决方案可以重写为 Microsoft JScript。然后它将是一个 javascript 版本(可以执行 ActiveX/COM 调用)来执行实际的 JSX javascript 代码。
2021-04-26 18:11:32
如果您运行的是 Windows x64 并且希望 32 位版本的 Photoshop 来制作一个包含以下内容的批处理文件来运行您的示例脚本: START C:\Windows\SysWOW64\cmd.exe /K "cscript test .vbs 你好”
2021-04-28 18:11:32
像宣传的那样工作!
2021-05-16 18:11:32

这适用于 Windows:

"C:\Program Files (x86)\Adobe\Adobe Photoshop CS5\Photoshop.exe" C:\completepathto\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(而不是 Elements),那么您可以将“echo %%f”更改

"%%f\..\..\Photoshop.exe" C:\completepathto\my.jsx 
您是否也可以通过这种方式将脚本参数传递给 JSX 文件,作为脚本路径之后的 Photoshop 的附加参数?
2021-04-20 18:11:32
@David:迟到的回复,但是,同样的方法适用于 OSX。
2021-04-21 18:11:32
我想知道类似的方法是否适用于 Mac:/pathOnMacTo/Photoshop /completePathTo/my.jsx
2021-05-06 18:11:32

直接的答案是YESIllustrator、InDesign 和 Photoshop 都可以通过 COM 编写脚本。您制作的任何可以访问 COM 的程序(例如 .net 语言、C++、BCX、Autohotkey 或 Powerpro)都可以告诉 Illustrator、InDesign 或 Photoshop 执行操作。

这是Powerpro的示例(您将需要powerpro的 com 插件),这适用于 CS4 和 CS5:

Function ComLoad() ;;MAKE SURE TO CALL .@ComUnload 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
    .@ComLoad()
    appRef.DoJavaScriptFile(whatscript)
    .@ComUnload()
    quit

这是我使用 Powerpro 制作的浮动工具栏的图像。这些按钮都附在 com 功能上。大多数时候我使用 com 函数来运行外部 jsx 脚本。

在此处输入图片说明

[编辑]

还有一种方法!您可以使用 Adob​​e Configurator 创建能够启动脚本的新面板。您可以按照自己喜欢的任何方式设计面板,结果与我上面描述的 powerpro 工具栏的效果非常相似。事实上,我从 powerpro 工具栏移到了 Adob​​e Configurator Panel。

但是,当 COM 被实例化时是否会启动 Adob​​e 应用程序,例如手动打开应用程序并通过脚本菜单执行脚本但以编程方式执行?或者这种技术是否可以在没有应用程序 GUI 的情况下在桌面上启动的情况下无 GUI 工作?我注意到,对于 MS Office(至少是早期版本),在调用 COM 时会像 Word 一样打开应用程序,完成后 GUI 关闭,因此您可以短暂地看到它打开以执行处理然后关闭。在可能的情况下,我更喜欢完全无 GUI 的选项。
2021-05-02 18:11:32
AutoIt 显然也支持 COM。我用过 AutoIt;它很棒,但我从来没有用过 COM 的东西。可能值得一看。
2021-05-08 18:11:32
好吧,您将必须编写代码来决定如果在之前未启动 adobe 应用程序的情况下调用 COM 函数时要执行的操作,并且您需要在开始 COM 调用之前执行此操作。但是,您不能做的是在不打开 Adob​​e 应用程序的 GUI 的情况下将 COM 函数调用到该应用程序。在某些情况下,MS Office 是另一回事。但是,如果 Adob​​e 应用程序已打开,您可以从另一个自定义应用程序对其进行无 GUI 的 COM 调用;但同样,Adobe 应用程序的 GUI 必须打开。我想你可能能够“隐藏”应用程序窗口或其他东西......
2021-05-09 18:11:32
在我上面用我的工具栏说明的情况下,由于工具栏只在 Adob​​e 应用程序打开时出现(感谢 powerpro!),我永远不必担心在运行 COM 脚本之前确保 Adob​​e GUI 是打开的。
2021-05-13 18:11:32

如果您将 .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,打开脚本面板并使用面板的上下文菜单打开脚本文件夹可能更容易。

我知道您可以通过打开 Flash 并将 .jsfl 脚本的路径作为参数传递来从命令行运行 .jsfl 脚本,但这似乎不适用于使用 InDesign 的 .jsx 文件。

HTH

不幸的是,每次新安装或更新 Adob​​e 产品时,“正确位置”都会发生变化。例如,这些评论非常古老,因为 CS5 现在“很久以前”了。
2021-04-21 18:11:32
CC 路径看起来类似: /Adobe Illustrator CC/en_US/Scripts
2021-04-29 18:11:32
有趣的。谢谢你,乔治。
2021-05-01 18:11:32