是否可以从外部 ExtendScript 执行 JSX 脚本?
-
27-09-2019 - |
题
通常,当您编写 .jsx 脚本来自动化 Adobe 产品(如 InDesign、Illustrator 或 Photoshop)时,您可以从 ExtendScript IDE 编写、调试和执行脚本。是否可以绕过 ExtendScript 并从第三个程序运行脚本?
我认为 Adobe 产品有一个内置的 JavaScript 解释器,ExtendScript 可以连接到该解释器来访问 Adobe 对象模型并自动化其软件。我希望能够直接连接到该解释器并运行 jsx 文件,就像在 ExtendScript 中一样。
解决方案
您在Mac上?如果是这样,你可以使用的AppleScript与osascript
工具来执行你的JavaScript。下面是一些例子:
运行JSX和返回值
保存此作为〜/温度/ 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
并保存此作为〜/温度/ 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 javascript
的AppleScript语句的返回值这也就是在AppleScript的文件的最后一个值,并osascript
打印终值)
在从JavaScript返回的值可以是一个数字,字符串,阵列,或其他任何当转换为一个字符串,它保持其值。如果你想返回一个复杂的对象,你需要#包括一个JSON库和呼叫.toJSONString()
的对象。
将参数传递给JSX
要参数传递给JSX代码,按照此示例:
文件〜/温度/ 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
文件〜/温度/ 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编辑器。
其他提示
对于Windows用户,你可以使用一个VBS脚本。 cscript
:通过提供参数,像这样的cscript test.vbs "hello"
命令参数传递给.jsx脚本。 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";
}
当然,应该SEEE插图(或任何土坯程序)警报“你好”,然后“测试”将被返回到stdout(你应该看到它在命令提示窗口)。
这在 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),那么您可以更改“回显%%f” 到
"%%f\..\..\Photoshop.exe" C:\completepathto\my.jsx
直答案是是即可。 Illustrator中,InDesign和Photoshop可以全部通过COM照本宣科。任何程序,让你能够访问COM(如.NET语言,C ++,BCX,AutoHotkey的或PowerPro中)可以告诉Illustrator中,InDesign或Photoshop做的事情。
下面是臣(您需要的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脚本。
<强> [编辑] 强>
有另一种方式!您可以使用Adobe配置来创建新的面板,其能够启动脚本。你可以设计你喜欢的任何方式的面板,其结果是在效果上我上面所描述的PowerPro的工具栏十分相似。事实上,我从PowerPro中的工具栏为Adobe配置面板移动。
如果您将.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