Implementing Sinks with Scripting Languages

Implementing Sinks with Scripting Languages

Microsoft® Collaboration Data Objects (CDO) provides transport event scripting hosts that enable you to implement sinks using a scripting language. The following steps outline this process:

  1. Write the script code that implements the appropriate event. The VBScript subroutines and Microsoft® JScript® functions that implement the events are listed in the following section. When using VBScript, you can place all the event method implementations within a single file. When using JScript, you must use a separate file for each event.
  2. Register the appropriate CDO event-scripting host as the event sink. The scripting host in turn dispatches the event method invocation to the scripting engine that is running your script code.
  3. In the Sink property bag, set the ScriptName property so that the binding points to the location of the file containing the script you wrote in Step 1. The CDO scripting host will execute the appropriate subroutine or function contained in the script when the event occurs.

Visual Basic, Scripting Edition (VBScript)

The Microsoft® Visual Basic®, Scripting Edition (VBScript) scripting engine uses the convention interface + "_" + method to denote implementation of a particular interface method. The code that follows lists the VBScript subroutines used to handle the ISMTPOnArrival.OnArrival, INNTPOnPostEarly.OnPostEarly, INNTPOnPost.OnPost, and INNTPOnPostFinal.OnPostFinal event methods. You can cut and paste these definitions into your script file if desired. Use the <SCRIPT LANGUAGE="VBScript"></SCRIPT> tags around all of your script code to identify it as VBScript code:

<SCRIPT LANGUAGE="VBScript">
Sub ISMTPOnArrival_OnArrival( ByVal Msg, Status)
  ' sink code here
End Sub

Sub INNTPOnPostEarly_OnPostEarly( ByVal Msg, Status)
  ' sink code here
End Sub

Sub INNTPOnPost_OnPost(ByVal Msg, Status)
  ' sink code here
End Sub

Sub INNTPOnPostFinal_OnPostFinal(ByVal Msg, Status)

End Sub
</SCRIPT>

JScript

The Microsoft JScript scripting engine uses the convention interface + "::" + method to denote implementation of a particular interface method. The code that follows lists the JScript functions used to handle the ISMTPOnArrival.OnArrival, INNTPOnPostEarly.OnPostEarly, INNTPOnPost.OnPost, and INNTPOnPostFinal.OnPostFinal event methods. When implementing the sink code in JScript, use the <SCRIPT LANGUAGE="JScript"></SCRIPT> tags around your script code as shown below. You must use a separate file for each of the four events. Unlike the VBScript engine, you cannot place implementations for more that one method within a single file.

<SCRIPT LANGUAGE="JScript">
function ISMTPOnArrival::OnArrival( Msg, Status) {
  // sink code here
}

function INNTPOnPostEarly::OnPostEarly( Msg, Status) {
  // sink code here
}

function INNTPOnPost::OnPost( Msg, Status) {
  // sink code here
}

function INNTPOnPostFinal::OnPostFinal( Msg, Status) {
  // sink code here
}
</SCRIPT>

Note   The Microsoft JScript syntax is case-sensitive, so all methods and properties on CDO interfaces must have the correct case.

Additionally, you cannot nest <SCRIPT> tags within the file, nor can the strings <SCRIPT> or </SCRIPT> appear anywhere within the script code. If you need to generate output text within the script code that contains these tags (for example, to generate HTML) you will need to do one of two things:

  • Use a variable to assemble this string at runtime:

    var strLt = "<";
    var strGt = ">";
    var strTag = "SCRIPT"
    var strHTML += strLt + strTag + strGt
    
  • Store the script code in an external file and access it at runtime.

Calling routines in one scripting language from another

You can call routines contained in one scripting language from another scripting language. When you want to invoke a function in a script block that is written in another scripting language, you can use a named, or intrinsic, object provided by the scripting host. If you have code written in VBScript and code written in JScript, the scripting host adds an intrinsic, named object called JScript into the VBScript scripting namespace. VBScript code can then invoke JScript routines by invoking the function through this intrinsic object. Similarly for JScript, if VBScript code is in the file, the scripting host inserts an intrinsic object called VBScript in the JScript scripting namespace. (Note that JScript is case-sensitive.) You can use this object to invoke routines in the VBScript portion of the file. For example:

<SCRIPT LANGUAGE="VBScript">
  Sub ISMTPOnArrival_OnArrival(ByVal Msg, Status)
    ...
    ' call a routine in JScript block
    JScript.UtilityFunctionInJScript Msg
  End Sub

  Sub UtilityFunctionInVBScript(Msg)
    ' utility code here
  End Sub
</SCRIPT>
<SCRIPT LANGUAGE="JScript">
function UtilityFunctionInJScript(Msg, Status) {
   // do something and then call a VBScript Utility function here
   VBScript.UtilityFunctionInVBScript(Msg);
   // JavaScript is case-sensitive! Use VBScript with case preserved
   ..
}

function INNTPOnPostEarly::OnPostEarly(Msg, Status) {
   // OnPostEarly code here
   // Note that the VBScript block sinks the OnArrival event
   // and JScript is used to sink the OnPostEarly event.
}
</SCRIPT>

Note that a single script file can contain event-handling code for all supported SMTP and NNTP events when using VBScript, but not with JScript. When using this method with VBScript, you must still register the appropriate CDO event scripting host for each event, but the ScriptName property in each sink binding's Sink property bag can point to the same file. When using JScript, each event binding must point to a separate file that provides the implementation of only that event. If more than one event method implementation exists within the file, a runtime exception will be raised.

For improved performance, the event dispatcher caches the CDO scripting event sink and all scripting engines that are loaded (including script code that is parsed and loaded). However, each time the scripting engine is about to run, the script file timestamp on the file system is checked. If the script timestamp is later than the last loaded script file, then the new script is automatically reloaded into the appropriate engine. This way, you do not have to stop and restart the Microsoft® Internet Information Services (inetinfo.exe) to reload the event handling script file.

See Also

Concepts

Registering Script Sink Bindings