2. IIS 5.0 ASP新功能

本章重点
 

介绍IIS 5.0於ASP上所新增加的功能,以及详细介绍其中Server.Transfer/Execute、Server.GetLastError、支援伺服器端Scriptlet、使用cookie取得浏览器资讯、保护asp或html原始码等新功能。

ASP(Active Server Pages)3.0
 

在IIS伺服器端执行的指令档语言ASP(Active Server Pages),可以用来建立动态的网页内容。

Windows 2000的ASP(Active Server Pages)3.0版本提供甚麽样的新功能呢?

本章将针对IIS 5.0於ASP上所新增加的功能,详细介绍其中Server.Transfer/Execute、Server.GetLastError、支援Scriptlet、使用cookie取得浏览器资讯、保护asp或html原始码等新功能。

侦测asp程式於IIS 5.0执行
 

由於IIS 5.0 ASP 3.0版本新增加一些功能,asp程式必须侦测於IIS的执行版本,若於IIS 5.0执行,则善用IIS 5.0之ASP 3.0版本新增加的一些功能。

如何侦测asp程式是否於IIS 5.0执行呢?

您可使用Request.ServerVariables("SERVER_SOFTWARE")来判断是否使用IIS 5.0("Microsoft-IIS/5.0"),如下:

if Request.ServerVariables("SERVER_SOFTWARE") = "Microsoft-IIS/5.0" then
	'IIS 5.0程式 
else
	'IIS 4.0程式
end if

2-1 IIS 5.0於ASP上新增哪些功能呢?
 

IIS 5.0於ASP方面新增加了几项功能,包括新的转向方法(Server.Transfer与Server.Execute方法)、新的错误处理功能(Server.GetLastError方法)、支援XML、增快无指令.asp的执行速度、调升可安装元件的效能、支援Scriptlet、使用cookie取得浏览器资讯、自动增减执行绪(executing threads)、SRC伺服器端包含功能、侦测使用者是否仍然连线、Script Encoder编码保护、内建物件的新增功能等,简介如下:

新的转向方法
 

新的转向方法(Server.Transfer与Server.Execute方法),直接由IIS 5.0於网站伺服器端直接转向到另一个网页,不需像Response.Redirect先传送到浏览器,再要求网站伺服器转向,如此可减少一次用户端与网站伺服器之间的来回通讯时间。


说明

有关新的转向方法部份,请参阅 2-2〈如何使用Server.Transfer/Execute呢?〉 。


新的错误处理功能
 

您可使用新的Server.GetLastError方法来显示有用的错误资讯。


说明

有关新的错误处理功能部份,请参阅 2-3〈如何使用Server.GetLastError呢?〉 。


支援XML
 

IIS 5.0的ADO 2.5,支援XML(eXtensible Markup Language),提供stream物件以将ADO之Recordset资料储存成XML格式,并暂时放置於记忆体当中。


说明

有关支援XML部份,请参阅 第叁章〈IIS 5.0与XML〉 。


增快无指令.asp的执行速度
 

IIS 5.0处理「无指令」的.asp档案时,执行速度上比旧版快上许多。所谓「无指令」即不含asp指令,指的是不含伺服器端程式的.asp档案。

因为处理副档名.asp须於伺服器端动态地产生内容,执行速度上比处理副档名.htm等固定资料慢上许多。於旧版IIS,即使一个副档名.asp档案只包括一些HTML码而未包括任何一行的asp指令时,执行速度也比副档名.htm慢,因此一般不会把副档名.htm改名为.asp。

IIS 5.0就可以放心地把副档名.htm改名为.asp。

调升可安装元件的效能
 

IIS 5.0新版的ASP将一些可安装元件(Installable Components)之执行效能加以调升。

支援伺服器端Scriptlet
 

ASP支援伺服器端Scriptlet(指令元件)指令技术,可以从.asp档案将Scriptlet当成COM元件的方式来呼叫。

您可以用VBScript或Jscript的语言(不需要使用Visual Basic、C++、或者Java语言来编写程式)编写Scriptlet,储存成.sct副档名,注册成为元件後,即可当成COM元件(Component Object Model)般来呼叫使用。


说明

有关Scriptlet部份,请参阅 2-4〈ASP如何支援伺服器端Scriptlet呢?〉 。


使用cookie取得浏览器资讯
 

现在於IIS 5.0,多了一项新的判断浏览器功能方法,方法为使用cookie储存於浏览器DHTML语法所侦测到的资讯传回IIS,以後便可透过Browser Capabilities元件得知cookie回报的浏览器资讯。


说明

有关cookie部份,请参阅 2-5〈如何使用cookie取得浏览器资讯?〉 。


自动增减执行绪(executing threads)
 

新版的ASP能自动增减执行绪(executing threads),当侦测到无法顺利执行要求(如被外界锁定资源)时,ASP会自动增加更多的执行绪数量,以便同时执行更多的用户端要求;当侦测到CPU的负荷过重时,ASP会自动缩减执行绪的数量。如此可降低系统来回切换执行绪的频率。

若要不启用此自动增减执行绪的功能,可以设定AspThreadGateEnabled的metabase属性。

SRC伺服器端包含功能
 

於伺服器端包含一个档案,除了#Include指令外,新版的ASP让您可以於HTML的<SCRIPT></SCRIPT>标记中的SRC属性来达成伺服器端的包含功能。语法如下,SRC属性可设定虚拟路径或相对路径,用RUNAT=SERVER属性来表示要伺服器端执行:

<SCRIPT LANGUAGE="VBScript" RUNAT=SERVER SRC="xxx.inc"></SCRIPT>

若须於<SCRIPT>标记内放入程式码,需多加一组<SCRIPT>标记。

侦测使用者是否仍然连线
 

Response.IsClientConnected侦测使用者是(True)否(False)仍然连线。

譬如:

<% 
  '侦测使用者是(True)否(False)仍然连线
  If Response.IsClientConnected = False Then 
    '若未连线则取得SessionID,并加予处理
     Shutdown(Session.SessionID) 
  End If
%>

若侦测使用者未连线,则取得SessionID,并呼叫Shutdown函数加予处理。

Script Encoder编码保护
 

Script Encoder程式编码工具,可以将浏览器端与伺服器端的指令加以编码,使原来的程式变成一堆无法阅读的乱码,以保护asp或html的原始码被他人所偷窥,执行时指令引擎会先自动进行解码。


说明

有关Script Encoder部份,请参阅 2-6〈如何保护asp或html原始码呢?〉 。


内建物件元件的新增功能
 

於内建的物件中,IIS 5.0比IIS 4.0所新增加的功能如下:


说明

有关内建物件部份,请参阅 附录B〈快速学会ASP内建物件〉 。


另外新增加Counters、Tools、Logging Utility叁个可安装的元件,如下:

  1.  Counters Component(计数器元件): 产生、储存、新增、读取多个个别的计数器。
  2.  Tools(工具元件): 提供判断档案是否存在、取得-32768 ~ 32767乱数等功能。
  3.  Logging Utility: 提供读取IIS Log档案内容的功能,IIS Log档案位於c:\WinNT\System32\LogFiles\W3SVC1\exYYMMDD.log。

说明

有关可安装的元件部份,请参阅 附录C〈快速学会ASP元件〉 。


IIS 5.0所包括的ADO 2.5对於XML新提供的功能:

  1.  RS.Save Response: 直接将recordset的资料,以XML格式输出(Response)到浏览器,使用RS.Save Response, adPersistXML指令。
  2.  新增加STREAM物件,提供recordset与XML格式记忆体交换的功能: 将recordset的资料以XML格式储存於记忆体(使用STREAM物件)中,使用RS.Save ST, adPersistXML指令;将储存於记忆体(使用STREAM物件)中XML格式资料转到recordset中,使用RS.Open ST指令。

说明

有关XML部份,请参阅 第叁章 〈IIS 5.0与XML〉 。


本章详细介绍其中Server.Transfer/Execute、Server.GetLastError、支援Scriptlet、使用cookie取得浏览器资讯、保护原始码等新功能,XML支援新功能将於 下一章介绍 。

2-2 如何使用Server.Transfer/Execute呢?
 

新的转向方法
 

以前在IIS 4.0网站,将一个网页转向到另一个网页的ASP转向的方法,为使用Response.Redirect指令,譬如:

<% Response.Redirect "http://www.asp.com.tw" %>

此方法需要由IIS网站先传送到浏览器,浏览器再将IIS网站要求转向到另一个网页www.asp.com.tw,如此会增加一次用户端与网站伺服器之间的来回通讯时间。那麽,为什麽不於网站伺服器端直接转向到另一个网页呢 ?

现在在IIS 5.0,可以直接由IIS 5.0於网站伺服器端直接转向到另一个网页,而不需先传送到浏览器再要求网站伺服器转向。

方法为使用IIS 5.0新增加的两个新转向方法:Server.Transfer与Server.Execute,譬如:

<% Server.Transfer("http://www.asp.com.tw") %>

Server.Transfer与Server.Execute相异之处
 

Server.Transfer与Server.Execute不同的地方,为执行Server.Transfer後就不会回原呼叫程式;而执行Server.Execute後仍然会继续执行原呼叫程式Server.Execute下一行的指令。

Server.Transfer与Response.Redirect比较相类似;而Server.Execute与#include用法比较相接近。

譬如execute1a.asp一行显示指令後,使用Server.Execute指令转向到另一个网页execute1b.asp:

<%  
Response.Write("A1(原呼叫程式)<BR>")
Server.Execute "execute1b.asp"
Response.Write("A2(原呼叫程式)<BR>")
%>

转向後execute1b.asp只有一行显示指令:

<%  Response.Write("B1(转向後)<BR>") %>

执行一行显示指令後,再执行转向後execute1b.asp显示指令,仍然会继续执行原呼叫程式Server.Execute下一行的指令。执行execute1a.asp结果如下:


 

若将execute1a.asp使用Server.Execute指令改变为Server.Transfer指令,如下transfer1a.asp:

<%  
Response.Write("A1(原呼叫程式)<BR>")
Server.Transfer "execute1b.asp"
Response.Write("A2(原呼叫程式)<BR>")
%>

则执行後,就不会执行Server.Transfer指令後的程式了。执行transfer1a.asp结果如下:


 

Server.Transfer与Response.Redirect相异之处
 

虽然Server.Transfer与Response.Redirect都会转向,但是Server.Transfer方法会将Session和Application变数值暂时带到转向後之URL位址,Response.Redirect则不会。

譬如/iis5samp/transfer2aa.asp设定Application("test")变数值後,使用Response.Redirect指令转向到另一个网页/iis5samp2/transfer2b.asp:

<%  
Application("test") = "Transfer前的Application值"
Response.Redirect "/iis5samp2/transfer2b.asp"
%>

另一个网页transfer2b.asp仅显示Application("test")变数值:

<%  Response.Write "Transfer後的Application值: " & Application("test") %>

因为转向前的iis5samp与转向後的iis5samp2属於不同的应用程式,因此iis5samp应用程式的Application("test")变数值不会传到iis5samp2应用程式,执行结果发现Application("test")为空的。执行transfer2aa.asp结果如下:


 

若将Response.Redirect指令改为使用Server.Transfer指令:

<%  
Application("test") = "是Transfer前的Application值"
Server.Transfer "/iis5samp2/transfer2b.asp"
%>

则因Server.Transfer方法会将Session和Application变数值带到转向後之URL位址,因此转向後执行结果Application("test")为转向前程式所设定的值。执行transfer2a.asp结果如下:


 

转向前程式之Session和Application变数值是暂时带到转向後的程式,不会影响转向後应用程式的Session和Application变数值。因此若再单独执行转向後的程式/iis5samp2/transfer2b.asp,并不会保留转向前程式所带来之Session和Application变数值。执行transfer2b.asp结果如下:


 

Server.Execute与#include相异之处
 

虽然Server.Execute与#include指令都是於原程式当中包含另外一个网页来执行,但是不一样的地方是#include仅将所包含的程式插入原程式当中,而Server.Execute系单独执行所包含的程式。

譬如include1a.asp使用#include指令包含另一个网页include1b.asp,第一行加入@ Transaction=Required,表示整个网页要有transaction功能:

<% @ Transaction=Required %>
<!-- #include file="include1b.asp" -->
<%  
Sub OnTransactionCommit
	Response.Write("原呼叫程式OnTransactionCommit副程式<BR>")
End Sub  
Sub OnTransactionAbort
	Response.Write("原呼叫程式OnTransactionAbort副程式<BR>")
End Sub  

%>

包含网页include1b.asp於第一行加入@ Transaction=Required,表示整个网页也要有transaction功能,如下:

<% @ Transaction=Required %>
<% ObjectContext.SetAbort %>

因此#include仅将所包含的程式插入,造成两行的@ Transaction=Required指令,因ASP内只可使用一次@命令,执行後将显示错误。执行include1a.asp结果如下:


 

Server.Execute与transaction关系
 

Server.Execute会将转向後之URL位址之transaction结果(OnTransactionAbort和OnTransactionCommit),带回原呼叫程式而影响其transaction结果。

譬如execute2a.asp使用Response.Redirect指令转向到另一个网页execute2b.asp,第一行加入@ Transaction=Required,表示整个网页要有transaction功能:

<% @ Transaction=Required %>
<%  
Server.Execute "execute2b.asp"
Sub OnTransactionCommit
	Response.Write("原呼叫程式OnTransactionCommit副程式<BR>")
End Sub  
Sub OnTransactionAbort
	Response.Write("原呼叫程式OnTransactionAbort副程式<BR>")
End Sub  
%>

转向後execute2b.asp於第一行加入@ Transaction=Required,表示整个网页也要有transaction功能,并加入一行ObjectContext.SetAbort强制放弃,如下:

<% @ Transaction=Required %>
<%  
ObjectContext.SetAbort
Sub OnTransactionCommit
	Response.Write("转向後OnTransactionCommit副程式<BR>")
End Sub  
Sub OnTransactionAbort
	Response.Write("转向後OnTransactionAbort副程式<BR>")
End Sub  
%>

执行後,因转向後execute2b.asp之transaction结果(ObjectContext.SetAbort强制放弃导致执行转向後之OnTransactionAbort副程式),会带回原呼叫程式execute2a.asp而影响其transaction结果,所以原呼叫程式也会执行其OnTransactionAbort副程式。执行execute2a.asp结果如下:


 

若移除转向後execute2b.asp之ObjectContext.SetAbort程式成execute3b.asp,则转向後execute3b.asp之transaction结果(执行OnTransactionCommit副程式),会带回原呼叫程式execute3a.asp而影响其transaction结果,所以原呼叫程式也会执行其OnTransactionCommit副程式。执行execute3a.asp结果如下:


 

2-3 如何使用Server.GetLastError呢?
 

现在於IIS 5.0,可以使用新的Server.GetLastError方法来显示有用的错误资讯。

譬如执行一个错误的ASP程式如下,其中nxt应该为Next:

<%
  for i=1 to 1
  nxt
%>

执行结果显示错误讯息,如下:


 

每当有错误发生时,IIS预设执行500-100.asp程式,此程式中相关ASP程式如下:

Set objASPError = Server.GetLastError

'Microsoft VBScript编译阶段错误(0x800A03FC)
  Response.Write Server.HTMLEncode(objASPError.Category)
  If objASPError.ASPCode > "" Then Response.Write Server.HTMLEncode
(", " & objASPError.ASPCode)
  Response.Write Server.HTMLEncode("(0x" & Hex(objASPError.Number) 
& ")") & "<br>"
'必须要有 'Next'

  If objASPError.ASPDescription > "" Then 
		Response.Write Server.HTMLEncode(objASPError.ASPDescription) & 
"<br>"
  elseIf(objASPError.Description > "") Then 
		 Response.Write Server.HTMLEncode(objASPError.Description) & 
"<br>" 
  end if

'/iis5samp/error1.asp, line 24
      Response.Write Server.HTMLEncode(objASPError.File)
      If objASPError.Line > 0 Then Response.Write ", line " & objASPError.Line
      If objASPError.Column > 0 Then Response.Write ", column " & objASPError.Column

首先由Set objASPError = Server.GetLastError取得错误资讯,接着由以下属性取得相关错误资讯,如下:

  •  objASPError.Category: 指示出错误来源为ASP、scripting language、或object ,譬如「Microsoft VBScript编译阶段错误」。
     
  •  objASPError.Number: 传回COM标准错误码,譬如「0x800A03FC」。
     
  •  objASPError.ASPDescription: 传回ASP详细错误原因描述,譬如「必须要有 'Next'」。
     
  •  objASPError.File: 传回错误程式档案名称,譬如「/iis5samp/error1.asp」。
     
  •  objASPError.Line: 传回ASP程式错误位置行数,譬如「24」。
     

您可以使用您自订的错误讯息 .asp档案来找出或显示错误。


说明

有关ASPError物件部份,请参阅附录B 〈快速学会ASP内建物件〉中 B-6〈如何使用ASPError物件呢?〉单元 。


2-4 ASP如何支援伺服器端Scriptlet呢?
 

ASP支援伺服器端Scriptlet(指令元件)新指令技术,您可以用VBScript或Jscript的语言(不需要使用Visual Basic、C++、或者Java语言来编写程式)编写Scriptlet,并储存成.sct副档名,注册元件成功後,即可当成COM元件(Component Object Model)般来呼叫使用。

Scriptlet可以从.asp档案或其他COM来呼叫,呼叫方式与呼叫一般COM元件相同。

如何编写Scriptlet呢 ? 首先使用 记事本 输入以下程式码,定义两个函数Add与Minus:

<SCRIPTLET>
<Registration Description="Scriptlet test" ProgID="test.scr1" Version="1.00">
</Registration>
<implements id=Automation type=Automation> <method name=Add>
		<PARAMETER name=A/>
		<PARAMETER name=B/>
	</method>
	<method name=Minus>
		<PARAMETER name=C/>
		<PARAMETER name=D/>
	</method>
</implements>
<SCRIPT LANGUAGE=VBScript> Function Add(A, B)
	  Add = A + B
  End Function
  Function Minus(C, D)
	  Minus = C - D
  End Function
</SCRIPT>
</SCRIPTLET>

接着将这个档案储存成.sct副档名,然後於 档案总管 中,在这个.sct档案上按下滑鼠右键并选取 注册 ,画面如下:


 

即可成功的注册为元件,画面如下:


 

注册成功後,asp程式如何呼叫此Scriptlet呢 ? asp程式使用Server.CreateObject("test.scr1")呼叫此Scriptlet後,即可使用所定义的两个函数Add与Minus。asp程式SCRIPTLET1.ASP如下:

<%
Set obj1 = Server.CreateObject("test.scr1")
Response.Write "<BR>3 + 5 = " & obj1.Add(3,5)
Response.Write "<BR>10 - 5 = " & obj1.Minus(10,5)
%>

执行SCRIPTLET1.ASP後之结果如下:


 

2-5 如何使用cookie取得浏览器资讯?
 

在以前的IIS版本,使用Browser Capabilities元件取得用户端浏览器的功能资讯,方法为当浏览器连线到IIS时会自动传送一个HTTP User Agent header,IIS收到後再与由其Browscap.ini对照表中找到此浏览器类型的详细资讯。

ASP程式使用Browser Capabilities元件之方法,譬如browsertype1.asp:

<%
Set obj1 = Server.CreateObject("MSWC.BrowserType") 
Response.Write "browser = " & obj1.browser  & "<BR>"
Response.Write "version = " & obj1.version  & "<BR>"
Response.Write "frames = " & obj1.frames  & "<BR>"
Response.Write "tables = " & obj1.tables  & "<BR>"
Response.Write "BackgroundSounds = " & obj1.BackgroundSounds  & "<BR>"
Response.Write "vbscript = " & obj1.vbscript & "<BR>"
Response.Write "javascript = " & obj1.javascript & "<BR>"
Response.Write "platform = " & obj1.platform  & "<BR>"
Response.Write "width = " & obj1.width  & "<BR>"
Response.Write "height = " & obj1.height  & "<BR>"
Response.Write "bufferDepth= " & obj1.bufferDepth  & "<BR>"
Response.Write "colorDepth = " & obj1.colorDepth  & "<BR>"
Response.Write "cookies = " & obj1.cookies  & "<BR>"
%>

使用浏览器执行browsertype1.asp之结果如下,显示浏览器详细资讯:


 

Browser Capabilities元件方法有些缺点,譬如Browscap.ini对照表可能为未更新,或使用者於用户端浏览器更改了设定时,用户端浏览器的功能资讯就可能抓错。

现在於IIS 5.0,多了一项新的判断浏览器功能方法,方法为使用cookie储存於浏览器所侦测到的资讯传回IIS後,透过Browser Capabilities元件得知cookie回报的浏览器资讯。

首先於ASP程式cookie1.asp加一行:

<!--METADATA TYPE="Cookie" NAME="BrowsCap" SRC="cookie1.htm"-->

告诉浏览器先使用cookie1.htm中的DHTML语法侦测浏览器的资讯,传回IIS後透过Browser Capabilities元件得知cookie回报的浏览器资讯:

<% Set obj1 = Server.CreateObject("MSWC.BrowserType") %>
<%
Response.Write "browser = " & obj1.browser  & "<BR>"
Response.Write "version = " & obj1.version  & "<BR>"
Response.Write "frames = " & obj1.frames  & "<BR>"
Response.Write "tables = " & obj1.tables  & "<BR>"
Response.Write "BackgroundSounds = " & obj1.BackgroundSounds  & "<BR>"
Response.Write "vbscript = " & obj1.vbscript & "<BR>"
Response.Write "javascript = " & obj1.javascript & "<BR>"
Response.Write "platform = " & obj1.platform  & "<BR>"
Response.Write "width = " & obj1.width  & "<BR>"
Response.Write "height = " & obj1.height  & "<BR>"
Response.Write "bufferDepth= " & obj1.bufferDepth  & "<BR>"
Response.Write "colorDepth = " & obj1.colorDepth  & "<BR>"
Response.Write "cookies = " & obj1.cookies  & "<BR>"
%>

cookie1.htm中的DHTML语法侦测浏览器的资讯,如下:

<Script Language="JavaScript">
function window.onload()
{
  body1.style.behavior = "url(#default#clientCaps)";
  bcString  =  "browse=" + body1.browser;
  bcString   +=  "&version=" + body1.version;
  bcString   +=  "&frames=" + body1.frames;
  bcString   +=  "&tables=" + body1.tables;
  bcString   +=  "&BackgroundSounds=" + body1.BackgroundSounds;
  bcString   +=  "&vbscript=" + body1.vbscript;
  bcString   +=  "&javascript=" + body1.javascript;
  bcString   +=  "&platform=" + body1.platform;
  bcString   +=  "&width=" + body1.width;
  bcString  +=  "&height="  + body1.height;
  bcString  +=  "&bufferDepth=" + body1.bufferDepth;
  bcString  +=  "&colorDepth=" + body1.colorDepth;
  bcString  +=  "&cookies=" + body1.cookieEnabled;
  document.cookie = "BrowsCap = " + bcString;
}
 </SCRIPT>
</HEAD>
<BODY ID="body1">
</BODY><HTML>

使用浏览器执行cookie1.asp之结果如下,显示浏览器详细资讯:


 

2-6 如何保护asp或html原始码呢?
 

Script Encoder编码保护
 

Script Encoder可以将Script原始程式指令码(如VBScript、JScript)加予编码成乱码,以保护asp或html的原始码被他人所偷窥,让原始程式码不易被使用者检视或修改。

Script Encoder程式编码工具screnc.exe,可以将浏览器端与伺服器端的指令加以编码,使原来的程式变成一堆无法阅读的乱码,执行时指令引擎会先自动进行解码,无须另外的程式。

Script Encoder程式编码工具只对script编码,不对HTML编码。

可编码的程式包括:

  • ASP(.asp .asa .cdx)
     
  • HTML(.html .htm)
     
  • WSH(.js .vbs .jse .vbe)
     
  • Scriptlet(.sct .wsh)
     

用法:

C:> screnc test.html encode.html

编码後结果变成一堆无法阅读的乱码:

<SCRIPT LANGUAGE=VBScript.Encode> 
#@~^cQIAAA==@#@&@#@&@#@&i?+DP1GxPxP;DnCD+r(%+1Y`r)
9rGAcZGxUn1YrW	E#@#@&7^Kxx 6a+UPr9~px1)
'hDK6'%l13wh4C2'WD9nDc:N(I9Db\Dx	/W	UR;
VGd@#@&@#@&nJ4AAA==^#~@   </SCRIPT>

譬如transfer1a.asp原始程式指令码:

<%  
Response.Write("A1(原呼叫程式)<BR>")
Server.Transfer "execute1b.asp"
Response.Write("A2(原呼叫程式)<BR>")
%>

使用screnc编码如下:

c:\iis5samp>screnc transfer1a.asp t.asp

编码後结果t.asp变成一堆无法阅读的乱码:

<%@ LANGUAGE = VBScript.Encode %>
<%#@~^dwAAAA==~,@#@&"+kwW	/ MkO+vJ)q,P`原呼叫程式
*@!A"@*J*@#@&?D7+.RP.mxd0.Pr+an1EYnq(RC/aE@#@&)/aWxk+c
	DbYn`rb+~,`原呼叫程式#@!$I@*J#@#@&PxwAAA==^#~@%>

详见网站 http://msdn.microsoft.com/scripting/ 。