以编程方式在任何应用程序中输入文本 [英] Programmatically enter text into any application

查看:109
本文介绍了以编程方式在任何应用程序中输入文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否存在概念验证的Objective-C可执行文件,该可执行文件使用Apple事件而不是AppleScript输入一些文本到应用程序中,然后单击鼠标?

Is there a proof-of-concept Objective-C executable that enters some text into an application and then clicks the mouse, using Apple events and not AppleScript?

例如相当于

tell application "System Events"
 tell process "Safari"
  keystroke "Hello World"
  click
 end tell 
end tell

它应可在Mac OS X 10.9上运行,最好是面向未来的(向后兼容性无关紧要).上下文是我将从另一种语言调用Objective-C代码.

It should work on Mac OS X 10.9, preferably be future oriented (backwards compatibility doesn't matter). The context is that I will be calling the Objective-C code from another language.

我之所以这样说是因为我读到了:

I'm saying this because I read that:

从Mac OS X 10.7开始,低级可可API(NSAppleEventDescriptor) 仍然缺乏必要的功能(例如发送Apple的功能 事件),而高级Cocoa API(脚本桥)则存在缺陷, 只能作为应用程序样式包装程序的可行基础.

As of Mac OS X 10.7, the low-level Cocoa API (NSAppleEventDescriptor) still lacks essential functionality (e.g. the ability to send Apple events), while the high-level Cocoa API (Scripting Bridge) is too flawed and limited to be a viable foundation for an appscript-style wrapper.

和:

NSAppleScript只能在主线程上安全使用

NSAppleScript can safely be used only on the main thread

所以,我的目标是:

  1. 任何应用程序(按名称或当前名称)
  2. 任何键盘输入或鼠标
  3. 来自C或Objective-C
  4. 几百毫秒之内

谢谢!

推荐答案

而不是使用AppleEvents,而是CoreGraphics框架中的CGEvent API<

Rather than using AppleEvents, the CGEvent API in CoreGraphics framework <https://developer.apple.com/library/mac/documentation/Carbon/Reference/QuartzEventServicesRef/Reference/reference.html> lets you post low-level mouse and keyboard events to the window server.

#include <CoreGraphics/CoreGraphics.h>

NSArray *launchedApplications = [[NSWorkspace sharedWorkspace] launchedApplications]; // depreciated but I couldn't find a modern way to get the Carbon PSN
NSPredicate *filter = [NSPredicate predicateWithFormat:@"NSApplicationName = \"TextEdit\""];
NSDictionary *appInfo = [[launchedApplications filteredArrayUsingPredicate:filter] firstObject];
ProcessSerialNumber psn;
psn.highLongOfPSN = [[appInfo objectForKey:@"NSApplicationProcessSerialNumberHigh"] unsignedIntValue];
psn.lowLongOfPSN = [[appInfo objectForKey:@"NSApplicationProcessSerialNumberLow"] unsignedIntValue];

CGEventRef event1 = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)6, true); // 'z' key down
CGEventRef event2 = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)6, false); // 'z' key up

CGEventPostToPSN(&psn, event1);
CGEventPostToPSN(&psn, event2);

您也可以考虑编写服务< https ://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/SysServices/introduction.html >,通过该菜单,您可以通过应用程序菜单中的服务"菜单为其他应用程序提供功能.请注意,您甚至可以将键盘快捷键分配给服务"菜单项.服务通过系统粘贴板工作;如果您只需要能够将某些罐头或生成的数据粘贴到另一个应用程序中,则此方法可能比处理原始窗口服务器事件更容易.

You might also consider writing a Service <https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/SysServices/introduction.html>, which lets you provide functionality to other applications through the Service menu in the application menu. Note that you can even assign keyboard shortcuts to Service menu items. Services work via the system pasteboard; this approach may be easier than dealing with raw window server events if you simply need to be able to paste some canned or generated data into another application.

这篇关于以编程方式在任何应用程序中输入文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆