Mac_04_AppleScript_自动发送邮件_自动按键

由于需要在「预览」这个程序上重复执行 上千次 的

0. 从大图中 选择区域 一块小的区域

1. 按 Commond + K(图片裁切) 

2. 按 向下箭头操作

3. 继续下一张大图的 选择区域...


人工实现起来组合按键既不精准,又耗精力,

因此希望能有代码能自动连接实现 上面两个操作



有三种不同的实现思路: 

1. 使用网上现成的按键精灵Mac版

2. 使用AppleScript来实现

3. 使用XCode,新建一个Mac App来实现


第1种比较简单,下载,添加权限,然后运行就可以了

主要是后面两种实现方法, 先说AppleScriptAppleScript


2. 使用AppleScript实现, 要创建一个 AppleScript,只需要两部就可以了

2.1  第一步, 打开系统偏好设置-->安全性与隐私

为脚本编辑器添加控制权限



2.2 第二步, 打开 Applications 文件夹里的 实用工具 里面的 脚本编辑器AppleScript Editor 

如图所示: 




打开后界面如下: 



2.3  编写示例脚本代码

tell application "Finder"
	
	display dialog "Hello World"
	
end tell

运行效果如下:



AppleScript 这种脚本语言本身尽可能使用平实的英语作为语法来让代码特别容易理解和阅读。

AppleScript 的大多数命令会位于 Tell 命令块内,

它叫 “Tell 命令块” 是由于你在“告诉”应用程序你想它做些什么。

比如上面所说的三行代码告诉 Finder 这个应用程序显示一个包含 “Hello World” 字符串的对话框。

当你在 Tell 命令块内写完了你想要应用程序做的一个或多个命令后,

注意: 你必须要以 “end tell” 命令来结束这个 Tell 命令块。



当你在编辑器内完成输入上面的代码后,按下上面的 “Compile” 铁锤图标。

如果你的语法是正确的话,你所输入的代码会被自动格式化并改变颜色。


代码成功编译后,再按 “Run” 图标,应该会看到以下的对话框:
Hello Beyond


现在按下 “OK” 按纽并且看一下编辑器下方。

当你运行一脚本时,编辑器会告诉你运行的结果是什么,或者什么被“返回”了,

在我们的例子里,它告诉我们 “好的” 按纽被按下了。



声明变量

变量在每一种编程语言里面的意义都是一样的,程序代码利用变量方便的对许多信息进行读取或运算。

但在每一种语言里创建或“声明”变量是不同的,

在 AppleScript 里你会像下面这样声明变量:

set greetingStr to "Hello 面码"
tell application "Finder"
display dialog greetingStr

end tell



运行效果如下:


上面的例子中有几处地方需要注意。

首先,我们注意到变量的声明是通过 “set” 和 “to” 命令来进行。

在例子中我们 “set” 了我们的变量(“greetingStr”)为一个值(“Hello 面码”)。

在很多编程语言里程序员被要求必须声明变量的类型(如整型、浮点型、字符串等等),

但 AppleScript 足够的聪明而不需要程序员声明类型。



另外,请注意如何对变量命名的。

不能在变量名中间加空格,所以最好使用驼峰型(theString)或下划线型(the_string)变量命名方法。



最后,我们注意到把 “Hello 面码” 放进了变量中,我可以在代码里一遍又一遍的引用这个变更。

如果后面我决定要把 “Hello 面码” 改成 “Good Morning 面码”,我只需要在声明变量的那一行进行修改就可以了。



使用变量
你可以尽情的使用变量来做各种疯狂的事,但鉴于这是一篇入门文章,我只会告诉你几种方法,输入下面的代码:
注意: -- 表示是注释

代码如下:

--Integer Variables
set theFirstNumber to 3
set the theSecondNumber to 2


--Variable Operations
set theAnswer to (theFirstNumber + theSecondNumber)
set theAnswer to (theAnswer + 1)


--String Variables
set theString to "3+2+1="


--Display Dialog
tell application "Finder"


	display dialog theString & theAnswer


end tell


效果如下:



当你的脚本变得越来越复杂,你就需要好好的组织一下你的脚本了。

在一行代码前加上两个”-”号,代表这一行是注释,你可以使用注释来隔开和解释你的代码方便以后阅读。

在上面的例子里,我创建了一个字符变量和几个整数变量。

你可以对变量进行数学运算,在这里我把 “theFirstNumber” 设为5,“theSecondNumber”设为6,

然后把他们相加并赋值给 “theAnswer” 变量。



另外,你可以在变量创建后改变变量的值。

在 “theFirstNumber” 和 “theSecondNumber” 相加并把结果赋值给 “theAnswer”(结果为11)后,

我马上把 “theAnswer” 自己加1(结果为7)。

如果你运行这个脚本,你应该会看到18这个结果:





 


这只是一个很简单的范例,示范你可以对变量做的一些操作。

你现在应该明白变量的值并不是不变的,一门编程语言的强大在于你能通过对变量的操作完成各种各样的任务。



重中之重:AppleScript 字典

虽然 AppleScript 本身自带有大量可以作用于 Mac 系统中任何程序的指令,

但应用程序的作者还是有责任针对他的应用添加 AppleScript 的全面支持。

换句话说,开发者必须编写一个他的程序如何与系统里其他程序进行通讯的手册,这些手册被称之为“字典”。

要打开字典,在 AppleScript Editor 选择菜单 File->Open Dictionary (或快捷键Shift-Command-O)。

例如在打开的字典里向下浏览,找到程序 Mail 然后按 “Choose”,你应该会看到以下的窗口:










在左边的列中包含了指令和物件的 “套件Suite”。

当你选择了一个套件,你会在下面的显示窗中看到此套件所包含的所有东西。

套件(方形的S)包含了

1. “指令” (圆形的C图标)

2. “类” (方形的C图标)


而 “类” 包含了 

1. “元素”(E图标)

2. “属性”(P图标)



要理解这些东西怎么工作在一起,最好的方法就是用字典来写一个脚本范例。



为脚本创建一个算法

首先我们需要一个算法,其实算法只是 “我们需要写下脚本如何工作” 的一个高端叫法。

我们希望创建一个脚本去编写和发送邮件。

我们会使用到变量来令到将来改变邮件内容和送件人变得容易一点。

在我们写下算法的时候,我们要时刻记住 AppleScript 是如何工作的,这些步骤是我得出来的:



为收件人名字、收件人邮件地址、邮件标题以及邮件文本等创建变量
创建新邮件的变量,同时指定邮件信息的属性。
创建一个新的邮件
发送这个新邮件


创建简单的变量

我们从上文已经了解到如何创建储存文本的变量,所以我们在这一步还用不到字典。

下面是代码:



--Variables
set recipientName to "Beyond"
set recipientAddress to "[email protected]"
set theSubject to "Hello Beyond"

set theContent to "あの日見た花の名前を僕達はまだ知らない"


如你所见,我们只是随便放了一些数据到这四个变量中,

它们分别是收件人名字、收件人邮件地址、邮件标题和邮件正文文本。

这些变量里面的内容你喜欢改成什么都可以,但我建议你把你自己的邮件地址放到收件人邮件地址变量中,

这样我们测试脚本的时候就可以通过查自己的邮箱看脚本是否发送邮件成功。



使用 Mail 字典来创建邮件变量

由于我们完全不知道怎么告诉 Mail 去创建一个新的邮件信息,所以我们必须借助于 AppleScript 字典

如果你点击一下 “Standard Suite(方形的S)” 你会看到一些 AppleScript 自带的公共标准命令。

由于我们是要 “创建” 一个新的邮件信息,我们通过向下浏览来找到相关的命令,你会发现里面没有 “create” 这个命令,

但在向下滑到差不多中间的部分你会找到 “make” 这个命令。


听起来貌似不错,所以创建一个新的邮件系统,

其实是要告诉 AppleScript 我们要 “make” 一些东西。





接下来点击最左列的 “Mail” 套件

因为我们刚才已经找到了动作 “make”

所以在这里我们就可以跳过所有“指令”(圆形的C)不用看了(因为动作指令已经有了就是make),

直接翻到下面的 “类(方形的C)”(名词)中。

我们第一个看到的类是 “outgoing message”,太好了这就是我们要的,因为我们就是要发出一个新的邮件信息。

接着点击 “outgoing message” 类然后看下面显示的属性说明。



我们需要把第一步创建的几个简单变量插入到新邮件变量中。

但在下面的 “outgoing message” 属性列表中,

我们只找到发件人sender,邮件标题subject内容content的属性,而没看到收件人相关的属性。

现在我们知道引用这些属性的正确语法了。

注意,字典告诉你的是属性的定义格式。

比如 subject 这个属性,我们定义的方法是 “subject:你想打的标题字样”。







同样你会在套件中找到一个叫 “send”的指令,我们会使用这个指令来发送邮件。

现在我们还需要知道正确表达收件人名字和收件人邮箱地址的语法。

由于不在这个套件中,我们点击 “Mail Framework” 套件。

向下浏览到差不多一半的时候我们找到 “receipient” 这个类,点击这个类会看到他的属性列表,

同样我们可以通过简单的英文来引用这个类的属性,它的属性包括 “name” 和 “address”。




小技巧:你可以使用字典窗右上角的 搜索栏快速的搜索你需要的类或属性等。


现在我们已经准备好用上面学到的语法来创建我们的邮件信息了,

代码如下:

--Variables
set recipientName to "beyond"
set recipientAddress to "[email protected]"
set theSubject to "Hello Beyond"
set theContent to "あの日見た花の名前を僕達はまだ知らない"


--Mail Tell Block
tell application "Mail"


--Create the message
set theMessage to make new outgoing message with properties {subject:theSubject, content:theContent, visible:true}


end tell

效果如下:









注意我创建了一个 tell 命令块来包住所有发送给 Mail 应用程序的命令。

然后我创建了一个变量(theMessage)并让他去 “make” 一个新的 “outgoing message”而且指定上面说到的它的属性。

需要注意的是属性组需要用{}来包住,每个属性间用逗号分隔(JSON格式)。

(备注:会编程的朋友可以把 “make new outgoing message” 理解成创建一个 “outgoing message”类的实例,

然后把实例赋值给 theMessage。)



第一步:设置收件人和发送邮件

我们虽然在上面创建了邮件的变量,但还没有收件人信息

我们现在会使用另一个 tell 命令块来让这个变量设置好收件人信息并且进行发送,

代码如下:

--Variables
set recipientName to "Beyond"
set recipientAddress to "[email protected]"
set theSubject to "Hello Beyond"
set theContent to "あの日見た花の名前を僕達はまだ知らない"

--Mail Tell Block
tell application "Mail"
	
	--Create the message
	set theMessage to make new outgoing message with properties {subject:theSubject, content:theContent, visible:true}
	
	--Set a recipient
	tell theMessage
		make new to recipient with properties {name:recipientName, address:recipientAddress}
		
		--Send the Message
		send
		
	end tell
end tell



效果如下:







注意: 如果发送失败, 则需要提前设置一下 邮件帐号

发件服务器: smtp.sina.cn

收件服务器: pop.sina.cn

如图所示: 


下面这是QQ的:

常用的收件/发件服务器的地址和端口是什么?

QQ邮箱的收取邮件支持POP/IMAP两种协议,

发送邮件采用SMTP协议,

收件和发件均使用SSL协议来进行加密传输,采用SSL协议需要单独对帐户进行设置。

采用SSL协议和非SSL协议时端口号有所区别,参照下表的一些常见配置组合:

类型

服务器名称

服务器地址

非SSL协议端口号

SSL协议端口号

发件服务器

SMTP

smtp.qq.com

25

465/587

收件服务器

POP

pop.qq.com

110

995

收件服务器

IMAP

imap.qq.com

143

993






我们知道 theMessage 指向的是一个 outgoing message 类的实例,

我们在前面查 outgoing message 类的时候,

看到除了属性列表外,前面还有一个叫 Elements 的说明,

这里说明的是这个类具有这些元素,其中就包括一个叫 to recipient 的元素。

那么这里就比较好理解了,“tell theMessage make new to recipient” 这句就可以理解为:

告诉 theMessage 这个实例创建(或者叫设置)它自己的 to recipient 元素,当然用的就是后面跟的 properties 了。



最后我们执行 “send” 指令来发送我们的邮件。

注意最下面我们用了两次 end tell,因为有两个 tell 命令块需要关闭。

当你修改完一些输入的错误并编译完成后点击 “Run”,Mail 程序应该会自动创建一封邮件并且发出。

现在查查你自己的邮箱有没有收到吧~



恭喜你,你已经完成了你第一个 AppleScript 脚本了!

你可以把脚本保存成 Script ,后面可以随时回来修改和运行,

又或者保存成 Application,当成是应用程序一样打开他运行。


我展示的 AppleScript 字典和语法仅仅是个开始,

但如果你真的对 AppleScript 很感兴趣,你需要看更多的教程才可能掌握。

Apple 在官网上提供了丰富的 AppleScript 相关资料,是一个不错的开始!



说了半天,只是完全一个发送邮件的AppleScript脚本, 

接下来才是本番:

1. 目标app是  预览

2. 需要完成的按键是   Commond + K (对图片中选择的区域进行裁切)

3. 接着需要实现的按键是  向下箭头↓ (因为要对下一幅图片继续进行第2个操作)

代码如下(推荐这种写法):

activate application "Preview"

tell application "System Events"
	-- Command + K 裁切
	key code 40 using {command down}
	delay 0.1
	-- 向下键
	key code 125
end tell



或者下面的代码也是一样的效果:

tell application "Preview"
	delay 0.1
	tell application "System Events"
		-- tab + Command 切换窗口	
		key code 48 using {command down}
		delay 0.1
		-- Command + K 裁切
		key code 40 using {command down}
		delay 0.1
		-- 向下键
		key code 125
	end tell
end tell



效果如下:




附录:  apple key code list

--脚本完成组合键按下 
 


-- 这个符号是注释符号,(**)这个也是注释符号,类似于C语言里面的//和/**/
-- key code 53的意思按下Esc键,53的含义见下面的列表
-- using {} 花括号部分按下的按键和前面的按键事件一起作用
-- command down, option down的含义是按下command和option
-- 所以这个脚本的作用就是启动强制退出窗口(command+option+Esc)

(*
apple key code list(后面会用到这个清单!):

0 0x00 ANSI_A
1 0x01 ANSI_S
2 0x02 ANSI_D
3 0x03 ANSI_F
4 0x04 ANSI_H
5 0x05 ANSI_G
6 0x06 ANSI_Z
7 0x07 ANSI_X
8 0x08 ANSI_C
9 0x09 ANSI_V
10 0x0A ISO_Section
11 0x0B ANSI_B
12 0x0C ANSI_Q
13 0x0D ANSI_W
14 0x0E ANSI_E
15 0x0F ANSI_R
16 0x10 ANSI_Y
17 0x11 ANSI_T
18 0x12 ANSI_1
19 0x13 ANSI_2
20 0x14 ANSI_3
21 0x15 ANSI_4
22 0x16 ANSI_6
23 0x17 ANSI_5
24 0x18 ANSI_Equal
25 0x19 ANSI_9
26 0x1A ANSI_7
27 0x1B ANSI_Minus
28 0x1C ANSI_8
29 0x1D ANSI_0
30 0x1E ANSI_RightBracket
31 0x1F ANSI_O
32 0x20 ANSI_U
33 0x21 ANSI_LeftBracket
34 0x22 ANSI_I
35 0x23 ANSI_P
36 0x24 Return
37 0x25 ANSI_L
38 0x26 ANSI_J
39 0x27 ANSI_Quote
40 0x28 ANSI_K
41 0x29 ANSI_Semicolon
42 0x2A ANSI_Backslash
43 0x2B ANSI_Comma
44 0x2C ANSI_Slash
45 0x2D ANSI_N
46 0x2E ANSI_M
47 0x2F ANSI_Period
48 0x30 Tab
49 0x31 Space
50 0x32 ANSI_Grave
51 0x33 Delete
53 0x35 Escape
55 0x37 Command
56 0x38 Shift
57 0x39 CapsLock
58 0x3A Option
59 0x3B Control
60 0x3C RightShift
61 0x3D RightOption
62 0x3E RightControl
63 0x3F Function
64 0x40 F17
65 0x41 ANSI_KeypadDecimal
67 0x43 ANSI_KeypadMultiply
69 0x45 ANSI_KeypadPlus
71 0x47 ANSI_KeypadClear
72 0x48 VolumeUp
73 0x49 VolumeDown
74 0x4A Mute
75 0x4B ANSI_KeypadDivide
76 0x4C ANSI_KeypadEnter
78 0x4E ANSI_KeypadMinus
79 0x4F F18
80 0x50 F19
81 0x51 ANSI_KeypadEquals
82 0x52 ANSI_Keypad0
83 0x53 ANSI_Keypad1
84 0x54 ANSI_Keypad2
85 0x55 ANSI_Keypad3
86 0x56 ANSI_Keypad4
87 0x57 ANSI_Keypad5
88 0x58 ANSI_Keypad6
89 0x59 ANSI_Keypad7
90 0x5A F20
91 0x5B ANSI_Keypad8
92 0x5C ANSI_Keypad9
93 0x5D JIS_Yen
94 0x5E JIS_Underscore
95 0x5F JIS_KeypadComma
96 0x60 F5
97 0x61 F6
98 0x62 F7
99 0x63 F3
100 0x64 F8
101 0x65 F9
102 0x66 JIS_Eisu
103 0x67 F11
104 0x68 JIS_Kana
105 0x69 F13
106 0x6A F16
107 0x6B F14
109 0x6D F10
111 0x6F F12
113 0x71 F15
114 0x72 Help
115 0x73 Home
116 0x74 PageUp
117 0x75 ForwardDelete
118 0x76 F4
119 0x77 End
120 0x78 F2
121 0x79 PageDown
122 0x7A F1
123 0x7B LeftArrow
124 0x7C RightArrow
125 0x7D DownArrow
126 0x7E UpArrow
*)

另外:  Apple Script + Automator工作流程 还可以实现自动输入密码, 帐号等完成自动登录功能


附录一个Mac App的代码,实现的是一个点击指定位置的效果,先留着以后可能会用到

- (void)viewDidLoad {
    [super viewDidLoad];

    // Do any additional setup after loading the view.
    
    NSButton* button = [[NSButton alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
    button.target = self;
    button.action = @selector(buttonClick);
    [self.view addSubview:button];
    [button mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.left.mas_equalTo(100);
        make.right.bottom.mas_equalTo(-100);
    }];
}

- (void)buttonClick
{
    CGPoint pt = CGPointMake(216, 80);
    
    PostMouseEvent(kCGMouseButtonLeft, kCGEventLeftMouseDown, pt);
    PostMouseEvent(kCGMouseButtonLeft, kCGEventLeftMouseUp, pt);
    
    sleep(2);
    
    [self writeString:@"Hello" withFlags:0];
}

void PostMouseEvent(CGMouseButton button, CGEventType type, const CGPoint point)
{
    CGEventRef theEvent = CGEventCreateMouseEvent(NULL, type, point, button);
    CGEventSetType(theEvent, type);
    CGEventPost(kCGHIDEventTap, theEvent);
    CFRelease(theEvent);
}

-(void)writeString:(NSString *)valueToSet withFlags:(int)flags
{
    UniChar buffer;
    CGEventRef keyEventDown = CGEventCreateKeyboardEvent(NULL, 1, true);
    CGEventRef keyEventUp = CGEventCreateKeyboardEvent(NULL, 1, false);
    CGEventSetFlags(keyEventDown,0);
    CGEventSetFlags(keyEventUp,0);
    for (int i = 0; i < [valueToSet length]; i++) {
        [valueToSet getCharacters:&buffer range:NSMakeRange(i, 1)];
        CGEventKeyboardSetUnicodeString(keyEventDown, 1, &buffer);
        CGEventSetFlags(keyEventDown,flags);
        CGEventPost(kCGSessionEventTap, keyEventDown);
        CGEventKeyboardSetUnicodeString(keyEventUp, 1, &buffer);
        CGEventSetFlags(keyEventUp,flags);
        CGEventPost(kCGSessionEventTap, keyEventUp);
        
    }
    CFRelease(keyEventUp);
    CFRelease(keyEventDown);
}




.







未完待续,下一章节,つづく

猜你喜欢

转载自blog.csdn.net/u012576807/article/details/80589756
今日推荐