将NSEvent发送到后台应用程序

时间:2011-09-15 14:09:22

标签: objective-c macos cocoa keycode nsevent

我需要将密钥组合^⌘C发送到包含标识符com.company.app的后台应用。然后,关键组合应激活该应用程序中的菜单项。

不幸的是,我不知道如何做到这一点。一些研究使用CGEventPostToPSN()向我指出了NSEvent和CGEvent API,但我无法正常工作,因为我不知道如何设置密钥组合。 CGEventPost()似乎无法处理我创建的事件,即使所需的应用是活动应用。

以下是我最终提出的代码,但这不起作用:

CGWindowID windowNumber;
NSEvent *event = [NSEvent keyEventWithType:NSKeyUp
                                  location:NSZeroPoint
                             modifierFlags:(NSControlKeyMask | NSCommandKeyMask)
                                 timestamp:[[NSProcessInfo processInfo] systemUptime]
                              windowNumber:windowNumber
                                   context:[NSGraphicsContext currentContext]
                                characters:@"c"
               charactersIgnoringModifiers:@"c"
                                 isARepeat:NO
                                   keyCode:8];
CGEventRef eventRef = [event CGEvent];

我现在该怎么办?为什么NSEvent没有等效CGEventPost()?是否有更简单的方法来激活该菜单项而不是发布活动?我可以很容易地获得NSRunningApplication的实例,但是没有合适的API来完成我的任务。

更新 我得到了它的工作:

- (void) postFakedKeyboardEventForCopyScreenToPasteboardToPSN:(ProcessSerialNumber)psn {
    CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStatePrivate);
    CGEventRef keyDownEvent = CGEventCreateKeyboardEvent(source, (CGKeyCode)8, true);
    CGEventSetFlags(keyDownEvent, (kCGEventFlagMaskControl | kCGEventFlagMaskCommand));
    CGEventRef keyUpEvent = CGEventCreateKeyboardEvent(source, (CGKeyCode)8, false);
    CGEventSetFlags(keyUpEvent, (kCGEventFlagMaskControl | kCGEventFlagMaskCommand));
    CFRelease(source);

    CGEventPostToPSN(&psn, keyDownEvent);
    CFRelease(keyDownEvent);
    CGEventPostToPSN(&psn, keyUpEvent);
    CFRelease(keyUpEvent);
}

...

OSStatus err = noErr;
ProcessSerialNumber psn;
err = GetProcessForPID([simulator processIdentifier], &psn);
if (err == noErr)
    [self postFakedKeyboardEventForCopyScreenToPasteboardToPSN:psn];

1 个答案:

答案 0 :(得分:1)

一些注意事项:

  1. 发送keyDown事件,而不仅仅是keyUp。这样,它就更像真正的按键。

  2. 您需要使用该CGEvent调用CGEventPostToPSN,或者至少调用发布该事件的SOME。

  3. 您是否尝试过调用CGPostKeyboardEvent()?