@Philp Regan:我测试了您的代码 - 令人惊讶的是 - 它不起作用:未创建了所需的“自动文本输入”对象。也许如果你没有包含if 块,它会默默地隐藏元素创建中的任何失败,你自己可能已经注意到了。
这是我从您的原始 ObjC 代码转换为 Python 的测试 - 不幸的是,我无法使用您的 ObjC 代码,因为sdp 在尝试为 Word 2011 创建胶水标题时呕吐(sdp 也像蚁丘一样有缺陷,并在 InDesign 和其他应用程序上搞砸了)。
#!/usr/bin/python
from ScriptingBridge import *
theWordApp = SBApplication.applicationWithBundleIdentifier_("com.microsoft.Word")
theWordTemplate = theWordApp.activeDocument().attachedTemplate()
testName = "test name 99"
theNewAutoTextEntry = theWordApp.classForScriptingClass_("auto text entry").alloc().initWithProperties_(NSDictionary.dictionaryWithObjectsAndKeys_(testName, "name", None))
theWordTemplate.autoTextEntries().addObject_(theNewAutoTextEntry)
print theWordTemplate.autoTextEntries().objectWithName_(testName).exists() # prints: False (!)
print theWordApp.lastError() # prints: None
如您所见,auto text entry 元素是未创建的;此外,SB 静默失败,让您不知道为什么操作不起作用。
(如果您愿意,我很乐意使用您自己创建的 Word.h 文件重试您的原始 ObjC 代码,但结果将完全相同。)
而且只是为了证明这是 SB 的错,而不是其他的错,这里是 Python appscript 中的等效代码,经过调整只是为了为 make 命令的 at 参数提供正确的参考形式:
#!/usr/local/bin/python3
from appscript import *
theWordApp = app(id="com.microsoft.Word")
theWordTemplate = theWordApp.active_document.attached_template
testName = "test name 101"
theNewAutoTextEntry = theWordApp.make(new=k.auto_text_entry, at=theWordTemplate, with_properties={k.name: testName})
print (theWordTemplate.auto_text_entries[testName].exists()) # prints: True
...
再一次:Scripting Bridge 和 sdp 不能正常工作;从来没有,永远不会。除了常见的错误和遗漏之外,SB 的设计存在根本缺陷:作为一个 ORM,它试图将 Cocoa 狭窄的 OO 语义强加于 Apple 事件的广泛 RPC + 关系查询语义,从而在两者之间造成严重的阻抗不匹配。 (这是 80/20/80 问题:80% 的时间它有效,但 20% 的时间它不起作用,80% 的时间你不知道为什么。)有很多 SB 失败的例子由于它对应用程序脚本的实际工作方式做出的所有有缺陷或不正确的假设,在 AppleScript 和 appscript 中完美运行的命令。
一些引用和命令甚至根本无法构造 - 例如,尝试将以下内容转换为 SB:
tell application "Finder"
get name of every file of entire contents of desktop
end tell
tell application "TextEdit"
tell document 1
duplicate paragraph 1 to after paragraph 2
end tell
end tell
第一个示例将无法编译,因为 SB 无法构造 every file of entire contents 部分,因为它只能引用具体对象(文件、文件夹、磁盘等)的属性和元素 - 以及 entire contents 属性持有一个引用(对象说明符),而不是一个具体的对象。
第二个将失败,因为它无法构造 after paragraph 2 部分:负责 SB 的 Apple 开发人员只是忘记实现适当的 before/after/beginning/end 构造所需的方法插入位置参考!
OP 的 Word 示例特别具有讽刺意味,因为根本问题在 SB 发布后几天内就报告给了 Apple:SB 的 -[NSElementArray addObject:] 只知道如何构造 make new <element> at end of <elements> ... 形式的 make 事件。但是,在 Apple 活动世界中,以下形式也是完全合法的:make new <element> at <element> ...、make new <element> at <property> ...、make new <element> at <elements> ...、make new <element> at end of <property> ...,可能还有其他一些形式。
特定应用程序可以理解哪些形式,哪些不可以由应用程序本身决定。脚本接口基于 Cocoa Scripting 构建的应用程序都理解make new <element> at end of <elements> ... 形式;但是,其脚本接口直接构建在 Carbon Apple 事件管理器 API 或各种定制或第三方 C/CC+ 框架上的应用程序通常差异很大。
例如,Finder、iTunes、Illustrator 和 Word 等基于 Carbon 的应用程序通常要求您输入 make new <element> at <elements> ...,但 SB 不允许您构建这些表单。如果您尝试使用 SB 的 -[NSElementArray addObject:],应用程序会抛出错误,因为它不理解 make new <element> at end of <elements> ... 表单。 (然后 SB 会默默地消除该错误,因为它的错误报告也很糟糕。)
负责为这些应用程序的make 处理程序构建正确参考表单的 SB even admitted it was incapable 的 Apple 开发人员。他的“解决方案”是破解一次性变通办法,导致-addObject: 在专门与 Finder 和 iTunes 交谈时组装make new <element> at <elements> ... 事件。不用说,这并没有解决根本问题,所以六年和四个主要操作系统版本之后,其他应用程序继续打破这个任何其他愚蠢的 SB 设计缺陷。
...
这些甚至不是困难或晦涩的用例 - 它们是基本的 Apple Events 101 内容。所以苹果真的没有理由把 SB 搞到这种程度:尤其是当他们可以开放访问所有内部 AppleScript 实现和文档时,更不用说至少六个第三方背后的所有代码和知识从优秀到糟糕的桥梁,从中学习 Apple 活动编程的所有注意事项。正如我在其他地方所说,这已经是一个已解决的问题:SB 再次完全解决它。
SB 根本无法说出 Apple 事件,因为它们实际上是由 真实用户 依赖的真实应用程序在真实世界中说出的做真正的工作。真正的应用程序脚本通常是混乱的、不一致的、被模糊或错误的字典所困扰,并且严重缺乏硬性规范、健壮、称职的框架或值得该死的开发人员或用户文档。但是,SB 没有接受这个令人不快的现实并为用户提供有时不吸引人但能胜任的工具来可靠地处理它,而是决定将整个烂摊子扫到 ORM 地毯下,假装它不存在。
对于那些仅将 SB 用于琐碎应用程序的琐碎工作的用户来说,这可能没问题,因此永远不要将其推到足够的程度,以使其无数的缺陷和缺点跳出来咬他们。但对于我们这些从事真正专业自动化工作的人来说,SB 只是一个糟糕的笑话,它比 Apple 什么都不做更能挫败 AppleScript 世界。