Прямой доступ к монтажному картону выглядит бесполезным. Во-первых, launchd не зарегистрирует процессы 1 с помощью порта Маха сервера монтажа. Сначала вам нужно найти способ получить порт Маха сервера монтажа (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'
Ссылки
- «Настройка пользовательских сеансов»
- "Общение между сеансами входа в систему"
- Интерфейс ядра Маха , особенно:
- Справочник CFMessagePort (упаковщик порта Маха):
- Руководство по программированию событий Apple
- Справочник по Apple Event Manager
- AEBuild *, AEPrint * и Friends
- AEBuildAppleEvent на CocoaDev
- Магия отладки Mac OS X (для AEDebugSends и других переменных среды AEDebug *)