ペーストボードに直接アクセスすることはできません。まず、launchdはプロセス1をペーストボード サーバーの mach ポートに登録しません。mach_port_names
最初に、ペーストボード サーバーのマッハ ポート ( ?)を取得する方法を見つける必要があります。また、ユーザーセッション間の直接通信は禁止されており2、それ以外の通信は制限されています。あなたのプログラムがペーストボード サーバーに接続する権利を持っているかどうかはわかりません。
Apple イベントを使用してクリップボードを文字列として取得および設定する例の最初のショットを次に示します。エラー処理は最小限か存在しません (私がどのように感じているかはわかりませんrequire_noerr
)。実行中にクリップボードのデータを複数回取得/設定する場合は、Apple イベントを保存し、クリップボードにコピーするときにAECreateDesc
&AEPutParamDesc
または (おそらく)を使用できますAEBuildParameters
。AEVTBuilderが役立つ場合があります。
NSString* paste() {
NSString *content;
AppleEvent paste, reply = { typeNull, 0L };
AEBuildError buildError = { typeNull, 0L };
AEDesc clipDesc = { typeNull, 0L };
OSErr err;
err = AEBuildAppleEvent(kAEJons, kAEGetClipboard,
typeApplicationBundleID, "com.apple.finder", strlen("com.apple.finder"),
kAutoGenerateReturnID, kAnyTransactionID,
&paste, &buildError,
""
);
require_noerr(err, paste_end);
err = AESendMessage(&paste, &reply, kAEWaitReply, kAEDefaultTimeout);
err = AEGetParamDesc(&reply, keyDirectObject, typeUTF8Text, &clipDesc);
require_noerr(err, pastErr_getReply);
Size dataSize = AEGetDescDataSize(&clipDesc);
char* clipData = malloc(dataSize);
if (clipData) {
err = AEGetDescData(&clipDesc, clipData, dataSize);
if (noErr == err) {
content = [NSString stringWithCString:clipData encoding:NSUTF8StringEncoding];
} else {}
free(clipData);
}
AEDisposeDesc(&clipDesc);
pastErr_getReply:
AEDisposeDesc(&reply);
pasteErr_sending:
AEDisposeDesc(&paste);
paste_end:
return content;
}
OSStatus copy(NSString* clip) {
AppleEvent copy, reply = { typeNull, 0L };
AEBuildError buildError = { typeNull, 0L };
OSErr err = AEBuildAppleEvent(kAEJons, kAESetClipboard,
typeApplicationBundleID, "com.apple.finder", strlen("com.apple.finder"),
kAutoGenerateReturnID, kAnyTransactionID,
©, &buildError,
"'----':utf8(@)",
AEPARAMSTR([clip UTF8String])
/*
"'----':obj {form: enum(prop), want: type(@), seld: type(@), from: null()}"
"data:utf8(@)",
AEPARAM(typeUTF8Text),
AEPARAM(pClipboard),
AEPARAMSTR([clip UTF8String])
*/
);
if (aeBuildSyntaxNoErr != buildError.fError) {
return err;
}
AESendMessage(©, &reply, kAENoReply, kAEDefaultTimeout);
AEDisposeDesc(&reply);
AEDisposeDesc(©);
return noErr;
}
上記の Core Foundation のアプローチはそのままにしておきますがNSAppleEventDescriptor
、Apple Event 応答からクリップボードの内容を抽出するために使用することをお勧めします。
err = AESendMessage(&paste, &reply, kAEWaitReply, kAEDefaultTimeout);
require_noerr(err, pasteErr_sending);
// nsReply takes ownership of reply
NSAppleEventDescriptor *nsReply = [[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&reply];
content = [[nsReply descriptorAtIndex:1] stringValue];
[nsReply release];
pasteErr_sending:
AEDisposeDesc(&paste);
paste_end:
return content;
}
また、NSAppleEventDescriptor
は よりもデバッガで調べるのが簡単ですAEDesc
。返信を調べるには、AEDebugReceives
osascript または Script Editor.app を使用するときに環境変数を設定することもできます。
AEDebugReceives=1 osascript -e 'tell application "Finder" to get the clipboard'
参考文献:
- 「ユーザー・セッションの構成」
- 「ログイン セッション間での通信」
- Mach Kernel Interface、特に:
- CFMessagePort リファレンス(マッハ ポート ラッパー):
- Apple Events プログラミングガイド
- Apple Event Manager リファレンス
- AEBuild*、AEPrint* とその仲間たち
- CocoaDevの AEBuildAppleEvent
- Mac OS X Debugging Magic (AEDebugSends およびその他の AEDebug* 環境変数用)