3

私はこれで頭を壁にぶつけています。スクリプト ブリッジを使用して、MS Word で新しいオートテキスト エントリを作成しようとしています。

これが私が使用しようとしているコードです:

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)>

自動テキスト入力が「未来」として示されているところ。何か案は?前もって感謝します!

4

3 に答える 3

0

@Philp Regan:あなたのコードをテストしましたが、驚いたことに、機能しません。目的の「自動テキスト入力」オブジェクトが作成されていません。おそらく、要素作成の失敗を黙って隠すブロックを含めていなければif、これに気付いたかもしれません。

元の ObjC コードから Python に翻訳された私のテストは次のとおりです。sdp残念ながら、Word 2011 のグルー ヘッダーを作成しようとしたときに突き出されたため、ObjC コードを使用できませんでした (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 コードを再試行しますが、結果はまったく同じになります。)

makeそして、これが SB のせいであり、他のせいではないことを証明するために、コマンドのatパラメーターの正しい参照形式を提供するためだけに微調整された、Python appscript の同等のコードを次に示します。

#!/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

every file of entire contents最初の例は、具体的なオブジェクト (ファイル、フォルダー、ディスクなど) のプロパティと要素のみを参照できるため、SB がその部分を構築できないため、コンパイルに失敗します。entire contentsプロパティは参照 (オブジェクト指定子) を保持しますが、具体的なオブジェクト。

2 つ目は、その部分を構築できないため失敗します。SBafter paragraph 2を担当する Apple 開発者は、挿入場所の参照を構築するために必要な // / メソッドを適切beforeに実装するのを忘れただけです!afterbeginningend

OP の Word の例は、SB のリリースから数日以内に根本的な問題が Apple に報告されたため、特に皮肉です: SBは form のイベント-[NSElementArray addObject:]を構築する方法しか知りません。ただし、Apple イベントの世界では、次の形式も完全に合法です: 、、、およびおそらくその他のいくつか。makemake new <element> at end of <elements> ...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 Event Manager API またはさまざまな特注またはサードパーティの C/CC+ フレームワーク上に直接構築されているアプリケーションは、多くの場合、大きく異なります。

たとえば、Finder、iTunes、Illustrator、Word などの Carbon ベースのアプリでは、しばしばmake new <element> at <elements> .... また、SB の を使用しようとすると-[NSElementArray addObject:]、フォームを理解できないため、アプリケーションはエラーをスローしますmake new <element> at end of <elements> ...。(そして、SB は、そのエラー報告もひどいので、静かにそのエラーを押しつぶします。)

SB の責任者である Apple の開発者は、これらのアプリケーションのハンドラーの正しい参照形式を構築することができないことを認めさえしました。make彼の「解決策」は、特に Finder と iTunes と通信するときにイベント-addObject:を組み立てる1 回限りの回避策をハックすることでした。make new <element> at <elements> ...言うまでもなく、それは根底にある問題に対処するものではありませんでしたが、6 年と 4 つの主要な OS リリースの後、他の多くのアプリケーションは、他の多くの愚かな SB 設計上の欠陥を破り続けています。

...

これらは難しいユースケースでも曖昧なユースケースでもありません - 基本的な Apple Events 101 のものです。したがって、Apple は SB をここまで台無しにする弁解の余地はありません。少なくとも半ダースのサードパーティの背後にあるすべてのコードと知識は言うまでもなく、AppleScript の内部実装とドキュメントのすべてにオープンにアクセスできたときはなおさらです。 Apple イベント プログラミングのすべてのすべきこととすべきでないことを学ぶための優れた橋からお粗末な橋まで。他の場所で述べたように、これはすでに解決された問題でした。SBが完全に解決するのに再び時間がかかりました。

Apple イベントは、実際のユーザーが実際の作業を行うために依存している実際のアプリケーションによって現実の世界で実際に話されているため、SB は単に Apple イベントを話すことができません。実際のアプリケーションのスクリプティングは、しばしば厄介で一貫性がなく、あいまいまたはバグのある辞書に悩まされ、厳密な仕様、堅牢で有能なフレームワーク、または開発者やユーザーのドキュメントがまったく不足しています。しかし、この不愉快な現実を受け入れて、魅力的ではないが確実に対処するための有能なツールをユーザーに提供する代わりに、SB は混乱全体を ORM の敷物の下に一掃し、存在しないふりをすることにしました。

これは、SB を些細なアプリケーションでの些細な作業にのみ使用するユーザーにとっては問題ないかもしれません。しかし、本当のプロの自動化作業を行っている私たちにとって、SB は単なる悪い冗談であり、Apple が何もしなかった場合よりも AppleScript の世界を後退させるために多くのことを行った.

于 2013-08-26T13:47:55.627 に答える
-1

SB が正しく動作しません。したことはありません。Cocoa アプリでさえ gyp を提供しますが、Word のような Carbon ベースのアプリとの互換性の問題が特に発生しやすく、参照やコマンドの作成方法に大きなばらつきがあります。

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 の面倒な作業の両方を回避できます。

詳細については、これらの投稿を参照してください。

OS X Cocoa アプリから Applescript に変数または文字列を渡す

Mac アプリで AppleScript ファイルを実行しますか?

...

次の出力が得られます: [...] 自動テキスト入力が「未来」として示されている場所。何か案は?

それは、SB の疑似 OO 偽物が漏れているだけです。それを無視します; とにかく混乱させるだけで、問題とは無関係です。

于 2013-07-16T21:21:04.633 に答える