Abstract:
The scripting engine interface provides the capability to interconnect any suitably written application or server with any scripting language. The implementation of the scripting engine itself (language, syntax, persistent format, execution model, and the like) is left entirely to the vendor, and the scripting engine need not come from the same vendor as the host application. The scripting engine interface implements this capability using a set of interfaces, the two most important ones being IActiveScriptSite (implemented by the host application) and IActiveScript (implemented by the language engine.) Together, these interfaces allow a host application to inform a scripting engine about the functionality that can be scripted and to define the scripts that the scripting engine should execute, either immediately or in response to user actions such as mouse clicks. The scripting engine interface redefines the handshake that is required between two specific types of software components in a manner not previously done. Unlike past scripting engine interfaces, which define a unique and proprietary way of hooking up to an application, the interface described here provides a universal hookup mechanism that is simple and direct.

Description:
FIELD OF THE INVENTION 
     This invention relates to a script engine interface that enables host applications to support disparate scripting languages from multiple sources and vendors, and that allows details of the script engines (language, syntax, persistent format, execution model, etc.) to be implemented independently of the host application. The interface also allows the host application to discover which script engines are available on the host machine. Thus any application can easily support any suitably implemented scripting language desired by the user. 
     PROBLEM 
     In the present software technology, there are two types of software components: scripting languages and applications. A user writes programs in a scripting language that automate functionality exposed by the host application. For example, a user might write a script in Visual Basic for Applications™ (VBA) to automatically create a chart using the graphics functions of Microsoft Excel. 
     However, under the current technology, each language engine is tightly coupled to a particular host application using proprietary interfaces that are different for every application. This means that users have no choice about which scripting engine to use with their application. They must use the language that was specifically designed for and included with the application, which is not necessarily the best language for their particular purposes. Similarly, scripting engine providers have a limited market for their products because they are unable to make their language engines interoperate with existing applications, due to the fact that the interfaces to those applications are proprietary, unpublished, and different for every application. 
     SOLUTION 
     The scripting engine interface of the present invention overcomes these problems and provides an advance in the art by introducing the capability to interconnect any suitably written application or server with any scripting language. The implementation of the script engine itself (language, syntax, persistent format, execution model, and the like) is left entirely to the vendor, and the script engine need not come from the same vendor as the host application. 
     The scripting engine interface design implements this capability using a set of interfaces, the two most important ones being IActiveScriptSite (implemented by the host application) and IActiveScript (implemented by the language engine.) 
     Together, these interfaces allow a host application to inform a script engine about the objects that can be scripted and to define the scripts that the engine should execute, either immediately or in response to user actions such as mouse clicks. 
     The scripting language engine interface redefines the handshake that is required between scripting engines and applications in a manner not previously done. Unlike past script engine interfaces, which define a unique and proprietary way of hooking up to an application, the interface described here provides a universal hookup mechanism that is simple and direct. This allows application vendors to design applications that can easily be scripted using any language desired by users, simply by exposing an object model for automation, supporting the interfaces to host script engines, and loading scripts into those engines. Similarly, language vendors can define language engines which will hook up to any suitably written application, without having to know the details of that application. Language vendors, application vendors, and end users all benefit from the increased choice and interoperability. 
    
    
     BRIEF DESCRIPTION OF THE DRAWING 
     FIG. 1 illustrates in block diagram form the operating environment and components which comprise the scripting language engine interface of the present invention; 
     FIG. 2 illustrates in block diagram form the relationships and interactions between the various scripting engine states; and 
     FIG. 3 illustrates in flow diagram form the actions and steps that the scripting engine takes during the various state transitions. 
    
    
     DETAILED DESCRIPTION 
     The scripting language engine interface provides the capability to add scripting and OLE Automation capabilities to programs such as applications or servers. The scripting language engine interface is embodied in the commercially available product known as Microsoft ActiveX™ Scripting (ActiveX Scripting), and enables host computers to call upon disparate scripting engines from multiple sources and vendors to perform scripting between software components. The implementation of the script itself: language, syntax, persistent format, execution model, and the like is left to the script vendor. Care has been taken to allow host computers that rely on ActiveX Scripting to use arbitrary language “back ends.” 
     Definitions 
     The following list contains definitions of the scripting-related terms used in this document. 
     
       
         
               
               
             
           
               
                   
               
               
                 Term 
                 Definition 
               
               
                   
               
             
             
               
                 Script 
                 The data that makes up the “program” that the 
               
               
                   
                 scripting engine runs. A script is any executable 
               
               
                   
                 code, including a piece of text, a block of pcode, 
               
               
                   
                 or even machine-specific executable byte codes. A 
               
               
                   
                 host computer loads a script into the scripting 
               
               
                   
                 engine through one of the IPersist* interfaces or 
               
               
                   
                 through the IActiveScriptParse interface. 
               
               
                 Script language 
                 The language in which a script is written (for example, 
               
               
                   
                 VBScript) and the semantics of that language. 
               
               
                 Scripting engine 
                 The object that processes scripts. A scripting engine 
               
               
                   
                 implements IActiveScript and, optionally, 
               
               
                   
                 IActiveScriptParse. 
               
               
                 Scripting host 
                 The application or program that owns the ActiveScript- 
               
               
                   
                 ing engine. The scripting host implements 
               
               
                   
                 IActiveScriptSite and, optionally, 
               
               
                   
                 IActiveScriptSiteWindow. 
               
               
                 Scriptlet 
                 A portion of a script that gets attached to an object 
               
               
                   
                 event through IActiveScriptParse. The aggregate 
               
               
                   
                 collection of scriptlets is the script. 
               
               
                 Code object 
                 An instance created by the scripting engine that is 
               
               
                   
                 associated with a named item, such as the module 
               
               
                   
                 behind a form in Visual Basic .. , or a C++ 
               
               
                   
                 class associated with a named item. 
               
               
                 Named item 
                 An object (preferably one that supports OLE Auto- 
               
               
                   
                 mation) that the host computer deems interesting to 
               
               
                   
                 the script. Examples include the HTML Document ob- 
               
               
                   
                 ject in a Web browser, and the Selection object in 
               
               
                   
                 Microsoft Word. 
               
               
                 Event 
                 A signal generated by a user action (such as clicking 
               
               
                   
                 a mouse) or by a software component (such as a 
               
               
                   
                 software clock with a “tick” event) which 
               
               
                   
                 causes associated scriptlets to run whenever the 
               
               
                   
                 event occurs. 
               
               
                   
               
             
          
         
       
     
     ActiveX Scripting Background 
     ActiveX Scripting components fall into two categories: ActiveX scripting hosts and ActiveX scripting engines. A scripting host computer creates a scripting engine and calls on the scripting engine to run the scripts. Examples of existing and potential ActiveX scripting hosts include: 
     Web browsers 
     Internet authoring tools 
     Servers 
     Office applications 
     Computer Games 
     ActiveX scripting engines can be developed for any language or run-time environment, including: 
     Microsoft Visual Basic for Applications (VBA) 
     Microsoft Visual Basic Scripting Edition (VBScript) 
     JScript 
     Perl 
     Lisp, Scheme 
     The ActiveX Scripting design isolates the interface elements required only in an authoring environment so that non-authoring host computers (such as browsers and viewers) and scripting engines (for example, VBScript) can be kept lightweight. 
     Basic Architecture 
     FIG. 1 illustrates in block diagram form the operating environment and components which comprise the scripting language engine interface of the present invention, and in particular the interaction between an ActiveX scripting host  105  and an ActiveX scripting engine  101 . This example includes the creation of a scripting engine  101  and the execution of a script input thereon. The following description details the steps involved in the interaction between the scripting host  105  and scripting engine  101  (the actual nesting of the function calls is omitted for clarity) and illustrates the flow of information between these components: 
     1. Create a Project. The scripting host  105  loads a project or document into its workspace from data storage  106  or a data communication interface (not shown) in well-known fashion. (This step is not particular to ActiveX Scripting, but is included here for completeness.) 
     2. Create the ActiveX Scripting Engine. The scripting host  105  calls the function CoCreateinstance to create a new ActiveX scripting engine  101 , specifying the class identifier (CLSID) of the specific scripting engine  101  to use. For example, the HTML browsing component of Internet Explorer receives the scripting engine&#39;s class identifier through the CLSID=attribute of the HTML &lt;OBJECT&gt; tag. The scripting host  105  can create multiple scripting engines for use by various applications, and the process of initiating a new scripting engine is well-known. 
     3. Load the Script. Once the new scripting engine  101  is created, if the script contents have been persisted, the scripting host  105  calls the scripting engine&#39;s IPersist*::Load method to feed it the script storage, stream, or property bag that is resident on the scripting host  105 . This exposes application&#39;s object model to the scripting engine  101 , by for example handing one or more application objects to the scripting engine  101 . Otherwise, the scripting host  105  uses IPersist*::InitNew or IActiveScriptParse::InitNew to create a null script. A scripting host  105  that maintains a script as text can use IActiveScriptParse::ParseScriptText to feed the scripting engine  101  the text of the script, after calling the function InitNew. 
     4. Add Items. For each top-level named item  103  (such as pages and forms) imported into the scripting engine&#39;s name space  102 , the scripting host  105  calls IActiveScript::AddNamedItem to create an entry in the scripting engine&#39;s name space  102 . This step is not necessary if top-level named items  103  are already part of the persistent state of the script loaded in step 3. A scripting host  105  does not use AddNameditem to add sublevel named items (such as controls on an HTML page); rather, the scripting engine  101  indirectly obtains sublevel items from top-level items by using the host&#39;s ITypeInfo and IDispatch interfaces. 
     5. Run the Script. The scripting host  105  causes the scripting engine  101  to start running the script by passing the SCRIPTSTATE_CONNECTED value to IActiveScript::SetScriptState. This call would likely perform any scripting engine construction work, including static bindings, hooking up to events (see below), and executing code similar to a scripted “main( )” function. 
     6. Get Item Information. Each time the scripting engine  101  needs to associate a symbol with a top-level item, it calls the IActiveScriptSite::GetItemInfo method, which returns information about the given item. 
     7. Hook Up Events. Before starting the actual script, the scripting engine  101  connects to the events of all the relevant objects through the 
     IConnectionPoint interface and other methods. As shown in FIG. 1, the IConnectionPoint::Advise(pHandler) message provides the scripting host  105  with a request for notification of any events that occur in the scripting host  105 . The message passes an object pHandler that the OAServer can call when an event occurs in the scripting host  105 . Once an event occurs in the scripting host  105 , the scripting host  105  transmits a message to the scripting engine  101  pdispHandler::Invoke(dispid) to notify the scripting engine  101  that an event occurred in the scripting host  105 . If the event matches a monitored event in the scripting engine  101 , the scripting engine  101  can activate a response, such as executing user written code. 
     8. Invoke Properties and Methods. As the script runs, the scripting engine  101  realizes references to methods and properties on named objects through IDispatch::Invoke or other standard OLE binding mechanisms. 
     Additional implementation details of ActiveX Scripting are disclosed herein as well as in Appendix A attached hereto, which document describes ActiveX Scripting Interfaces and Methods. 
     Basically, the user exposes internal objects of the application via OLE Automation and the resultant OLE Automation object is an entity which exposes properties and methods of the application. A method is an action which the object can perform, while a property is an attribute of the object, like a variable. The OLE Automation Interfaces include IDispatch which is an interface to manipulate OLE Automation objects. This process is used to get a property, set a property, or call a method. The process uses “late binding” mechanism that enables a simple, interpreted language. Type information in the OLE Automation includes ITypeinfo which is used for describing an object. A collection of these TypeInfos constitutes a type library, which usually exists on a disk in the form of a data file. The data file can be accessed through ITypeLib and is typically created using MKTypLib. In ActiveX scripting, the type information is provided by scripting hosts and objects that are used by the scripting hosts. The type information is then used by the scripting engines. 
     Active Scripting Engine 
     To write an Active Scripting engine, the user writes an OLE Component Object Model object that supports the following interfaces: 
     
       
         
               
               
               
             
           
               
                   
               
               
                 Interface 
                 Required? 
                 Description 
               
               
                   
               
             
             
               
                 IActiveScript 
                 Yes 
                 Basic scripting ability. 
               
               
                 IPersist* 
                 Yes-one of 
                 Persistence support. 
               
               
                   
                 the following: 
               
               
                 IPersistStorage 
                   
                 DATA={url} syntax for OBJECT 
               
               
                   
                   
                 tag. 
               
               
                 IPersistStreamInit 
                 . 
                 Same as above, as well as DATA= 
               
               
                   
                   
                 “string-encoded byte stream” 
               
               
                   
                   
                 syntax for OBJECT tag. 
               
               
                 IPersistPropertyBag 
                 . 
                 PARAM= syntax for OBJECT tag. 
               
               
                 IActiveScriptParse 
                 No 
                 Ability to add script text, evaluate 
               
               
                   
                   
                 expressions, and the like. 
               
               
                   
               
             
          
         
       
     
     Support for the IActiveScriptParse interface is optional. However, if the IActiveScriptParse interface is not supported, the script engine  101  must implement one of the IPersist* interfaces in order to load a given script. 
     Certain interpreted script languages (for example, VBScript) running in specific scripting host environments (for example, Internet Explorer) may rarely (or never) be called upon to save or restore a script state through IPersist*. Instead, IActiveScriptParse is used by calling IActiveScriptParse::InitNew to create a blank script, then scriptlets are added and connected to events with the function IActiveScriptParse::AddScriptlet and general code is added via IActiveScriptParse::ParseScriptText. Nonetheless, a scripting engine  101  should fully implement at least one IPersist* scheme (preferably IPersistStreamInit), because other scripting host applications may try to make use of them. 
     Registry Standard 
     An ActiveX scripting engine can identify itself as such using component categories. The ActiveX Scripting program currently defines two component 
     
       
         
               
               
             
           
               
                   
               
               
                 Category 
                 Description 
               
               
                   
               
             
             
               
                 CATID_ActiveSport 
                 Indicates that the class identifiers (CLSIDs) 
               
               
                   
                 are ActiveX scripting engines that support, at 
               
               
                   
                 a minimum, IactiveScript and a persistence 
               
               
                   
                 mechanism, such as IpersistStorage, IPersist- 
               
               
                   
                 StreamInit, or IPersistPropertyBag. 
               
               
                 CATID_ActiveScriptParse 
                 Indicates that the CLSIDs are ActiveX 
               
               
                   
                 scripting engines that support, at a 
               
               
                   
                 minimum, IActiveScript and IActiveScript- 
               
               
                   
                 Parse. 
               
               
                   
               
             
          
         
       
     
     Although IActiveScriptParse is not a true persistence mechanism, it does support an InitNew method that is functionally equivalent to IPersist*::InitNew. 
     Script Engine States 
     At any given time, an ActiveX scripting engine can be in one of several states, as noted in the following: 
     
       
         
               
               
             
           
               
                   
               
               
                 State 
                 Description 
               
               
                   
               
             
             
               
                 Uninitialized 
                 The script has not been initialized or loaded using an 
               
               
                   
                 IPersist* interface, or does not have an IActiveScriptSite 
               
               
                   
                 set. The scripting engine is generally not usable from this 
               
               
                   
                 state until the scripting host takes steps to initialize 
               
               
                   
                 the scripting engine. 
               
               
                 Initialized 
                 The script has been initialized with an IPersist* interface 
               
               
                   
                 and has an IActiveScriptSite set, but is not connected 
               
               
                   
                 to host objects and sinking events. Note that this 
               
               
                   
                 state simply means that Ipersist*::Load, 
               
               
                   
                 IPersist*::InitNew, or IactiveScriptParse::InitNew 
               
               
                   
                 has been completed, and IActiveScript::SetScriptSite 
               
               
                   
                 has been called. The scripting engine cannot run code 
               
               
                   
                 in this mode. The scripting engine queues code that 
               
               
                   
                 the scripting host passes to it through the function 
               
               
                   
                 IActiveScriptParse::ParseScriptText, and executes the 
               
               
                   
                 code after transitioning to the started state. 
               
               
                 Started 
                 The transition from the initialized state to started state 
               
               
                   
                 causes the scripting engine to execute any code that 
               
               
                   
                 was queued in the initialized state. The scripting 
               
               
                   
                 engine can execute code while in the started state, 
               
               
                   
                 but it is not connected to events of the objects added 
               
               
                   
                 through IActiveScript::AddNamedItem. The scripting 
               
               
                   
                 engine can execute code by calling the IDispatch 
               
               
                   
                 interface which is obtained from the function 
               
               
                   
                 IActiveScript::GetScriptDispatch, or by calling the 
               
               
                   
                 function IActiveScriptParse::ParseScriptText. It is 
               
               
                   
                 possible that further background initialization 
               
               
                   
                 (progressive loading) is still ongoing, and that calling 
               
               
                   
                 SetScriptState with the SCRIPTSTATE_CONNECTED 
               
               
                   
                 value may cause the script to block until initialization 
               
               
                   
                 is complete. 
               
               
                 Connected 
                 The script is loaded and connected for sinking events 
               
               
                   
                 from scripting host objects. 
               
               
                 Disconnected 
                 The script is loaded and has a run-time state, but 
               
               
                   
                 is temporarily disconnected from sinking events from 
               
               
                   
                 scripting host objects. This state is distinguished from 
               
               
                   
                 the initialized state in that the transition to this 
               
               
                   
                 state does not cause the script to reset, the run-time 
               
               
                   
                 state of the script is not reset, and a script initializ- 
               
               
                   
                 ation procedure is not executed. 
               
               
                 Closed 
                 The script has been closed. The scripting engine no 
               
               
                   
                 longer works and returns errors for most methods. 
               
               
                   
               
             
          
         
       
     
     The functions of these states and their interrelationship is disclosed in the following description of FIGS. 2 and 3. FIG. 2 illustrates in block diagram form the relationships and interactions between the various scripting engine states. FIG. 3 illustrates in flow diagram form the actions and steps that the scripting engine takes during the various state transitions. 
     At step  301  in FIG. 3, the scripting engine instance  101  is created by the scripting host  105  and reserved for future use via execution path  1  in FIG. 2 where the scripting engine  101  is placed in the uninitialized state. The  10  scripting engine  101  executes the functions passed at item  1  in FIG.  2 : 
     GO Create Instance ( ) 
     IActiveScript::Clone ( ) 
     to enter the initialized state. The scripting host  105  at step  302  loads data into the scripting engine  101  from data storage or initializes the scripting engine  101  to accept scriptlets. At step  303 , the scripting engine  101  runs the function “Main( )”, to enter the started state where the scripting engine  101  proceeds to hook up events at step  304  in the connected state. Once the events are hooked up, the scripting engine  101  reenters the initialized state at step  305  to destroy the run time state and unhook the events at step  306 . The scripting engine  101  in this process executes the functions passed at item  2  in FIG.  2 : 
     IPersist*::Load( ) or 
     IPersist*::InitNew( ) or 
     IActiveScriptParse::IniNew( ) and 
     IActiveScript::SetScriptSite( ) 
     The scripting engine  101  is now in the disconnected state and at step  307  begins the execution of its defined function by rehooking events and executing the defined function. The scripting engine  101  receives, interprets and executes the code that is passed to it by the scripting host  105 , in response to script input in the application. The functions that are passed in item  3  of FIG.  2  and executed in this step comprise: 
     IActiveScript::SetScriptState( ) 
     The scripting engine  101  at step  308  completes the execution of the received code and executes the function passed at item  4  in FIG.  2 : 
     IActiveScript: :Close( ) 
     The scripting engine  101  at step  308  destroys the run time state and at step  309  unhooks events, releases all held interface pointers and frees the allocated resources. At step  310 , the scripting engine  101  is released and ceases operation until it is again activated by the scripting host  105 . The final function executed by the script engine  101  and passed on path  5  in FIG. 2 to the scripting host  105  at this step is: 
     Release( ). 
     This completes the creation and operation of the scripting engine  101 .