[[[note: This is a work in progress. I will update it as I have pieces completed. It is made visible in case the information is useful to anyone.]]]
Using an external source for script functions is a useful and time saving device for scripters. I though I might take some time to share a couple of methods for accomplishing this.
There area basically four different ways to include scripts at runtime.
- Injecting a script into the memory of the currently executing script.
- WSF file using <script src="pathname"> tag
- WSF file using included global <script> section and injecting it into the memory of the executing job.
- Creating a WSC (Windows Script Component) that contains the function library.
I will describe each of these and provide a simple example along with any known caveats.
III. WSF File using <script> tag.
One of the advantages of using a WSF file to hold your scripts is that it can also contain a common script library or libraries which can be written in multiple scripting languages. This will allow things like calling jscript functiosn from vbscript and the reverse. A WSF file is XMLfile containing as a set of "JOB" sections that can be run independently from a switch "//Job:<jobname>". The WSF file can contain multiple "<script> blocks.
Let's look at the script tag more closely.
<script id="myscript" language="vbscript">
Function MyFunc1( arg1, arg2 ) End Function
Function MyFunc2( argx, argy, argz ) End Function
</script>
As you can see we can define a "language" attribute which can be set to any scripting language available on you machine. Normally we will use either "vbscript" or "jscript" These are the two default scripting languages installed on Windows.
This is basically the same as declaring a script block in an HTML page. To make it useful in a WSF file we also have to add a way to find the script block. This is done by addin an "ID" attribute. Here we have set the ID to "myscript"
To load this script library into memory we need to use a helper function which can read code from a file and load it into memory in an executable fashion. We will do this with the following function.
Function LoadThisLibrary(strXPATHQuery) Dim xml,fso,strXML
' open file and read it inot a stream Setfso = CreateObject("Scripting.FileSystemObject") Setfs = fso.OpenTextFile(WScript.ScriptFullName) strXML = fs.ReadAll
' create XML DOM and load stream then query for library script Setxml = CreateObject("MSXML2.DOMDocument") xml.loadXML strXML xml.setProperty "SelectionLanguage", "XPath" strScript = xml.selectNodes(strXPATHQuery).item(0).nodeTypedValue
' execute string to load it into memory ExecuteGlobal strScript
End Function
This function takes as an argument an "XPATH" query and uses it to retrieve a specific node in an XML document. Since our WSF file is an XML document we can use this XPATH query to retrieve the contents of our <script> section by using it's ID. The XPATH will look something like this:
child::package/job/script[attribute::id='myscript'
This says that we want to find the "child" of the guy whose ID at the specified path is 'myscript'. The child of the attribute is the contents of the script tag which is our script library.
We do this by loading the current file into a file system object stream using the WScript.ScriptFullName value which is the full pathname of the current WSF file. After loading the stream object we create an XMLDomDocument object and load the stream into the XMLDOM. From here we can select the script by using the XPATHQuery above. Once we have the script loaded into a string "strScript" we can use WScripts "ExecuteGlobal" method to compile this script into memory. Now all of the functions in the script will be callable from the current JOB.
In the next installment I will cover the other structures of the WSF file format that will help to guarantee that this will work reliably. Be patient. When I am done it will be much easier to use this but we need to be sure that you understand how and where it can break. A few more steps will make this clear and yo will be able to quickly wrap related groups of your functions in a WSF <script> wrapper and make them callable from any JOB in the WSF file.
No comments:
Post a Comment