1、服务端配置

安装即可,无需启动,在安装ansible之前需要配置epel源

[root@m01 ~]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo

[root@m01 ~]# yum makecache

[root@m01 ~]# yum install ansible -y    #安装ansible

修改配置文件,指定主机组已经主机信息

[root@m01 ~]# vim /etc/ansible/hosts        #修改配置文件/etc/ansible/hosts

[test]    #主机组名,通过组名进行分类便于管理

10.0.0.7 ansible_ssh_user=root ansible_ssh_pass=123456

10.0.0.51 ansible_ssh_user=root ansible_ssh_pass=123456

[root@Web01 ~]# vim /etc/ssh/ssh_config

StrictHostKeyChecking no    #配置服务端ssh配置文件,不询问是否连接

2、ansible模块使用

查看帮助ansable-doc -s user

2.1、测试主机组下的主机是否存活模块ping

[root@m01 ~]# ansible test -m ping

10.0.0.51 | SUCCESS => {

"changed": false,

"ping": "pong"

}

10.0.0.7 | SUCCESS => {

"changed": false,

"ping": "pong"

}

2.2、命令模块command(不支持管道和分号)

[root@m01 ~]# ansible test -m command -a "date"

10.0.0.7 | SUCCESS | rc=0 >>

Thu May 17 17:54:36 CST 2018

10.0.0.51 | SUCCESS | rc=0 >>

Thu May 17 17:56:17 CST 2018

2.3、模块shell(支持管道和分号)

[root@m01 ~]# ansible test -m shell -a 'ifconfig eth0|grep "inet addr:"'

10.0.0.7 | SUCCESS | rc=0 >>

inet addr:10.0.0.7 Bcast:10.0.0.255 Mask:255.255.255.0

10.0.0.51 | SUCCESS | rc=0 >>

inet addr:10.0.0.51 Bcast:10.0.0.255 Mask:255.255.255.0

2.4、用户管理模块user

模块参数说明:

name:指定用户名

password:设定用户密码,password参数需要接受md5加密后的值

state:用户状态,默认为present,present:表示添加用户,absent:表示删除用户

update_password:修改用户密码,always:新密码和旧密码不同时进行修改,on_create:为新创建的用户指定密码

createhome:创建家目录,yes:默认项,即创建用户默认是有家目录的,no:创建用户时不创建家目录

remove:yes:删除用户家目录,需要指定此参数

no:默认项,删除用户时默认不删除用户的家目录

system:yes:默认创建为普通用户,而非系统用户,如果不指定默认生成的选项有:

home:创建家目录

shell:创建默认的shell为/bin/bash

system:默认创建为普通用户,而非系统用户,指定是用yes

user模块中的password是需要经过md5加密的

[root@m01 ~]# echo 123456|openssl passwd -1 -stdin

$1$66TtUpmH$Fkcg13VjPwXXBPZoEpHgB/

添加用户

[root@m01 ~]# ansible test -m user -a 'name=abc password=$1$66TtUpmH$Fkcg13VjPwXXBPZoEpHgB/ createhome=no shell=/bin/sh system=yes uid=888'

10.0.0.7 | SUCCESS => {

"changed": true,

"comment": "",

"create_home": false,

"group": 499,

"home": "/home/abc",

"name": "abc",

"password": "NOT_LOGGING_PASSWORD",

"shell": "/bin/sh",

"state": "present",

"system": true,

"uid": 888

}

10.0.0.51 | SUCCESS => {

"changed": true,

"comment": "",

"create_home": false,

"group": 495,

"home": "/home/abc",

"name": "abc",

"password": "NOT_LOGGING_PASSWORD",

"shell": "/bin/sh",

"state": "present",

"system": true,

"uid": 888

}

删除用户

[root@m01 ~]# ansible test -m user -a 'name=abc state=absent'

10.0.0.7 | SUCCESS => {

"changed": true,

"force": false,

"name": "abc",

"remove": false,

"state": "absent"

}

10.0.0.51 | SUCCESS => {

"changed": true,

"force": false,

"name": "abc",

"remove": false,

"state": "absent"

}

2.5、任务计划模块cron

模块参数说明:

模块参数详解:

state:present:创建任务,absent:删除任务

backup:对远程主机上的原任务计划内容修改之前做备份

job:要执行的任务

name:该任务的描述(必须项)

user:以哪个用户的身份运行

minute:分钟(0-59,*,*/2,……),不写默认为*

hour:小时(0-23,*,*/2,……),不写默认为*

day:日(1-31,*,*/2,……),不写默认为*

month:月(1-12,*,*/2,……),不写默认为*

weekday:周(0-7,*,……),不写默认为*

创建一个定时任务,每5分钟同步一次时间

[root@m01 ~]# ansible test -m cron -a 'name="every 5 minute sync time" minute=*/5 job="/usr/sbin/ntpdate ntp2.aliyun.com"'

10.0.0.7 | SUCCESS => {

"changed": true,

"envs": [],

"jobs": [

"every 5 minute sync time"

]

}

10.0.0.51 | SUCCESS => {

"changed": true,

"envs": [],

"jobs": [

"every 5 minute sync time"

]

}

删除该定时任务

[root@m01 ~]# ansible test -m cron -a 'name="every 5 minute sync time" minute=*/5 job="/usr/sbin/ntpdate ntp2.aliyun.com" state=absent'

10.0.0.51 | SUCCESS => {

"changed": true,

"envs": [],

"jobs": []

}

10.0.0.7 | SUCCESS => {

"changed": true,

"envs": [],

"jobs": []

}

2.6、远程复制备份模块copy

模块参数说明:

src:指定源文件路径,可以是相对路径,也可以是绝对路径,可以是目录(并非是必须的,可以使用content,直接生成文件内容)

dest=:指定目标文件路径,只能是绝对路径,如果src是目录,此项必须是目录

owner:指定属主

group:指定属组

mode:指定权限,可以以数字指定比如0644

content:代替src,直接往dest文件中写内容,可以引用变量,也可以直接使用inventory中的主机变量

backup:在覆盖之前将原文件备份,备份文件包含时间信息。有两个选项:yes|no

force:yes:默认项,如果目标主机包含该文件,但内容不同,则强制覆盖

no:则只有当目标主机的目标位置不存在该文件时,才复制

directory_mode:递归的设定目录的权限,默认为系统默认权限

复制本地文件到远程主机并对原文件进行备份

[root@localhost tmp]# ansible erp -m copy -a 'src=/tmp/abc.txt dest=/tmp/ backup=yes'

192.168.10.10 | SUCCESS => {

"backup_file": "/tmp/abc.txt.2017-02-07@10:55:31~",

"changed": true,

"checksum": "13520f9e1a6f0b2ca9557d85825616c3680b4edc",

"dest": "/tmp/abc.txt",

"gid": 0,

"group": "root",

"md5sum": "baae19d280afe4e2df1799daa37bebba",

"mode": "0644",

"owner": "root",

"size": 18,

"src": "/root/.ansible/tmp/ansible-tmp-1486436129.98-98537282809491/source",

"state": "file",

"uid": 0

}

192.168.10.6 | SUCCESS => {

"backup_file": "/tmp/abc.txt.2017-02-07@10:55:31~",

"changed": true,

"checksum": "13520f9e1a6f0b2ca9557d85825616c3680b4edc",

"dest": "/tmp/abc.txt",

"gid": 0,

"group": "root",

"md5sum": "baae19d280afe4e2df1799daa37bebba",

"mode": "0644",

"owner": "root",

"size": 18,

"src": "/root/.ansible/tmp/ansible-tmp-1486436130.19-187127825454744/source",

"state": "file",

"uid": 0

}

向远程主机的文件中写内容,会把原内容覆盖掉

[root@localhost tmp]# ansible erp -m copy -a 'content="\nMy age is 26" dest=/tmp/abc.txt'

192.168.10.6 | SUCCESS => {

"changed": true,

"checksum": "e1cbbec8927a295a767fa44e91dea6eeafa5a4f4",

"dest": "/tmp/abc.txt",

"gid": 0,

"group": "root",

"md5sum": "55ec30ce5102aa8716b75ab5e98163a7",

"mode": "0644",

"owner": "root",

"size": 13,

"src": "/root/.ansible/tmp/ansible-tmp-1486436336.05-254449966786008/source",

"state": "file",

"uid": 0

}

192.168.10.10 | SUCCESS => {

"changed": true,

"checksum": "e1cbbec8927a295a767fa44e91dea6eeafa5a4f4",

"dest": "/tmp/abc.txt",

"gid": 0,

"group": "root",

"md5sum": "55ec30ce5102aa8716b75ab5e98163a7",

"mode": "0644",

"owner": "root",

"size": 13,

"src": "/root/.ansible/tmp/ansible-tmp-1486436348.0-188270058505341/source",

"state": "file",

"uid": 0

}

2.7、远程文件管理模块file

模块参数说明:

owner:修改属主

group:修改属组

mode:修改权限

path=:要修改文件的路径

recurse:递归的设置文件的属性,只对目录有效

yes:表示使用递归设置

state:

touch:创建一个新的空文件

directory:创建一个新的目录,当目录存在时不会进行修改

link:创建软连接,结果src一起使用此选项才生效

hard:创建硬连接

absent:删除文件,目录,软连接

src:当state=link时,要被连接文件的源路径

新建一个文件

[root@localhost tmp]# ansible erp -m file -a 'path=/tmp/liuwei.txt state=touch'

192.168.10.10 | SUCCESS => {

"changed": true,

"dest": "/tmp/liuwei.txt",

"gid": 0,

"group": "root",

"mode": "0644",

"owner": "root",

"size": 0,

"state": "file",

"uid": 0

}

192.168.10.6 | SUCCESS => {

"changed": true,

"dest": "/tmp/liuwei.txt",

"gid": 0,

"group": "root",

"mode": "0644",

"owner": "root",

"size": 0,

"state": "file",

"uid": 0

}

新建一个目录

[root@localhost tmp]# ansible erp -m file -a 'path=/tmp/liuwei state=directory'

192.168.10.10 | SUCCESS => {

"changed": true,

"gid": 0,

"group": "root",

"mode": "0755",

"owner": "root",

"path": "/tmp/liuwei",

"size": 4096,

"state": "directory",

"uid": 0

}

192.168.10.6 | SUCCESS => {

"changed": true,

"gid": 0,

"group": "root",

"mode": "0755",

"owner": "root",

"path": "/tmp/liuwei",

"size": 4096,

"state": "directory",

"uid": 0

}

删除文件或者目录

[root@localhost tmp]# ansible erp -m file -a 'path=/tmp/liuwei.txt state=absent'

192.168.10.10 | SUCCESS => {

"changed": true,

"path": "/tmp/liuwei.txt",

"state": "absent"

}

192.168.10.6 | SUCCESS => {

"changed": true,

"path": "/tmp/liuwei.txt",

"state": "absent"

}

递归设置文件的属主或者属组

[root@localhost tmp]# ansible erp -m file -a 'path=/tmp/liuwei owner=root group=root recurse=yes'

192.168.10.10 | SUCCESS => {

"changed": true,

"gid": 0,

"group": "root",

"mode": "0755",

"owner": "root",

"path": "/tmp/liuwei",

"size": 4096,

"state": "directory",

"uid": 0

}

192.168.10.6 | SUCCESS => {

"changed": true,

"gid": 0,

"group": "root",

"mode": "0755",

"owner": "root",

"path": "/tmp/liuwei",

"size": 4096,

"state": "directory",

"uid": 0

}

为文件设置软连接

[root@localhost tmp]# ansible erp -m file -a 'src=/tmp/liuwei state=link path=/tmp/liuzhengwei'

192.168.10.6 | SUCCESS => {

"changed": true,

"dest": "/tmp/liuzhengwei",

"gid": 0,

"group": "root",

"mode": "0777",

"owner": "root",

"size": 11,

"src": "/tmp/liuwei",

"state": "link",

"uid": 0

}

192.168.10.10 | SUCCESS => {

"changed": true,

"dest": "/tmp/liuzhengwei",

"gid": 0,

"group": "root",

"mode": "0777",

"owner": "root",

"size": 11,

"src": "/tmp/liuwei",

"state": "link",

"uid": 0

}

2.8、远程主机执行本地脚本模块script

[root@localhost tmp]# ansible erp -m script -a '/tmp/a.sh'

192.168.10.10 | SUCCESS => {

"changed": true,

"rc": 0,

"stderr": "",

"stdout": "Tue Feb 7 11:26:41 CST 2017\r\n",

"stdout_lines": [

"Tue Feb 7 11:26:41 CST 2017"

]

}

192.168.10.6 | SUCCESS => {

"changed": true,

"rc": 0,

"stderr": "",

"stdout": "Tue Feb 7 11:26:52 CST 2017\r\n",

"stdout_lines": [

"Tue Feb 7 11:26:52 CST 2017"

]

}

2.9、收集远程主机信息模块setup

收集可用的facts,收集每个节点的相关信息:架构信息,IP,时间,域名,网卡,MAC,主机名,CPU等信息。

这些收集的信息,可以作为变量。

[root@localhost tmp]# ansible erp -m setup

2.10、安装模块yum

模块参数说明:

name:表示要安装软件包的名字,默认最新的程序包,指明要安装的程序包,可以带上版本号

state:表示是安装还卸载

present:默认的,表示为安装

lastest:安装为最新的版本

absent:表示删除

2.11服务模块service

模块参数说明:

enabled:表示设置服务开机是否启动,取值为true或者false;enabled=yes

name=:表示要控制哪一个服务

state:

started:表示现在就启动此服务

stopped:表示现在关闭此服务

restarted:表示重启此服务

sleep:如果执行了restarted,在stop和start之间沉睡几秒

runlevel:定义在哪些级别可以自启动

arguments:表示向命令行传递的参数

[root@localhost tmp]#ansible erp -m service -a 'enabled=on name=httpd state=started'

2.12、文件编辑模块lineinfile

模块参数说明:

path:指定要修改的配置文件

regexp:匹配要修改的内容

line:要增加或者修改的内容

state:

absent:表示删除,当匹配到时进行删除

present:表示增加,当匹配到时进行修改,当没有匹配到时在最后增加一行,默认为此项

backrefs:

no:表示如果没有匹配到,则增加line;如果匹配成功,则替换line;

yes:表示如果没有匹配到,则不变line;如果匹配成功,则替换line;

backup:

no:表示如果没有匹配到,则增加line;如果匹配成功,则替换line;不备份原文件

yes:表示如果没有匹配到,则增加line;如果匹配成功,则替换line;备份原文件

insertafter(匹配的是此行):

在匹配到的行之后添加一行

insertbefore(匹配的是此行):

在匹配到的行之前添加一行

3、ansible剧本YAML

playbook是由一个或多个"play"组成的列表。play的主要功能在于将事先归并为一组的主机装扮成事先通过ansible中的task定义好的角色。从根本上来讲,所有task无非是调用ansible的一个module。将多个play组织在一个playbook中,即可以让他们连同起来按事先编排的机制同唱一台大戏。

剧本1:

[root@m01 scripts]# vim first.yml

- hosts: test    #指定主机组名

tasks:    #任务

- name: test host ping    #操作名称

ping:    #ansible模块名称

[root@m01 scripts]# ansible-playbook first.yml     #执行

PLAY [test] *************************************************************************************************

TASK [Gathering Facts] **************************************************************************************

ok: [10.0.0.7]

ok: [10.0.0.51]

TASK [test host ping] ***************************************************************************************

ok: [10.0.0.7]

ok: [10.0.0.51]

PLAY RECAP **************************************************************************************************

10.0.0.51 : ok=2 changed=0 unreachable=0 failed=0

10.0.0.7 : ok=2 changed=0 unreachable=0 failed=0

剧本2:

[root@m01 scripts]# vim second.yml

- hosts: test

tasks:

- name: test host ping

ping:

- name: check hostname

command: hostname

[root@m01 scripts]# ansible-playbook second.yml

PLAY [test] *************************************************************************************************

TASK [Gathering Facts] **************************************************************************************

ok: [10.0.0.7]

ok: [10.0.0.51]

TASK [test host ping] ***************************************************************************************

ok: [10.0.0.7]

ok: [10.0.0.51]

TASK [check hostname] ***************************************************************************************

changed: [10.0.0.7]

changed: [10.0.0.51]

PLAY RECAP **************************************************************************************************

10.0.0.51 : ok=3 changed=1 unreachable=0 failed=0

10.0.0.7 : ok=3 changed=1 unreachable=0 failed=0

剧本3:

[root@m01 scripts]# vim third.yml

- hosts: test

tasks:

- name: test host ping

ping:

- name: check hostname

command: hostname

- name: sleep 10

shell: sleep 10

[root@m01 scripts]# ansible-playbook third.yml

PLAY [test] *************************************************************************************************

TASK [Gathering Facts] **************************************************************************************

ok: [10.0.0.51]

ok: [10.0.0.7]

TASK [test host ping] ***************************************************************************************

ok: [10.0.0.51]

ok: [10.0.0.7]

TASK [check hostname] ***************************************************************************************

changed: [10.0.0.51]

changed: [10.0.0.7]

TASK [sleep 10] *********************************************************************************************

changed: [10.0.0.7]

changed: [10.0.0.51]

PLAY RECAP **************************************************************************************************

10.0.0.51 : ok=4 changed=2 unreachable=0 failed=0

10.0.0.7 : ok=4 changed=2 unreachable=0 failed=0

剧本4:

[root@m01 scripts]# cat forth.yml

- hosts: test

tasks:

- name: ping baidu.com

shell: ping www.baidu.com -c4

- name: install httpd

yum: name=httpd state=present

- name: start httpd

service: name=httpd enabled=no state=restarted sleep=3

[root@m01 scripts]# ansible-playbook forth.yml

PLAY [test] *************************************************************************************************

TASK [Gathering Facts] **************************************************************************************

ok: [10.0.0.7]

ok: [10.0.0.51]

TASK [ping baidu.com] ***************************************************************************************

changed: [10.0.0.51]

changed: [10.0.0.7]

TASK [install httpd] ****************************************************************************************

ok: [10.0.0.51]

ok: [10.0.0.7]

TASK [start httpd] ******************************************************************************************

changed: [10.0.0.7]

changed: [10.0.0.51]

PLAY RECAP **************************************************************************************************

10.0.0.51 : ok=4 changed=2 unreachable=0 failed=0

10.0.0.7 : ok=4 changed=2 unreachable=0 failed=0

剧本5:

利用ansible配置rsync服务端backup和客户端web01,在本地ansible服务器的配置文件中加入相应主机组,并在本地创建/srv/rsyncd.conf

[root@m01 srv]# vim /etc/ansible/hosts

[rsync_client]

10.0.0.7 ansible_ssh_user=root ansible_ssh_pass=123456

[backup]

10.0.0.41 ansible_ssh_user=root ansible_ssh_pass=123456

[root@m01 srv]# pwd

/srv

[root@m01 srv]# vim rsyncd.conf

#rsync server

##rsyncd.conf start##

uid = rsync

gid = rsync

use chroot = no

max connections = 2000

timeout = 600

pid file = /var/run/rsyncd.pid

lock file = /var/run/rsync.lock

log file = /var/log/rsyncd.log

ignore errors

read only = false

list = false

hosts allow = 192.168.1.0/24

auth users = rsync_backup

secrets file = /etc/rsync.password

#####################################

[backup]

comment = back server by har

path = /backup

[root@m01 scripts]# vim backup.yml

- hosts: backup

tasks:

- name: server

shell: useradd -M -s /sbin/nologin rsync;mkdir /backup;chown -R rsync:rsync /backup

- name: copy rsyncd.conf

copy: src=/srv/rsyncd.conf dest=/etc/rsyncd.conf force=yes

- name: password file and start rsync daemon

shell: echo "rsync_backup:rsync" >/etc/rsync.password;chmod 600 /etc/rsync.password;rsync --daemon; netstat -lntup|grep 873

- hosts: rsync_client

tasks:

- name: client

shell: echo "rsync">/etc/rsync.password;chmod 600 /etc/rsync.password

- name: rsync dir

shell: rsync -avz /etc/sysconfig rsync_backup@192.168.1.41::backup --password-file=/etc/rsync.password

[root@m01 scripts]# ansible-playbook -v backup.yml        #执行

部分参考来源:http://blog.51cto.com/liuzhengwei521/1895480

ansible自动化工具使用的更多相关文章

  1. ansible自动化工具安装和简单使用

    ansible自动化工具安装和简单使用 1.安装 ansible依赖于Python 2.6或更高的版本.paramiko.PyYAML及Jinja2. 2.1 编译安装 解决依赖关系 # yum -y ...

  2. centos下安装ansible自动化工具(超详细,包含基本使用)

    ansible官网:https://www.ansible.com 众所周知,ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet.cfengine.chef ...

  3. centos7+ansible自动化工具使用

    一.基础介绍 ========================================================================================== 1. ...

  4. Ansible 自动化工具入门

    Ansible 配置 Ansible 简单管理 下面的小实验,我们将采用以下的IP地址规划,请自行配置好. [实验环境] [状态] [主机列表] [python版本] 控制机 192.168.1.10 ...

  5. 在 CentOS 7 中安装并使用自动化工具 Ansible

    Ansible是一款为类Unix系统开发的自由开源的配置和自动化工具.它用Python写成,类似于Chef和Puppet,但是有一个不同和优点是我们不需要在节点中安装任何客户端.它使用SSH来和节点进 ...

  6. Ansible自动化运维工具-上

    [Ansible特点] 1)Ansible与saltstack均是基于Python语言开发的 2)安装使用简单,基于不同插件和模块实现各种软件,平台,版本的管理以及支持虚拟容器多层级的部署 3)不需要 ...

  7. Ansible运维自动化工具19个常用模块使用实例【转】

    一.模块列表 1.setup 2.ping 3.file 4.copy 5.command 6.shell 7.script 8.cron 9.yum 10.service 11.group 12.u ...

  8. 运维自动化工具ansible

    企业级自动化运维工具应用实战ansible 公司计划在年底做一次大型市场促销活动,全面冲刺下交易额,为明年的上市做准备.公司要求各业务组对年底大促做准备,运维部要求所有业务容量进行三倍的扩容,并搭建出 ...

  9. Ansible 自动化运维工具

    Ansible 自动化运维工具 Ansible是什么? Ansible是一个"配置管理工具"也是一个"自动化运维工具" Ansible 作用: Ansible是 ...

随机推荐

  1. oracle怎么查看一个表或一个索引占用多少空间

    很多时候我们想知道一个表或一个索引占用多少M的空间,以下脚本就是满足这个要求的,记住替换其中的内容. SELECT owner, segment_name, SUM(bytes)/1024/1024 ...

  2. testng自定义注解

    在testng中大部分的注解已经可以满足我们测试的需求,但是在测试的时候想要通过注解的方式加入自己测试一些内容,比如 测试项目 测试描述  验证点等信息,可通过自定义注解的方式实现. 具体操作步骤如下 ...

  3. jquery 的ajax

    一,$.get(url,[data],[callback]) 说明:url为请求地址,data为请求数据的列表(是可选的,也可以将要传的参数写在url里面),callback为请求成功后的回调函数,该 ...

  4. 行为型设计模式之职责链模式(Chain of Responsibility)

    结构 意图 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止. 适用性 有多个的对象可以处理一个请求,哪个 ...

  5. 函数atof,atoi,atol,strtod,strtol,strtoul 描述

    函数atof,atoi,atol,strtod,strtol,strtoul atof(将字串转换成浮点型数) 相关函数 atoi,atol,strtod,strtol,strtoul表头文件 #in ...

  6. python的加密操作

    hashlib加密 import hashlib # 有很多种加密方式,md5,sha1等等 h = hashlib.md5() # 提交加密的内容,bytes形式 h.update(b"s ...

  7. 【转载】无需图片,使用CSS3实现圆角按钮

    原文地址:http://www.open-open.com/home/space-37924-do-blog-id-5789.html 首先来看看效果: 事例HTML代码: <a href=&q ...

  8. AC日记——算术天才⑨与等差数列 bzoj 4373

    4373 思路: 判断一个数列是否是等差数列: 1,最大值减去最小值==(区间个数-1)*k: 2,gcd==k: 3,不能有重复(不会这判断这一条,但是数据水就过了): 来,上代码: #includ ...

  9. J.U.C并发框架源码阅读(八)ArrayBlockingQueue

    基于版本jdk1.7.0_80 java.util.concurrent.ArrayBlockingQueue 代码如下 /* * ORACLE PROPRIETARY/CONFIDENTIAL. U ...

  10. MFC学习1

    引用:http://v.youku.com/v_show/id_XMjM3MTI1ODky.html MSG 窗口——一般是程序在屏幕上的不同的矩形区域。 窗口句柄——标识窗口类型的类(资源的标识) ...