Part 1 of 2:
If I had to list the two most important tasks that a developer will face when creating an initial Active Scripting host, I'd include creating/initializing the script engine to begin processing script text and interrupting/terminating a running host. This month, we'll begin a 2-part series by taking a longer look at the latter task.
Scanning through the set of methods that are available on the core Active Scripting interface IActiveScript, you will come across the method InterruptScriptThread. This method takes a set of parameters including the script thread id, a pointer to an exception block, and a set of flags.
The script thread id is a DWORD value that indicates to the engine which thread to interrupt -- currently it may be one of the following values: SCRIPTTHREADID_ALL, SCRIPTTHREADID_BASE, SCRIPTTHREADID_CURRENT. Since InterruptScriptThread is one of the few IActiveScript methods that can be called from a thread other than the one that created the engine (actually, the one that called IActiveScript::SetScriptSite but usually the same one as the creator) it's critical to be able to specify which thread to interrupt. Typically, the SCRIPTTHREADID_ALL value is used when the you don't know which thread you're calling from and just want the engine to stop. The other values are for more finely tuned situations where you may only wish to stop the engine if it's running on a thread that needs to stop or suspend the script to update some other context within the application.
The exception block is an [in] value of type EXCEPINFO (actually, it should have been an [out] value instead and the last parameter of the method, but whatever....) This structure is pretty straightforward to use and contains basic information about what happened, where, etc. However, it does have one annoyance -- you must free any BSTR's yourself contained with the block using SysFreeString even though you didn't create them. Otherwise, you'll suffer memory leakage. The simplest fix for this in C++ is to create a class (something like CExcepInfo would do nicely) and derive in publicly from the structure EXCEPINFO. In the destructor, check for non-null pointers and free the corresponding BSTR values as need be. Then use this class anywhere you might have used EXCEPINFO.
The set of flags allows for more fine tuning of how the interruption will be handled by the engine. Typically, a value of 0 is passed to InterruptScriptThread rather than one of the other supported values -- SCRIPTINTERRUPTDEBUG and SCRIPTINTERRUPT_RAISEEXCEPTION. The value of 0 simply indicates no flag is being passed (in essence, the default). The SCRIPTINTERRUPT_DEBUG value is used where the host might want the script debugger (possibly the host itself) to be invoked. The SCRIPTINTERRUPT_RAISEEXCEPTION value is used when the host wants the script code itself to handle the interruption as an exception.
With this much information, most developers would implement support for interrupting a script using InterruptScriptThread in their applications, and move on. However, sometimes this active mechanism doesn't really fit into the design of an application. It's similar to what happens in a GUI application that needs to update menu items based on changes in state -- you can either update them as state changes, or wait until the menu needs to know the current state and update them at that time. The former is active updating while the latter is passive updating. In the same way as updating menu item states, the Active Scripting API provides for active and passive interruption.
Next month, we'll take a look at a little known (and documented) but fully supported Active Scripting interface to enable passive interruption of scripts.
Do you have a passion for Scripting?
If you want to access the extensive exchanges between other developers about Active Scripting, head over to Google's archive of Usenet newsgroups and read through the microsoft.public.scripting.hosting group. If you're working with the newer .NET version of scripting, you might look through microsoft.public.dotnet.scripting.
Also, if you have questions about how to use Active Scripting, I'd encourage you to read through my Active Scripting FAQ document that covers a wide range of problems other developers have had and many useful answers from their experiences. You can find it here.
Finally, a rich source of material on Active Scripting, JScript and VBScript from a true Microsoft insider is Eric Lippert's blog.
Looking for back issues of the Active Scripting newsletter?
Head over to the Dr. Dobb's Journal site to read any of the back issues on-line. The Active Scripting newsletter has now been in publication for over 4 years and you will find a wealth of information, commentary and insight that will make using and understanding Active Scripting easier and more productive.
I hope you find this newsletter a timely and helpful addition to your knowledge base about Active Scripting. Please feel free to email me at [email protected] and let me know what you think of it, ways to improve on content, and how this newsletter is helping you.
Until next month...