MSAgent简介 摘录

http://www.microsoft.com/china/technet/community/scriptcenter/funzone/agent.mspx
Microsoft Agent:教您的脚本说话

当想起自己对电脑说过的一些话时,您可能会认为电脑不会还口(或者不会扔东西)真是一件幸事。但是,作为一个脚本编写者,有时候您很可能会发现能向代码中加入一点声频反馈(以及一点动画)将很有用。例如,有视力障碍的用户更愿意登录脚本反馈通过声音形式提供,而不是在很小的对话框中提供难以阅读的视觉反馈。新用户可能更愿意得到有声说明,而不是难懂的消息框或滚动速度比阅读速度还快的命令窗口文本。而且 - 喘口气!- 有时候您可能觉得会说话的头像比那些人们看都不看就点击的对话框更有趣。

如果您想过“要是我的脚本能告诉每个人发生了什么事该多好,”,那您真走运:Microsoft Agent 技术(对,就是为我们带来文档活页夹 Clippy 和 Rover - 一只能在您搜索硬盘时提供帮助的狗 - 的技术)可完全脚本化。我们不知道您是否会需要(或希望)在您的脚本中包含 Microsoft Agent,但为以防万一,下面我们就教您怎样做。

注意:本文假设您已经在电脑上安装了 Microsoft Agent。Microsoft Agent 技术随 Windows 2000 和 Windows XP 预装在系统中;在 Windows XP 系统中,您还需要安装语音引擎和 SAPI 4.0 runtime。有关详细信息,请参阅 Microsoft Agent 主页。

 

本页内容
 现在,您是想看看,还是 …?
 Microsoft Agent 程序设计
 指挥人物
 在系统管理脚本中使用 Microsoft Agent
 就这么简单吗?

现在,您是想看看,还是 …?
尽管显示并控制会说话人物的方法听起来极其复杂,但使用 Microsoft Agent 编程实际上相当简单。想要您的人物说“hello”吗?那么使用类似如下一行代码:

objCharacter.Speak "Hello."

想要您的人物显出吃惊的表情吗?那么使用类似如下一行代码:

objCharacter.Play "Surprised"

对于多数情况,就这么简单。事实上,对于使用 Microsoft Agent 编写脚本来说,唯一麻烦的部分就是让您的人物出现在屏幕上,并让其逗留足够长的时间来完成程序要求其做的任何事情。这是因为 Microsoft Agent 代码异步运行;您启动 Agent 后,接下来 - 除非您采取适当的步骤,这一点我们稍后会解释 - 人物将完全独立于脚本中任何其他代码运行。这有一点好处:这样一来,您的人物不会妨碍其余部分脚本的运行(比如,显示 Agent 不会让忙于利用硬件和软件库存的脚本运行速度变慢)。但同样也有坏处:如果其余代码比您的 Agent 代码运行速度快,那么可能在您的 Agent 出现之前,脚本就已运行完毕。

我们知道这样说有些难懂,那么就让我们演示一下我们的意思。这里有一个简单的脚本,它用来显示 Merlin 这个人物。Merlin 在屏幕上出现后,他就会敲击显示器以引起您的注意,再问好并说再见,然后就消失。

strAgentName = "Merlin"
strAgentPath = "C:\Windows\Msagent\Chars\" & strAgentName & ".acs"
Set objAgent = CreateObject("Agent.Control.2")

objAgent.Connected = TRUE
objAgent.Characters.Load strAgentName, strAgentPath
Set objCharacter = objAgent.Characters.Character(strAgentName)

objCharacter.Show
objCharacter.Play "GetAttention"
objCharacter.Speak "Hello, how are you?"
objCharacter.Speak "I'm going now. Goodbye."
objCharacter.Hide

像我们刚才所说的那样,脚本应该做的就是这些。但是当您运行脚本时,实际上发生了什么呢?什么也没有发生。Merlin 甚至没有出现在屏幕上,更不用说敲显示器或说点什么了。

不用问,控制 Merlin 的代码是正确的;问题就出在代码出现的时间上。脚本运行时,它将依次执行每一行,并且尽可能快地执行。这就意味着脚本发送命令以显示(显现)Merlin,然后不等到 Merlin 实际出现,就开始执行其他代码行了。这并没有什么问题,只是 Merlin 需要花一两秒的时间才能启动,然后才真正出现在屏幕上。在 Merlin 能够出现之前,脚本引擎已经执行脚本最后一行了。因为最后一行代码已经执行,所以脚本也就自动终止了。脚本一终止,agentsrv.exe(负责运行 Microsoft Agent 的程序)也就终止了。脚本运行得实在太快,Agent 服务器根本无法跟上。结果是,Merlin 始终没有出现。

如果您想就此做个测试,尝试一下运行下面修改后的脚本。在该脚本中,我们在发出让 Merlin 出现在屏幕上的命令后,紧接着插入一个 Echo 语句。如果您使用 Wscript(而不是 Cscript)运行该脚本,就会产生一个消息框,它能暂停该脚本的运行。只要不马上点击 OK,就会看到 Merlin。但是,只要点击 OK 并关闭该消息框,Merlin 就会消失。为什么呢?还是我们刚才遇到的问题:其余的代码执行得太快;在脚本结束之前,Merlin 没有机会对命令做出反应。(如果您使用 Cscript 运行该脚本,此语句将回显命令窗口,您仍然无法看到 Merlin。)

strAgentName = "Merlin"
strAgentPath = "C:\Windows\Msagent\Chars\" & strAgentName & ".acs"
Set objAgent = CreateObject("Agent.Control.2")

objAgent.Connected = TRUE
objAgent.Characters.Load strAgentName, strAgentPath
Set objCharacter = objAgent.Characters.Character(strAgentName)

objCharacter.Show

Wscript.Echo "Waiting on Merlin."

objCharacter.Play "GetAttention"
objCharacter.Speak "Hello, how are you?"
objCharacter.Speak "I'm going now. Goodbye."
objCharacter.Hide

尝试多运行几次这个脚本,其中几次马上点击该消息框,另几次等一小会再关闭消息框。您就会明白我们的意思了。

显然,这是一个小问题;当会说话的人物真正出现在屏幕上并说话的时候,他们通常会更有用也更有趣。幸运的是,至少有两种方法可以解决这个问题。现在我们将教您一种非常简单的方法,然后在本文后面再演示一种稍微有点复杂(但更灵活)的方法。

您可能已经注意到,为使 Merlin 出现在屏幕上,我们只是调用了 Show 方法。Merlin 出现后,他会停留在屏幕上,直到发生下面两件事情中的任何一件:脚本结束,或者我们调用 Hide 方法。最终 Hide 方法才能解决问题:要在可以让 Merlin 消失前让他一直停留在屏幕上,就需要确保脚本始终不结束,至少在我们调用 Hide 方法之前不结束。

要做到这一点,或许最简单的方法就是在脚本末尾添加下面这三行代码:

Do While objCharacter.Visible = TRUE
    Wscript.Sleep 250
Loop

我们所做的是创建一个循环,只要我们的 Agent 的 Visible 属性为 True(也就是说只要人物在屏幕上),该循环就一直运行。如果 Merlin 在屏幕上,该脚本暂停四分之一秒 (Wscript.Sleep 250),然后循环继续并检查 Merlin 是否仍然可见。该过程持续不断直到 Merlin 不再出现在屏幕上;当 Merlin 不再可见,Visible 属性将变为 False,该脚本也将中止此循环。因为此循环恰好是脚本中最后几行代码,这也就意味着当我们关闭 Merlin 时该脚本就会终止。

哦,对了:要是您有疑问,下面就是用来关闭 Merlin 的代码:

objCharacter.Hide

仍然感到困惑吗?无论何时运行 Microsoft Agent 脚本(或任何其他脚本),每行代码都是依次并尽可能快地执行。大多数代码都是控制 Merlin 执行某项任务的命令。这些命令存储为一列,Merlin 将依次执行它们。在我们先前的脚本中,这些命令同样排成队列,但是在 Merlin 能够执行其中任何一个命令之前脚本就结束了。换句话说,脚本会运行每一行代码,从而将 Merlin 命令存储在队列中。因此,Merlin 也将按照命令在队列中的顺序依次执行这些命令。然而,在 Merlin 能够执行完命令队列前脚本就已经执行到最后一行代码。当脚本中最后一行代码执行完毕后,该脚本就自动结束了。而且脚本的结束也就意味着 Merlin 谢幕了。

现在我们已经对该脚本进行了配置,让它在 Merlin 执行 Hide 命令之前不会结束。因为 Hide 是我们对 Merlin 发布的最后的命令,所以 Merlin 在执行命令队列中的所有其他命令后再隐藏自己,然后该脚本才会结束。

下面是一个完整的脚本,运行它时将显示 Merlin,并让他敲打显示器以引起您的注意,问好并道别,然后消失。

strAgentName = "Merlin"
strAgentPath = "C:\Windows\Msagent\Chars\" & strAgentName & ".acs"
Set objAgent = CreateObject("Agent.Control.2")

objAgent.Connected = TRUE
objAgent.Characters.Load strAgentName, strAgentPath
Set objCharacter = objAgent.Characters.Character(strAgentName)

objCharacter.Show
objCharacter.Play "GetAttention"
objCharacter.Speak "Hello, how are you?"
objCharacter.Speak "I'm going now. Goodbye."
objCharacter.Hide

Do While objCharacter.Visible = TRUE
    Wscript.Sleep 250
Loop

我们了解,我们了解。但是我们的目的并不是要在您甚至还没入门之前就把您吓跑。只是 Microsoft Agent 工作方式和其他脚本编写技术不一样。如果您有一个使用 WMI 的脚本,那么该脚本会尽职地等待所有的 WMI 代码执行完毕后再继续执行,对于 ADSI、CDO、WSH(或其他您可能说出来的脚本编写缩写词)情况也是一样。但对于 Microsoft Agent,情况却并非如此,所以您应牢记这一点,否则 Agent 脚本恐怕永远不会按照您所希望的方式去工作。但请相信我们:从现在开始,这不过是小事一桩。

返回页首
Microsoft Agent 程序设计
让我们从头开始。我们将快速浏览下面这段代码,它举例说明 Microsoft Agent,并加载人物,然后让人物显示在屏幕上:

strAgentName = "Merlin"
strAgentPath = "C:\Windows\Msagent\Chars\" & strAgentName & ".acs"
Set objAgent = CreateObject("Agent.Control.2")

objAgent.Connected = TRUE
objAgent.Characters.Load strAgentName, strAgentPath
Set objCharacter = objAgent.Characters.Character(strAgentName)

objCharacter.Show

定义了一对变量之后,该脚本创建了一个 Microsoft Agent 服务器的实例并与该实例相连接。接下来该脚本加载脚本头两行已指定的名称为 (strAgentName) 的人物以及文件路径 (strAgentPath)。加载人物后,该脚本创建一个人物对象实例,该实例与刚加载的人物相对应。然后,脚本使用下面这行代码显示人物:

objCharacter.Show

就这么简单;事实上,您可能在大多数脚本中都能够原封不动地使用此样板代码。您唯一可能需要更改的地方就是人物的名称(假设您要使用的人物不是 Merlin),或许还有 .acs 文件的路径(只有当文件在 C:\Windows\Msagent\Chars 下无法找到的时候才需更改)。除此之外,您尽可以将样板代码复制并粘贴到用 Microsoft Agent 编写的每一个脚本中。

注意:我们选择了 Merlin 作为我们的示例人物,是因为 Merlin 随 Windows 提供并安装。不过,还有其他一些人物可供使用,其中包括三个可免费下载的 Microsoft 人物:Peedy 是一只鹦鹉;Genie 是一个精灵;Robby 是一个机器人。有关详细信息,请参阅 Microsoft Agent 主页。

默认情况下,无论何时调用了 Show 方法,这些人物都会演示“出场动画”;例如,对于 Merlin,首先出现的是他的帽子,然后他从帽子里面落下来。如果您希望人物出现时不演示生动的出场动画,那么只需要将 Show 方法的可选 Fast 参数设为 TRUE 即可:

objCharacter.Show TRUE

返回页首
指挥人物
当 Merlin 出现在屏幕上以后,我们就可以开始对他发号施令了。现在,我们假设调用 Show 方法后,可以让人物执行六种任务:


? 让人物说话(使用 Speak 方法)。
 
? 让人物思考(使用 Think 方法)。
 
? 让人物做些举动,比如显得高兴,显得困惑或者挥手告别(使用 Play 方法)。
 
? 让人物指向某物(使用 GestureAt 方法)。
 
? 让人物移动到屏幕上的其他位置(使用 MoveTo 方法)。
 
? 关闭人物(使用 Hide 方法)。
 

让我们来看看用来执行所有这些操作的脚本:

strAgentName = "Merlin"
strAgentPath = "c:\windows\msagent\chars\" & strAgentName & ".acs"
Set objAgent = CreateObject("Agent.Control.2")

objAgent.Connected = TRUE
objAgent.Characters.Load strAgentName, strAgentPath
Set objCharacter = objAgent.Characters.Character(strAgentName)

objCharacter.Show

objCharacter.Play "GetAttention"
objCharacter.Speak "Hello, how are you?"
objCharacter.Play "LookDown"
objCharacter.Think "Maybe I should move around a little ...."
objCharacter.MoveTo 500,400
objCharacter.Play "Pleased"
objCharacter.Speak "Goodbye."
objCharacter.Hide

Do While objCharacter.Visible = TRUE
    Wscript.Sleep 100
Loop

现在让我们来较为详细地看看每一个操作。

让人物说话

不管您相信与否,作为一个脚本编写者,您要做的最简单的事情之一就是让人物说话:您只需要调用 Speak 的方法,并在其后加上任何您希望人物所说的话即可。如果您使用下面这行代码:

objCharacter.Speak "Hello, how are you?"

您就会看到类似下面这样的画面,并听到说话的声音:


默认情况下,每次当人物说话时,他或她的话都伴随着文字气球出现。如果您希望人物说话时不显示文字气球,那么只需将 Balloon.Style 属性设置为 0:

objCharacter.Balloon.Style = 0

您将仍然能听到 Merlin 的声音,但是文字气球将不再显示:


让人物思考

让人物思考采用与让人物说话几乎相同的步骤:调用 Think 方法,并在其后加上任何您希望人物思考的事情。例如,下面这行代码命令人物产生这样一个想法,“Just a moment; I’m thinking.”

objCharacter.Think "Just a moment; I’m thinking."

当人物思考时,只有他或她的想法显示在文字气球上。人物并不说话,而且也您听不到任何声音。


让人物做些举动

每个 Microsoft Agent 人物都自带一组动画,可以使用 Play 方法调用这些动画。例如,假设您希望人物显得很悲伤。您只需调用 Sad 动画:

objCharacter.Play "Sad"

同样,Merlin 能通过取出并吹奏一个喇叭示意发出通知。通过调用 Announce 动画就能做到:

objCharacter.Play "Announce"


可以调用的动画取决于不同的人物。(动画比较特殊,它们被硬编码到每个人物中。)下表中列出了可用于 Merlin 的动画的列表:

动画
 说明
 
Acknowledge
 点头
 
Alert
 伸直并抬起眉毛
 
Announce
 举起喇叭并吹奏
 
Blink
 眨眼睛
 
Confused
 挠头
 
Congratulate
 展示奖品
 
Congratulate_2
 鼓掌
 
Decline
 抬起手并摇头
 
DoMagic1
 举起魔法棍
 
DoMagic2
 放下魔法棍,出现云彩
 
DontRecognize
 捂住耳朵
 
Explain
 将两臂向两侧展开
 
GestureDown
 向下的手势
 
GestureLeft
 向左的手势
 
GestureRight
 向右的手势
 
GestureUp
 向上的手势
 
GetAttention
 向前倾并敲击
 
GetAttentionContinued
 向前倾并再次敲击
 
GetAttentionReturn
 返回正常姿势
 
Hearing_1
 耳朵伸长(循环的动画)
 
Hearing_2
 头向左倾(循环的动画)
 
Hearing_3
 头向左转(循环的动画)
 
Hearing_4
 头向右转(循环的动画)
 
Hide
 消失在帽子下面
 
Idle1_1
 喘口气
 
Idle1_2
 向左看并眨眼
 
Idle1_3
 向右看
 
Idle1_4
 从上往右看并眨眼
 
Idle2_1
 看看魔法棍并眨眼
 
Idle2_2
 手握手并眨眼
 
Idle3_1
 打呵欠
 
Idle3_2
 入睡(循环的动画)
 
LookDown
 向下看
 
LookDownBlink
 眨眼向下看
 
LookDownReturn
 返回正常姿势
 
LookLeft
 向左看
 
LookLeftBlink
 眨眼向左看
 
LookLeftReturn
 返回正常姿势
 
LookRight
 向右看
 
LookRightBlink
 眨眼向右看
 
LookRightReturn
 返回正常姿势
 
LookUp
 向上看
 
LookUpBlink
 眨眼向上看
 
LookUpReturn
 返回正常姿势
 
MoveDown
 向下飞行
 
MoveLeft
 向左飞行
 
MoveRight
 向右飞行
 
MoveUp
 向上飞行
 
Pleased
 微笑并把手合在一起
 
Process
 搅拌大锅
 
Processing
 搅拌大锅(循环的动画)
 
Read
 打开书,阅读并查寻
 
ReadContinued
 阅读并查寻
 
ReadReturn
 返回正常姿势
 
Reading
 阅读(循环的动画)
 
RestPose
 正常姿势
 
Sad
 悲伤的表情
 
Search
 观察水晶球
 
Searching
 观察水晶球(循环的动画)
 
Show
 从帽子中出现
 
StartListening
 手靠向耳朵
 
StopListening
 手捂在耳朵上
 
Suggest
 显示电灯泡
 
Surprised
 显得很吃惊
 
Think
 用手托住下巴向上看
 
Thinking
 用手托住下巴向上看(循环的动画)
 
Uncertain
 向前倾并抬起眉毛
 
Wave
 摆手
 
Write
 打开书,书写并查寻
 
WriteContinued
 书写并查寻
 
WriteReturn
 返回正常姿势
 
Writing
 书写(循环的动画)
 

您还可以使用如下的脚本检索与人物有关的动画:

strAgentName = "genie"
strAgentPath = "C:\WINDOWS\msagent\chars\" & strAgentName & ".acs"
Set objAgent = CreateObject("Agent.Control.2")

objAgent.Connected = TRUE
objAgent.Characters.Load strAgentName, strAgentPath
Set objCharacter = objAgent.Characters.Character(strAgentName)

For Each strName in objCharacter.AnimationNames
    Wscript.Echo strName
Next

循环的动画。您可能已经注意到表格中有些动画标示为“循环的”动画。循环的动画就是动画始终运行直到您明确命令它停止(通过使用 Stop 方法)。例如,这是一个始终运行的脚本。为什么呢?因为我们调用了循环的动画 (Searching) 并且没有明确地停止它:

strAgentName = "Merlin"
strAgentPath = "C:\Windows\Msagent\Chars\" & strAgentName & ".acs"
Set objAgent = CreateObject("Agent.Control.2")

objAgent.Connected = TRUE
objAgent.Characters.Load strAgentName, strAgentPath
Set objCharacter = objAgent.Characters.Character(strAgentName)

objCharacter.Show
objCharacter.Speak "Please wait."
objCharacter.Play "Searching"
 
objCharacter.Hide

Do While objCharacter.Visible = True
    Wscript.Sleep 250
Loop

注意:您可以通过右键点击 Merlin 并选择 Hide 来停止这个动画和这个脚本。

下面是修订过的脚本,它使用了 Stop 方法。调用 Searching 动画后,我们使用 Wscript.Sleep 来暂停脚本几秒钟;以此来确保脚本实际上有时间启动这个动画。然后使用 Stop 方法停止该动画并让脚本结束:

strAgentName = "Merlin"
strAgentPath = "C:\Windows\Msagent\Chars\" & strAgentName & ".acs"
Set objAgent = CreateObject("Agent.Control.2")

objAgent.Connected = TRUE
objAgent.Characters.Load strAgentName, strAgentPath
Set objCharacter = objAgent.Characters.Character(strAgentName)

objCharacter.Show
objCharacter.Speak "Please wait."
objCharacter.Play "Searching"

Wscript.Sleep 10000
 
objCharacter.Stop

objCharacter.Hide

Do While objCharacter.Visible = True
    Wscript.Sleep 250
Loop

让人物指向某处

您会问,那手势怎么办呢?问得好。有时候您不想播放动画;只是希望您的人物指向一般的方向。要实现这个操作您可以调用 GestureAt 方法,并传递两个参数:左侧位置(以像素为单位)和上方位置(同样以像素为单位)。这些值将强迫人物指向与指定方向接近的方向(该动画还没有复杂到能够指向准确的像素)。如下的代码将很可能会使 Merlin 指向屏幕的左侧。(为什么是很可能呢?Merlin 手势的确切方向不仅取决于您输入的坐标,也取决于 Merlin 的当前屏幕位置。要达到您所希望的准确结果,可能需要多试验几次。)

objCharacter.GestureAt 0, 0

如下代码可以让 Merlin 指向屏幕右侧:

objCharacter.GestureAt 800, 0


坦白地讲,根据 Merlin 在屏幕上的位置不同,有时候要预测其手势的方向会很困难。如果要确保您的人物向指定的方向观看,执行动画(如 LookRight 或 LookLeft)而不依靠 GestureAt 是个好办法。

让人物移动到某处

可使用 MoveTo 方法在屏幕上四处移动人物。MoveTo 以像素为单位来测量屏幕上的移动,0,0 代表屏幕的左上边界。要将人物移动到距屏幕左边界 200 像素且距上边界 600 像素的位置,可使用如下代码:

objCharacter.MoveTo 200, 600


默认情况下,人物的速度以 1000 毫秒时间设置。要改变人物的速度,可向 MoveTo 方法添加第三个参数。要使人物移动得更快,可添加一个小于 1000 的数;要使其速度变慢,可添加一个大于 1000 的数。例如,下面这行代码让 Merlin 以大约其正常速度一半的速度移动:

objCharacter.MoveTo 200, 600, 2000

默认情况下,内置动画让人物平稳地从一个位置移动到另一个位置。如果您希望人物从一个地点突然消失然后出现在另一个地点,可将可选速度参数设置为 0:

objCharacter.MoveTo 200, 600, 0

MoveCause 属性。如果您想要人物做些古怪一点的事情(我们得承认,如果您没有想过,您就不会一直读到这里),每个人物都有 MoveCause 属性,它指示人物上次移动的原因。MoveCause 返回下表所示的一个值:


 说明
 
0
 人物没有移动。
 
1
 用户移动过人物。
 
2
 应用程序移动过人物。
 
3
 其他的客户端应用程序移动过人物。
 
4
 Agent 服务器移动过人物,以使人物在屏幕分辨率更改后仍然保留在屏幕上。
 

这有什么酷的呢?好吧,这里是一个简单的小脚本,该脚本让 Merlin 出现在屏幕上,并且请求人们不要点击他并将他到处拖动。接着,该脚本检查 MoveCause 属性的值。若 MoveCause 等于 1,就意味着用户移动过人物;结果,Merlin 会表现出吃惊,并提醒用户,“Hey, I said don’t move me!”如果用户没有移动 Merlin,那么 Merlin 什么也不会说。该脚本还使用了 Request 对象,我们将在本文下一部分对其进行讨论。

strAgentName = "Merlin"
strAgentPath = "c:\windows\msagent\chars\" & strAgentName & ".acs"
Set objAgent = CreateObject("Agent.Control.2")

objAgent.Connected = TRUE
objAgent.Characters.Load strAgentName, strAgentPath
Set objCharacter = objAgent.Characters.Character(strAgentName)

objCharacter.Show
Set objRequest = objCharacter.Speak _
    ("Please don't click the mouse and drag me to a new location.")

Do While objRequest.Status > 0
    Wscript.Sleep 500
Loop

If objCharacter.MoveCause = 1 Then
    objCharacter.Play "Surprised"
    objCharacter.Speak "Hey, I said don't move me!"
End If

objCharacter.Hide

Wscript.Sleep 3000

Do While objCharacter.Visible = True
    Wscript.Sleep 1000
Loop

要了解 MoveCause 的工作方式,可运行该脚本两次:一次将 Merlin 拖动到新的位置,另一次则不动。

让人物消失

正如我们前面提到的,您只需调用 Hide 方法便可让人物消失:

objCharacter.Hide

同 Show 方法一样,Hide 同样有一个可选的 Fast 参数。默认情况下,当您调用 Hide 方法时,人物会表演退场动画;就 Merlin 而言,他会将自己卷到帽子中然后消失。如果您希望人物只是消失,而不表演退场动画,可将 Fast 参数设为 TRUE:

objCharacter.Hide TRUE

返回页首
在系统管理脚本中使用 Microsoft Agent
至此,我们重点向您介绍了如何让人物出现,并逗留足够长的时间以做些有趣的事。有时候,这就够了;例如,您可能希望人物停留的时间够说一些话(如“我们正在完成您的登录脚本处理,请稍等”)即可,然后就消失。不过,在其他时候,您可能希望人物在脚本运行期间一直逗留在屏幕上。但是,象我们早先看到的那样,这里存在一个问题:当人物以一个线程运行而其余的脚本又以另外一个线程运行的时候,我们如何才能保持人物与脚本同步呢?

或许,最好的方法便是使用 Request 对象。每次您调用人物方法的时候,系统都会创建 Request 对象;该对象包含有 Status 属性,它能告诉您这个方法的当前状态。如果请求的 Status 为 0,则该请求是完成的(例如,动画演示已经完成);如果该请求大于 0(Status 值在 0 到 4 之间),则该请求可能在队列中、正在执行或已经中断。(有关 Request 对象及其状态代码的完整说明,请参阅 MSDN 上 Microsoft Agent SDK 的相关部分)。

使用 Request 对象能让脚本暂停直到指定的方法完成。例如,要确保 Announce 动画一直演示到完成,可以使用类似如下的代码:

Set objRequest = objCharacter.Play("Announce")

Do While objRequest.Status > 0
    Wscript.Sleep 100
Loop

当我们调用 Play 方法时,同时也创建了一个 Request 对象的实例。在下一行代码中,我们创建一个 Do While 循环用来检查 Status 属性。如果 Status 大于 0,则脚本睡眠 100 毫秒,循环继续并再次检查 Status 属性。如果 Status 等于 0,我们就退出循环继续运行下面的代码。

通过将这些 Do While 循环插在脚本中,我们能够非常好地实现人物行为与其余脚本的同步运行。

例如,下面这个脚本,它可以显示 Merlin 人物,然后在检索(并回显)有关安装在电脑上的服务的信息时,让 Merlin 一直留在屏幕上。

strAgentName = "Merlin"
strAgentPath = "C:\Windows\Msagent\Chars\" & strAgentName & ".acs"
Set objAgent = CreateObject("Agent.Control.2")

objAgent.Connected = TRUE
objAgent.Characters.Load strAgentName, strAgentPath
Set objCharacter = objAgent.Characters.Character(strAgentName)

objCharacter.Show
Set objRequest = objCharacter.Play("Announce")

Do While objRequest.Status > 0
    Wscript.Sleep 100
Loop

Set objRequest = objCharacter.Speak _
    ("Please wait while we collect inventory information for your computer.")

Do While objRequest.Status > 0
    Wscript.Sleep 100
Loop

objCharacter.Play "Writing"

Wscript.Sleep 5000

strComputer = "."
Set objWMIService = GetObject _
    ("winmgmts:\\" & strComputer & "\root\cimv2")
Set colServices = objWMIService.ExecQuery _
    ("Select * From Win32_Service")

For Each objService in colServices
    Wscript.Echo objService.Name, objService.Status
Next

objCharacter.Stop

Set objRequest = objCharacter.Speak _
    ("We're done. Thank you for your patience.")

Do While objRequest.Status > 0
    Wscript.Sleep 100
Loop

objCharacter.Hide

请注意我们如何使用 Request 对象来控制脚本的流程。首先我们调用 Announce 动画;使用 Request 对象确保在脚本继续之前该动画完成。接着,让 Merlin 告诉用户我们将要收集库存信息。再次使用 Request 对象来发表声明;这将确保 Merlin 有机会说话。我们调用 Writing 动画(循环的动画),然后插入 5 秒钟的暂停 (Wscript.Sleep 5000);之所以插入暂停是因为服务信息返回得非常快,而我们希望能确保动画开始演示。如果您的脚本返回许多库存类型信息(这样运行时间会更长),可能就不需要插入暂停。

在循环动画运行同时,我们现在使用 WMI 来检索服务信息。完成信息收集后,我们调用 Stop 方法来停止循环动画。然后让 Merlin 说再见,再一次使用 Request 对象来确保他有机会说话。至此您已实现了您的目的:动画与其余脚本比较好地实现了同步。

返回页首
就这么简单吗?
您很可能很快就掌握了使用 Microsoft Agent 的基础知识,毕竟,它实际上就这么简单。不过,接下来呢?难道这就是全部:让 Agent 出现在屏幕上,再让人物说点什么,然后就全部结束了吗?

远不止这些;事实上,使用 Microsoft Agent 可以做各种各样其他很酷的事。例如,您可以在屏幕上同时显示两个或更多的 Agent,并且让他们彼此交互。在这方面,您甚至可以使用语音识别并让 Agent 同您进行交互:您可以发布 Agent 会做出回应的语音命令。所有这些都远超出这篇介绍性文章的范围,但如果大家有足够的兴趣,我们会在以后重新讨论这些主题。同时,您可以通过查看 MSDN 上的 Microsoft Agent SDK 得到完整的 Agent 功能列表。

有用的提示:如果您在寻找可让编写 Microsoft Agent 脚本变得容易的图形化的实用程序,请浏览 http://www.bellcraft.com/mash 上的 MASH (Microsoft Agent Scripting Helper)。

 

posted on 2007-05-14 10:05  shappy  阅读(589)  评论(0编辑  收藏  举报

导航