Objective c OBJ-C脚本桥-创建具有属性的脚本对象时遇到问题(Microsoft Word)
我一直用这个把头撞在墙上。我正在尝试使用脚本桥在MS Word中创建一个新的自动图文集条目 以下是我尝试使用的代码:Objective c OBJ-C脚本桥-创建具有属性的脚本对象时遇到问题(Microsoft Word),objective-c,cocoa,scripting,applescript,scripting-bridge,Objective C,Cocoa,Scripting,Applescript,Scripting Bridge,我一直用这个把头撞在墙上。我正在尝试使用脚本桥在MS Word中创建一个新的自动图文集条目 以下是我尝试使用的代码: wordApplication *theWordApp = [SBApplication applicationWithBundleIdentifier:@"com.microsoft.Word"]; wordTemplate *theWordTemplate = [[theWordApp activeDocument] attachedTemplate]; wordAutoTe
wordApplication *theWordApp = [SBApplication applicationWithBundleIdentifier:@"com.microsoft.Word"];
wordTemplate *theWordTemplate = [[theWordApp activeDocument] attachedTemplate];
wordAutoTextEntry *theNewAutoTextEntry = [[[theWordApp classForScriptingClass:@"auto text entry"] alloc] init];
[[theWordTemplate autoTextEntries] addObject:theNewAutoTextEntry];
[theNewAutoTextEntry setName:@"test name"];
NSLog(@"%@", [theNewAutoTextEntry name]);
使用此选项,我得到以下错误:
*** -[SBProxyByClass setName:]: object has not been added to a container yet; selector not recognized [self = 0x6d9fbd0]
我也尝试过:
wordApplication *theWordApp = [SBApplication applicationWithBundleIdentifier:@"com.microsoft.Word"];
wordTemplate *theWordTemplate = [[theWordApp activeDocument] attachedTemplate];
wordAutoTextEntry *theNewAutoTextEntry = [[[theWordApp classForScriptingClass:@"auto text entry"] alloc] initWithProperties:[NSDictionary dictionaryWithObjectsAndKeys:@"testname", @"test", nil]];
NSLog(@"%@", [theNewAutoTextEntry name]);
这样我也会犯同样的错误
有趣的是,当我运行以下程序时:
wordApplication *theWordApp = [SBApplication applicationWithBundleIdentifier:@"com.microsoft.Word"];
wordTemplate *theWordTemplate = [[theWordApp activeDocument] attachedTemplate];
wordAutoTextEntry *theNewAutoTextEntry = [[[theWordApp classForScriptingClass:@"auto text entry"] alloc] init];
NSLog(@"%@", theNewAutoTextEntry);
我得到这个输出:
<future MicrosoftWordAutoTextEntry with properties (null)>
其中,自动文本输入指示为“未来”。有什么想法吗?提前谢谢 某人工作不正常;从来没有,将来也不会。它特别容易与基于碳的应用程序(如Word)发生兼容性问题,因为Word在构造引用和命令的方式上具有更大的可变性,尽管即使是Cocoa应用程序也会给它提供gyp 以下是如何在AppleScript中实现这一点,它可以完美地工作:
tell application "Microsoft Word"
make new auto text entry at attached template of active document ¬
with properties {name:"test name", auto text value:"test value"}
end tell
但是,将其转换为SB代码只会在以下行产生“选择器未识别”错误,因为SB无法构造所需的引用形式:
[theWordTemplate addObject:theNewAutoTextEntry];
假设您的目标是10.6或更高版本,请忘记SB,改用AppleScript ObjC桥。AppleScript是唯一仍然支持的解决方案,它知道如何正确地谈论Apple事件。ASOC使AppleScript脚本对象在应用程序的其余部分显示为普通的Cocoa类和实例,允许您的ObjC代码直接与AppleScript通信,反之亦然,从而避免了SB缺陷和NSAppleScript繁琐的工作
有关更多信息,请参见这些帖子:
我得到这个输出:[…]其中自动文本条目被指示为“future”。有什么想法吗
那只是某人的假货泄露出去了。忽视它;它只是让人困惑,而且与您的问题无关。您的思路是正确的,但似乎没有从其数组中获取对象,这是处理该对象所必需的。最好使用name属性初始化对象,以确保轻松检索。也就是说
word011 *theWordApp = [SBApplication applicationWithBundleIdentifier:@"com.microsoft.Word"];
word2011Template *theWordTemplate = [[theWordApp activeDocument] attachedTemplate];
// create the object with them name property to grab it later
NSString *testName = @"test name";
word2011AutoTextEntry *theNewAutoTextEntry = [[[theWordApp classForScriptingClass:@"auto text entry"] alloc] initWithProperties:[NSDictionary dictionaryWithObjectsAndKeys:testName, @"name", nil]];
[[theWordTemplate autoTextEntries] addObject:theNewAutoTextEntry];
// you created the object, but now you have to actually *get* the object
// check for existence first other EXC_BAD_ACCESS will happen
if ( [[[theWordTemplate autoTextEntries] objectWithName:testName] exists] {
theNewAutoTextEntry = [[theWordTemplate autoTextEntries] objectWithName:testName];
}
// name already set, so you can move with working with the object
//[theNewAutoTextEntry setName:@"test name"];
@Philp Regan:我测试了你的代码,但出乎意料的是,它不起作用:所需的“自动文本输入”对象是未创建的。如果没有包含隐藏元素创建中任何失败的
if
块,您自己可能已经注意到了这一点
下面是我从原始ObjC代码翻译成Python的测试-不幸的是,我无法使用您的ObjC代码,因为sdp
在尝试为Word 2011创建粘合头时呕吐(sdp
也有问题,在InDesign和其他应用程序上也有问题)
如您所见,自动文本输入
元素是未创建的;此外,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
再一次:脚本桥和sdp不能正常工作;从来没有,永远不会。除了常见的bug和遗漏之外,SB的设计还有根本性的缺陷:作为一个ORM,它试图将Cocoa狭隘的OO语义强加于Apple events广泛的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无法构造包含全部内容的每个文件
部分,因为它只能引用具体对象(文件、文件夹、磁盘等)的属性和元素,全部内容
属性包含引用(对象说明符),而不是具体对象
第二个将失败,因为它无法构建第2段之后的部分:负责SB的Apple开发人员只是忘记了在/开始之后实现构建插入位置引用所需的相应方法
OP的Word示例尤其具有讽刺意味,因为基本问题在SB发布后的几天内就被报告给了苹果:SB的-[NSElementArray addObject:][/code>只知道如何构造make
形式的事件在…
末尾新建。然而,在Apple events世界中,以下形式也是完全合法的:在…
创建新的,在…
创建新的,在…
创建新的,在…
结尾创建新的,可能还有一些其他形式
特定应用程序将理解哪些表单,哪些不理解,这由应用程序自己决定。脚本接口构建在Cocoa脚本上的应用程序都理解在…末尾进行新创建表单;然而,其脚本接口直接构建在Carbon Apple Event Manager API或各种定制或第三方C/CC+框架上的应用程序通常差别很大
例如,Finder、iTunes、Illustrator和Word等基于碳元素的应用程序通常要求您在…
上说“新建”,但SB不允许您构建这些表单。如果您试图使用SB的-[NSElementArray addObject:
,应用程序会抛出一个错误,因为它不理解末尾的make new
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