Expect 自动交互式程序

1. Expect 自动交互式程序介绍及安装

1.1 Expect 介绍

Expect 是一个用来实现自动化交互功能的软件套件。

1.2 为什么使用 Expect

在现今的企业运维中,自动化运维已经成为运维的主流趋势,但是在很多情况下,执行系统命令或程序时,系统会以交互式的形式要求运维人员输入指定的字符串,之后才能继续执行命令。例如:

① 为用户设置密码时,一般情况下就需要手工输入两次密码

② 使用 SSH 远程连接服务时,第一次连接要和系统实现两次交互式输入:

简单地说,Expect 就是用来自动实现与交互式程序通信的,而无需管理员手工干预。比如 SSH 、FTP 远程连接等,正常情况下都需要手工与它们进行交互,而使用 Expect 就可以模拟手工交互的过程,实现自动与远端程序的交互,从而达到自动化运维的目的。

1.3 Expect 的自动交互工作流程简单说明

spawn 启动指定进程 --->expect 获取期待的关键字 ---> send 向指定进程发送指定字符 ---> 执行完退出

1.4 安装 Expect 软件

在管理机上,确保机器可以正常上网,并设置好 yum 安装源,然后执行 yum install expect -y 安装。

        安装过程如下:

[[email protected] ~]# rpm -qa expect      #  检查是否安装。(没有输出说明未安装)

[[email protected] ~]# yum install expect -y    # 执行安装命令。

[[email protected] ~]# rpm -qa expect   #  再次检查是否安装(安装成功会输出版本号)。

expect-5.44.1.15-5.el6_4.x86_64

[[email protected] ~]# which expect   #  查看命令路径。

/usr/bin/expect

2.Expect 自动化交互式程序应用实践

2.1 小试牛刀:通过 Expect 自动交互功能查看远程服务器负载

准备两台服务器,IP 和主机名列表为:


IP 地址


主机名


192.168.136.142


nfs-server


192.168.136.141


lamp01

远程连接查看负载

[[email protected] ~]# ssh -p22 [email protected] uptime

[email protected]‘s password:  #  此处提示需要手工输入密码。

22:28:32 up  1:51,  1 user,  load average: 0.00, 0.00, 0.00

利用 expect 的功能实现自动交互的脚本

[[email protected] ~]# cat ex.exp

#!/usr/bin/expect    #  脚本开头解释器。

spawn ssh [email protected] uptime

expect "*password"

send "111111\n"

expect eof    #  处理完毕后结束 expect 。

[[email protected] ~]# expect ex.exp

spawn ssh [email protected] uptime

[email protected]‘s password:

22:34:38 up  1:57,  1 user,  load average: 0.00, 0.00, 0.00

提示:此时不需输入密码就自动连接到远端机器执行 ssh 命令了。

2.2 Expect 程序自动交互的重要命令及示例

2.2.1 spawn 命令

在 Expect 自动交互程序执行的过程中,spawn 命令是一开始就需要使用的命令,通过 spawn 执行一个命令或程序,之后所有的 Expect 操作都会在这个执行过的命令或程序进程中进行,包括自动交互功能,因此如果没有 spawn 命令,Expect 程序将无法实现自动交互。

        语法:spawn 【选项】  【需要自动交互的命令或程序】

        例如:spawn ssh [email protected] uptime    # (Expect 脚本中命令)

在 spawn 命令的后面,直接加上执行的命令或程序(例如 ssh 命令)等,除此之外,spawn 还支持如下选项:(不常用,了解)

-open  表示启动文件进程。

-ignore 表示忽略某些信号。

        提示:使用 spawn 命令是程序实现自动化交互工作流程中的第一步,也是最关键的一步。

2.2.2 expect 命令

在 Expect 自动交互程序执行的过程中,当使用 spawn 命令执行一个命令或程序之后,会显示出某些交互式信息,expect 命令的作用就是获取 spawn 命令执行后的信息,看看是否和其事先制定的相匹配,一旦匹配上指定的内容就执行 expect 后面的动作,expect 命令也有一些选项,用的最多的一个就是:-re 表示使用正则表达式 的方式来匹配。

     语法:expect 【表达式】  【动作】

        例如:spawn ssh [email protected] uptime

expect "*password" {send "123456\r"}   # (Expect 脚本中命令) 。

范例 1:执行 ssh 命令远程获取服务器负载值,并要求实现自动输入密码。

方法一:将 expect 和send 放在同一行:

[[email protected] ~]# cat ex01.exp

#!/usr/bin/expect    #  脚本开头解释器。

spawn ssh [email protected] uptime

expect "*password"   {send "111111\n"}

expect eof    #  处理完毕后结束 expect 。

方法二:将 expect 和send 放在不同行:

[[email protected] ~]# cat ex02.exp

#!/usr/bin/expect    #  脚本开头解释器。

spawn ssh [email protected] uptime

expect "*password"

send "111111\n"

expect eof    #  处理完毕后结束 expect 。

上面两种方法的执行结果是一样的:

[[email protected] ~]# expect ex.exp

spawn ssh [email protected] uptime

[email protected]‘s password:

22:34:38 up  1:57,  1 user,  load average: 0.00, 0.00, 0.00

提示:expect 命令还可以在一个 expect 匹配中多次匹配不同的字符串,并给出不同的处理动作。只需要将匹配的所有字符串放在一个 { } 即可(需要借助 exp_continue 实现继续匹配)。

范例二:执行 ssh 命令远程获取服务器负载值,并要求实现自动输入 yes 及用户密码。

实现的脚本:

[[email protected] ~]# cat ex03.exp

#!/usr/bin/expect

spawn ssh [email protected] uptime

expect  {   #  大括号前要有空格。

"yes/no"     {exp_send "yes\r";exp_continue}

"*password"  {exp_send "111111\r"}

}

expect eof   #  处理完毕后结束 expect 。

执行结果:

① 首先清除密钥文件使其出现 yes/no 提示信息:

[[email protected] ~]# ll ~/.ssh/known_hosts

-rw-r--r-- 1 root root 1191 Dec 11 01:58 /root/.ssh/known_hosts

[[email protected] ~]# rm -f ~/.ssh/known_hosts

② 执行脚本:

[[email protected] ~]# expect ex03.exp

spawn ssh [email protected] uptime

The authenticity of host ‘192.168.136.141 (192.168.136.141)‘ can‘t be established.

RSA key fingerprint is 8a:f2:af:0c:86:03:5c:35:25:75:5d:75:1d:9f:3c:8b.

Are you sure you want to continue connecting (yes/no)? yes    #  expect 自动输入 yes 。

Warning: Permanently added ‘192.168.136.141‘ (RSA) to the list of known hosts.

[email protected]‘s password:     #  expect 自动输入密码。

23:06:05 up  2:29,  1 user,  load average: 0.00, 0.00, 0.00

范例三:利用 expect 响应 Shell 脚本中的多个 read 读入:

① 准备数据:利用 read 提示用户输入,创造交互式输入。

[[email protected] ~]# cat expread.sh

#!/bin/sh

read -p ‘please input your username:‘ name

read -p ‘please input your password:‘ pass

read -p ‘please input your email:‘ mail

echo -n "your name is $name,"

echo -n "your password is $pass,"

echo -n "your email is $mail."

② 执行结果:(下面的提示输入只能手动输入)

[[email protected] ~]# sh  expread.sh

please input your username:alinuxer

please input your password:111111

please input your email:[email protected]

your name is alinuxer,your password is 111111,your email is [email protected]

问题:开发 expect 自动化脚本,根据需求自动输入多个字符串:

[[email protected] ~]# cat ex04.exp

#!/usr/bin/expect

spawn /bin/sh expread.sh

expect {

"username" {exp_send "alinuxer\r";exp_continue}

"*pass" {exp_send "123456\r";exp_continue}

"*mail" {exp_send "[email protected]\r"}

}

expect eof    #  处理完毕后结束 expect 。

执行结果如下:  (回车后无需任何人工交互,直接输出结果)       

[[email protected] ~]# expect ex04.exp

spawn /bin/sh expread.sh

please input your username:alinuxer

please input your password:123456

please input your email:[email protected]

your name is alinuxer,your password is 123456,your email is [email protected]

2.2.3 send 命令

在上面的案例中用到的 exp_send 和 send 命令是 Expect 中的动作命令,用法类似,即在 expect 命令匹配指定的字符串后,发送的指定的字符串给系统,这两个命令支持一些特殊转义符号如\r(回车)、\n (换行)、\t (制表符)等

参数:

- i   指定 spawn_id ,用来向不同的 spawn_id 进程发送命令,是进行多程序控制的参数。

- s  s 代表 slowly ,即控制发送的速度使用的时候要与 expect 中的变量 send_slow 相关联。

2.2.4 exp_continue 命令

一般处于 expect 命令中,属于一种动作命令,一般使用在匹配多次字符串的动作中,即让 Expect 程序继续匹配的意思。

提示:如果需要一次匹配多个字符串,那么不同的匹配之间就要加上 exp_continue ,否则 expect 将不会自动输入指定的字符串。最后一个结尾就不需要加 exp_continue 了,因为已经匹配完成了。

2.2.5 send_user 命令

该命令可以用来打印 Expect 脚本信息,类似 Shell 里的 echo (-e 参数)命令,而默认的 send、exp_send 命令都是将字符串输出到 Expect 程序中去。

示例如下:

[[email protected] ~]# vi ex05.exp

#!/usr/bin/expect

send_user "I am alinuxer.\n"

send_user "I like playing basketball.\n"

send_user "My girlfriend is KeXin.\n"

执行结果如下:

[[email protected] ~]# expect ex05.exp

I am alinuxer.

I like playing basketball.

My girlfriend is KeXin.

2.2.6 exit 命令

该命令的功能类似于 Shell 中的 exit ,即直接退出 Expect 脚本,除了最基本的退出脚本功能外,还可以利用该命令对脚本做一些关闭前的清理和提示等工作。

示例如下:

[[email protected] ~]# cat ex06.exp

#!/usr/bin/expect

send_user "I am alinuxer.\n"

send_user "I like playing basketball.\n"

send_user "My girlfriend is KeXin.\n"

exit -onexit {send_user "I am so cool!\n"

}

执行结果如下:

[[email protected] ~]# expect ex06.exp

I am alinuxer.

I like playing basketball.

My girlfriend is KeXin.

I am so cool!

Expect 常用命令总结:见<< 老男孩 Shell 编程实战 P325 >> 【略】

3. Expect 程序普通变量

定义变量的基本语法: set  变量名   变量值

打印变量的基本语法: puts $变量名

3.1 定义变量及输出变量示例

[[email protected] ~]# cat ex07.exp

#!/usr/bin/expect

set password "123456"

puts $password

send_user "$password\n"    #  send_user 也可以打印输出变量。

执行结果如下:

[[email protected] ~]# expect ex07.exp

123456

123456

3.2 Expect 程序特殊参数变量

在 Expect 里也有与 Shell 脚本里的$0、$1、$# 等类似的特殊参数变量,用于接收及控制 Expect 脚本参数。

在 Expect 中 $argv 表示参数数组,可以使用 [lindex $argv n] 接收 Expect 脚本传参,n 从零开始,分别表示第一个参数([lindex $argv 0]),第二个参数([lindex $argv 1]),第三个参数([lindex $argv 2])......

范例 1:定义及输出特殊参数变量:

[[email protected] ~]# cat ex08.exp

#!/usr/bin/expect

#define var

set file [lindex $argv 0]    #  定义特殊参数变量。

set host [lindex $argv 1]    #  定义特殊参数变量。

set dir [lindex $argv 2]    #  定义特殊参数变量。

send_user "$file\t$host\t$dir\n"       #  打印特殊参数变量。

puts "$file\t$host\t$dir\n"    #  打印特殊参数变量。

执行结果如下:(命令行传参)

[[email protected] ~]# expect ex08.exp a.log 192.168.136.142 /tmp

a.log   192.168.136.142 /tmp

a.log   192.168.136.142 /tmp

提示:注意 Expect 接受参数的方式和 bash 脚本的方式的区别。除了基本的位置参数外,Expect 也支持其他的特殊参数,例如:$argc 表示传参的个数,$argv0 表示脚本的名字。

范例 2:针对 Expect 脚本传参的个数及脚本名参数的实践:

脚本如下:

[[email protected] ~]# cat ex09.exp

#!/usr/bin/expect

#define var

set file [lindex $argv 0]

set host [lindex $argv 1]

set dir [lindex $argv 2]

send_user "$file\t$host\t$dir\n"

puts "$file\t$host\t$dir\n"

puts $argc

puts $argv0

执行的结果:

[[email protected] ~]# expect ex09.exp b.log 192.168.136.141 /opt

b.log   192.168.136.141 /opt

b.log   192.168.136.141 /opt

3                #  打印参数个数($argc)。

ex09.exp   #  输出脚本名字($argv0)。

3.3 Expect 程序中的 if 条件句

范例 1 :使用 if 语句判断脚本传参的个数,如果不符合则给予提示:

脚本如下:

[[email protected] ~]# cat ex10.exp

#!/usr/bin/expect

if { $argc != 3 } {

send_user "Usage:expect $argv0 file host dir\n"

exit

}

#define var

set file [lindex $argv 0]

set host [lindex $argv 1]

set dir [lindex $argv 2]

puts "$file\t$host\t$dir"

执行的结果:

[[email protected] ~]# expect ex10.exp c.log 192.168.136.141 /home

c.log   192.168.136.141 /home

范例 2 :使用 if 语句判断脚本传参的个数,无论是否符合都给予提示:

脚本如下:

[[email protected] ~]# cat ex11.exp

#!/usr/bin/expect

if { $argc != 26 } {

puts "bad"

} else {

puts "good"

}

执行结果如下:

[[email protected] ~]# expect ex11.exp {a..z}

good

[[email protected] ~]# expect ex11.exp {a..y}

bad

3.4 Expect 中的关键字

Expect 中的特殊关键字用于匹配过程,代表某些特殊的含义或状态,一般只用于 Expect 命令中而不能在 Expect 命令外面单独使用。

① eof   end-of-file  用于匹配结束符。

②  timeout  控制时间的一个关键字变量。可通过为该变量赋值来规定整个 Expect 操作的时间。

4. 企业生产场景下的 Expect 案例

4.0 环境准备:准备三台服务器,IP 和主机名见下表


IP 地址


主机名


角色


192.168.136.142


nfs-server


管理机


192.168.136.141


lamp01


被管理机 1


192.168.136.143


lnmp02


被管理机 2

4.1 开发 Expect 脚本实现自动交互式批量执行命令

1)实现 Expect 自动交互的脚本:

[[email protected]s-server ~]# cat zidongjiaohu.exp

#!/usr/bin/expect

if { $argc != 2 } {

puts "Usage:expect $argv0 ip command"

exit

}

#define var

set ip  [lindex $argv 0]

set cmd [lindex $argv 1]

set password "111111"

#

spawn ssh [email protected]$ip $cmd

expect {

"yes/no"     {send "yes\r";exp_continue}

"*password"  {send "$password\r"}

}

expect eof

执行结果如下:

[[email protected] ~]# expect zidongjiaohu.exp 192.168.136.143 uptime

spawn ssh [email protected] uptime

[email protected]‘s password:

23:57:06 up  3:43,  1 user,  load average: 0.00, 0.00, 0.00

[[email protected] ~]# expect zidongjiaohu.exp 192.168.136.141 "free  -m"

spawn ssh [email protected] free  -m

[email protected]‘s password:

total       used       free     shared    buffers     cached

Mem:           980        177        802          0         26         45

-/+ buffers/cache:        105        874

Swap:         1023          0       1023

2)利用 Shell 循环执行 Expect 脚本命令:

[[email protected] ~]# cat sh_piliang_exp.sh

#!/bin/sh

if [ $# != 1 ]

then

echo $"Usage:$0 cmd"

exit 1

fi

cmd=$1

for n in 130 141 143

do

expect zidongjiaohu.exp 192.168.136.$n  "$cmd"

done

执行结果如下:

[[email protected] ~]# sh sh_piliang_exp.sh uptime

spawn ssh [email protected] uptime

The authenticity of host ‘192.168.136.130 (192.168.136.130)‘ can‘t be established.

RSA key fingerprint is 8a:f2:af:0c:86:03:5c:35:25:75:5d:75:1d:9f:3c:8b.

Are you sure you want to continue connecting (yes/no)? yes

Warning: Permanently added ‘192.168.136.130‘ (RSA) to the list of known hosts.

[email protected]‘s password:

21:35:26 up  3:52,  1 user,  load average: 0.00, 0.00, 0.00

spawn ssh [email protected] uptime

[email protected]‘s password:

22:40:24 up  3:52,  1 user,  load average: 0.00, 0.00, 0.00

spawn ssh [email protected] uptime

[email protected]‘s password:

00:05:41 up  3:52,  1 user,  load average: 0.00, 0.00, 0.00

4.2 开发 Expect 脚本实现自动交互式批量发送文件或目录

1)实现 Expect 自动化交互的脚本:

[[email protected] ~]# cat zidongjiaohu01.exp

#!/usr/bin/expect

if { $argc != 3 } {

puts "Usage:expect $argv0 file host dir"

exit

}

#define var

set file [lindex $argv 0]

set host [lindex $argv 1]

set dir  [lindex $argv 2]

set password "111111"

spawn scp -p22 -rp $file [email protected]$host:$dir

expect {

"yes/no"  {send "yes\r";exp_continue}

"*password" {send "$password\r"}

}

expect eof

执行结果如下:

[[email protected] ~]# expect zidongjiaohu01.exp

Usage:expect zidongjiaohu01.exp file host dir

[[email protected] ~]# expect zidongjiaohu01.exp /etc/hosts 192.168.136.130:/tmp

Usage:expect zidongjiaohu01.exp file host dir

[[email protected] ~]# expect zidongjiaohu01.exp /etc/hosts 192.168.136.130 /tmp

spawn scp -p22 -rp /etc/hosts [email protected]:/tmp

[email protected]‘s password:

hosts                                               100%  255     0.3KB/s   00:00

在 192.168.136.130 查看发送 hosts 文件结果是否成功:

[[email protected] tmp]# ll   #  执行前没有 hosts 文件。

total 4

drwxr-xr-x  2 root root 4096 Dec 10 21:46 data

-rw-------. 1 root root    0 Dec  9 22:11 yum.log

[[email protected] tmp]# ll   #  执行后有了 hosts 文件。

drwxr-xr-x  2 root root 4096 Dec 10 21:46 data

-rw-r--r--  1 root root  255 Dec 11 01:53 hosts

-rw-------. 1 root root    0 Dec  9 22:11 yum.log

2)利用 Shell 循环执行 Expect 脚本命令:

[[email protected] ~]# cat sh_piliang_exp01.sh

#!/bin/sh

if [ $# -ne 2 ]

then

echo $"Usage:$0 file dir"

exit 1

fi

file=$1

dir=$2

for n in 130 141 143

do

expect zidongjiaohu01.exp $file 192.168.136.$n $dir

done

执行结果如下:表示批量发送文件成功。

[[email protected] ~]# sh sh_piliang_exp01.sh /etc/hosts /tmp

spawn scp -p22 -rp /etc/hosts [email protected]:/tmp

[email protected]‘s password:

hosts           100%  255     0.3KB/s   00:00

spawn scp -p22 -rp /etc/hosts [email protected]:/tmp

[email protected]‘s password:

hosts           100%  255     0.3KB/s   00:00

spawn scp -p22 -rp /etc/hosts [email protected]:/tmp

[email protected]‘s password:

hosts          100%  255     0.3KB/s   00:00

4.3 开发 Expect 脚本实现自动交互式批量执行 Shell 脚本

见<<老男孩 Shell 高级编程实战 P334~336>>  【略】

4.4 开发 Expect 脚本实现自动交互式批量分发公钥

1)本地生成密钥对:【一路回车】

[[email protected] ~]# ssh-keygen -t dsa

Generating public/private dsa key pair.

Enter file in which to save the key (/root/.ssh/id_dsa):

/root/.ssh/id_dsa already exists.

Overwrite (y/n)?

[[email protected] ~]# ll .ssh/

total 8

-rw------- 1 root root 668 Dec 11 01:55 id_dsa

-rw-r--r-- 1 root root 605 Dec 11 01:55 id_dsa.pub

2)开发 Expect 脚本自动化交互分发公钥到所有的服务器:

[[email protected] ~]# cat fenfa_pub.exp

#!/usr/bin/expect

#created by ZhangLei

if { $argc != 2 } {

send_user "Usage:expect $argv0 file host\n"

exit

}

#define var

set file [lindex $argv 0]

set host [lindex $argv 1]

set password "111111"

#start exec command

spawn ssh-copy-id -i $file "-p 22 [email protected]$host"

expect {

"yes/no"  {send "yes\r";exp_continue}

"*password" {send "$password\r"}

}

expect eof

3)开发 Shell 脚本循环执行 Expect 脚本:

[[email protected] ~]# cat sh_xunhuanfenfa_pub.sh

#!/bin/sh

for n in 130 141 143

do

expect fenfa_pub.exp ~/.ssh/id_dsa.pub 192.168.136.$n

done

执行 Shell 脚本即可分发公钥到所有服务器,略。

原文地址:https://www.cnblogs.com/alinuxer/p/9880114.html

时间: 2024-11-10 17:57:24

Expect 自动交互式程序的相关文章

linux expect自动登录ssh,ftp

expect是一种能够按照脚本内容里面设定的方式与交互式程序进行“会话”的程序.根据脚本内容,Expect可以知道程序会提示或反馈什么内容以及 什么是正确的应答.它是一种可以提供“分支和嵌套结构”来引导程序流程的解释型脚本语言. shell功能很强大,但是不能实现有交互功能的多机器之前的操作,例如ssh和ftp.而expect可以帮助我们来实现. 一,安装expect yum install expect 其实expect根bash形势上差不多的. 二,实例 1,ssh实现自动登录,并停在登录服

shell脚本--expect自动应答

expect自动应答  TCL语言 需求1:远程登录到A主机,什么事情也不做 #! /usr/bin/env expect # 开启一个程序 spawn ssh [email protected]192.144.213.113 # 捕获相关内容 expect { "(yes/no)?" { send "yes\r";exp_continue } "password:" { send "Lzw18519331036\r" } }

用Python开发小学二年级口算自动出题程序

版权声明:本文为博主原创文章,欢迎转载,并请注明出处.联系方式:[email protected] 武汉光谷一小二年级要求家长每天要给小孩出口算题目,让孩子练习. 根据老师出题要求编写了Python程序自动出题,结果保存为txt文件,打印出来作为练习用,这样就不用每天繁琐地人工出题了,其中的数字用randint随机产生. 程序如下: # -*- coding:utf-8 -*- __author__ = 'zhengbiqing [email protected]' __doc__ = "&qu

c# 软件自动升级 程序自我关闭自己后重启

//指定一个文件名,写入脚本 string filename = Path.Combine(path,"killmyself.bat"); using (StreamWriter bat = new StreamWriter(filename, false, Encoding.GetEncoding("GB2312"))) { //删除指定程序,复制指定程序到指定路径 bat.WriteLine(string.Format(@" @echo off del

expect实现交互式输入

一.用expect实现交互式输入 #!/usr/bin/expect -fset LUKS_passphrase xxxx123set Verify_passphrase xxxx123spawn cryptsetup luksFormat /dev/vdb1 expect "Are you sure? (Type uppercase yes):"set timeout 5send "YES\r" expect "Enter LUKS passphrase

一个可以自动生成静态库,自动安装程序的Makefile

.PHONY:clean install CC=g++ CFLAGS=-Wall -g BIN=libecho.a INCLUDE=echo SRC=src OBJS=Socket.o Rio.o TcpConnection.o PollPoller.o InetAddress.o TcpServer.o Thread.o Condition.o ThreadPool.o Exception.o Timer.o TimerThread.o STARD=-std=c++0x -rdynamic $

[VC]VC实现开机自动运行程序

有时候,我们需要在计算机启动的时候就启动某些程序,不要人干预.这里,提供一种让程序开机自动运行的方法.见下面代码: BOOL CXXX::SetAutoRun(CString strPath) { CString str; HKEY hRegKey; BOOL bResult; str=_T("Software\\Microsoft\\Windows\\CurrentVersion\\Run"); if(RegOpenKey(HKEY_LOCAL_MACHINE, str, &

如何在Linux实现自动运行程序

1.开机启动时 Linux加载后, 它将初始化硬件和设备驱动, 然后运行第一个进程init. init根据配置文件继续引导过程,启动其它进程.通常情况下,修改放置在 /etc/rc或 /etc/rc.d ( /etc/rc?.d) 目录下的脚本文件,可以使init自动启动其它程序. /etc/rc:This file is responsible for starting/stopping services when the runlevel changes 例如: 编辑 /etc/rc.d/r

C#之tcp自动更新程序

.NETTCP自动更新程序有如下几步骤: 第一步:服务端开启监听 ServiceHost host; private void button1_Click(object sender, EventArgs e) { host = new ServiceHost(typeof(WCFService.Service)); host.Open(); if (host.State == CommunicationState.Opened) { this.button1.Enabled = false;