程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> Visual Basic語言 >> VB綜合教程 >> 在VB編程中采用Windows腳本控件實現程序腳本化

在VB編程中采用Windows腳本控件實現程序腳本化

編輯:VB綜合教程
電子郵件腳本病毒在網絡上泛濫成災之後,作為腳本缺陷的始作俑者,WSH(Windows腳本主機)受到了廣泛和強烈的抨擊,不過,對應用程序開發人員而言,WSH仍然具備相當大的潛質和開發魅力。是的,腳本技術完全可能取代網絡管理員對批處理文件的依賴,更時髦的腳本相信對那些“真正”的開發人員仍具相當的實用性。
  
  比方說,你知道微軟的Office套件如此流行的原因嗎?其中之一就是所有的Office應用程序都包括了了簡單的開發環境,稍有技術的用戶都可以由此實現重復任務的自動化。VBA(VisualBasicforApplications)就為Office軟件提供了這種環境,而且,如果你能承擔微軟要求的許可證費用,你還可以在你自己的應用程序中使用VBA。現在,我們再來看看WSH和WindowsScriptControl,它們是對VBA廉價而且相當有用的替代選擇。為VisualBasic應用程序提供了自動的腳本化技術。
  
  掌握腳本控件
  WindowsScriptControl把ActiveScriptingEngine封裝在了非用戶界面的ActiveX控件之內以方便VB編程的使用,而ActiveScriptingEngine正是WSH的核心。程序員可以利用該控件執行整個腳本或者腳本的片段,而這些腳本可以用WSH所支持的任何語言編寫。也許你的計算機上已經安裝了這種控件;它的名字是msscript.ocx,通常位於System32目錄下。否則你可以從微軟網站下載
  
  WindowsScriptControl控件還包括了一些文檔,但照我的經驗看,這些文檔有點不完整而且不太准確。掌握控件用法的最好方法就是具體應用它,通過具體應用了解其工作原理和用途。我自己就是這麼做的,先創建了一個測試項目,用它來了解腳本控件的可能現象和用途,你可以從這裡下載測試項目。這篇文章中會反復用到該測試項目。
  
  運行腳本
  為了運行用到腳本控件的腳本,你有以下若干選擇:
  
  Eval方法,它同VBAEval函數類似,從簡單算術到包含嵌入腳本的命令或對象方法調用的復雜表達式都可以計算,而且會把結果返回給你的應用程序。
  ExecuteStatement方法執行任何完整的腳本語句。
  聯合運用AddCode和Run方法可以裝載並執行定制的腳本程序。這也是功能性最強大的方法,同時也是本文余下部分要討論的方法。
  ScriptingDemo簡介
  ScriptingDemo應用程序由一個窗體、兩個文本框組成,窗體顯示應用程序所在目錄下的腳本文件列表,一個文本框獲取腳本程序所需要的參數,另一個文本框顯示執行腳本的輸出結果。在應用程序啟動的時候,它實例化一個定制集合對象colCustomers,通過它從SQLServer的Northwind目錄的Customers數據表裝載數據供我們的示例腳本操作數據。應用程序在運行時顯示的主窗體如圖A所示。
  
  圖A
  
  
  運行時的ScriptingDemo主窗體
  
  
  在選擇了一個腳本之間之後,應用軟件逐行讀取腳本代碼並通過AddCode方法把它加到腳本控件的環境內。單擊RunScript按鈕之後腳本控件就會執行所選文件同名(不帶擴展名)的程序。
  
  以ASimpleScript.vbs為例。它包含以下的子程序:
  SubASimpleScript()
  MsgBox"HellofromVBScript!"
  EndSub
  
  選擇該文件,然後單擊RunScript按鈕即產生圖B所示的輸出結果。
  
  圖B
  
  運行ASimpleScript.vbs之後的結果
  
  對,我承認這個程序太簡單了,但它確實說明你在運行腳本,除此以外,我們還需要深入控件內部探個究竟。
  
  同腳本共享數據
  現在讓我們更深入一步,看看隱藏在窗體Load事件(清單A)之後的代碼,代碼中有以下兩行:
  
  ScriptControl1.AddObject"Customers",oCustomers,True
  ScriptControl1.AddObject"Output",oScriptOutput,True
   
->清單A->->frmMain'sLoadevent
  PrivateSubForm_Load()
  DimstrDirAsString'Directorycontents
  DimoCustomersAsNewcolCustomers'playcollection
  DimoScriptOutputAsNewOutput'Outputobjectforscript
  
  'Getalistofallvbsscriptfilesintheappdirectory
  strDir=Dir(App.Path&"*.vbs")
  DoUntilstrDir=""
  Me.List1.AddItemstrDir
  strDir=Dir()
  Loop
  
  'setupourscripts'playenvironment.
  SetoScriptOutput.OutputBox=Me.txtOutput
  'LoadDataacceptsaDSNname,auseridandapassword
  oCustomers.LoadData"SQLServer","sa",""
  'Maketheseobjectsavailabletoscriptsrunwiththe
  'scriptcontrol.
  ScriptControl1.AddObject"Customers",oCustomers,True
  ScriptControl1.AddObject"Output",oScriptOutput,True
  
  EndSub->


  我們還沒有談論過AddObject。該方法把對對象的引用加到腳本控件的執行環境。用這種方式添加的對象可以受到控件所運行的所有腳本的全局訪問,從而令腳本獲得了訪問應用程序所創建的對象的權限。同時這也是一種和應用程序通訊的方式。在這種情況下,我們就為主窗體裝載Customers時創建的數據操作集合添加了引用,同時也對Output類如法炮制,它則給腳本賦予了對主窗體上的txtOutput只寫的訪問權限。

查看EnumCustomer腳本的代碼可以從中了解這種方法的有用性,該腳本代碼請見(清單B)。該腳本獲取單個輸入參數,該參數表示Customers集合內包含的客戶索引,而該集合則是我們通過調用AddObject添加到腳本控件環境的。EnumCustomer腳本訪問Customers集合並枚舉出所選項目的所有可用字段,然後通過Output對象的txtOutput打印出結果。
   

-width="100">清單B->-width="100">EnumCustomerscript
  SubEnumCustomer(num)
  Output.PrintLine("ID:"&Customers(num).CustomerId)
  Output.PrintLine("CompanyName:"&Customers(num).CompanyName)
  Output.PrintLine("ContactName:"&Customers(num).ContactName)
  Output.PrintLine("Address:"&Customers(num).Address)
  Output.PrintLine("City:"&Customers(num).City)
  Output.PrintLine("PostalCode:"&Customers(num).PostalCode)
  Output.PrintLine("Country:"&Customers(num).Country)
  Output.PrintLine("Phone:"&Customers(num).Phone)
  Output.PrintLine("Fax:"&Customers(num).Fax)
  EndSub->


  有利就有弊
  現在你的頭腦裡可能產生了這樣一個問題:為什麼要把txtOutput封裝在類裡而不是經由AddObject為frmMain.txtOutput增加引用呢?UpdateCustomer.vbs的代碼給出了答案:
  SubUpdateCustomer(num)
  Output.PrintLine("Changing")
  Output.PrintLine(Customers(num).ContactName)
  Output.PrintLine("toBobHope")
  
  Customers(num).ContactName="BobHope"
  EndSub
  
  這個腳本修改了Customers集合中一個項目的內容,意味著腳本對經由AddObject被加到它們環境中的對象進行了讀寫操作。假如我允許有害腳本自由訪問txtOutput的話它不也可以做同樣的事嗎:
  
  txtOutput.Visible=False
  
  當後續運行的腳本試圖經由txtOutput與用戶通訊時,這一行為就會出漏子了。雖然我無法創建成功改變全局對象實際引用的腳本(全局對象是通過AddObject增加的,比如Customers=Nothing),但是我也得承認這種行為也不是不可能的。因此,在訪問腳本的時候就存在一個道德問題了。
  
  用途廣泛
  腳本化的應用程序在最終用戶定制和自動化領域具有顯然的巨大作用。比方說,用腳本臨時修補程序等。而且在某些應用程序事件發生的情況下可以運行腳本行使鉤子功能。這樣,你就可以通過簡單地分派腳本糾正應用程序的錯誤而不是分派更新的二進制代碼。定制報告和數據分析也能從中得益。->

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved