Tuesday, January 6, 2009

Script Code: Talking Between Languages

This post is really about requesting data from one (scripting) language using another (scripting language).  In this case between KiXtart and Windows Scripting Host (VBscript).  It's easy to execute a script file from one language using a script file in another language, it usually involves some sort of shell operation or forked process.  But it's a bit different to make a more direct interface and pass information between them.

There are limitations, and a caveat or two, but it can be done, and it can be quite useful at times. I was reminded of a rather peculiar, yet talented, programmer I knew in the early 90's. He wrote some clever C++ code that wrote its own extensions, at runtime, and even compiled and ran them based on runtime condition logic. Often in multiple languages too (in this case: LISP, Scheme and ANSI-C).  Very elegant coding.  Amazing stuff.  Good times.

First, let's fetch some environment information from KiXtart using VBscript. The caveat here is that you need to register the kixtart.dll library before this will work. This DLL is included with the free KiXtart download ZIP file. To register kixtart.dll, use the familiar "regsvr32 \kixtart.dll" method.

        Function FormatDateTime($strDate, $format)
                $sc = CreateObject("ScriptControl")
                $sc.Language = "vbscript"
                $result$sc.Eval("FormatDateTime(" Chr(34) + $strDate Chr(34) + "," $format ")")
                $sc = 0
                $FormatDateTime = $result
        EndFunction
       
        $testvalue = '2009/10/03 12:34:56'
       
        $test1 = FormatDateTime($testvalue, 'vbShortDate')
        $test2 = FormatDateTime($testvalue, 'vbLongDate')
        $test3 = FormatDateTime($testvalue, 'vbLongTime')
       
        ? "shortdate: $test1"
        ? "longdate: $test2"
        ? "longtime: $test3"

KiXtart only exposes macros, not commands or functions. This is still useful in some cases. I'm still trying to find a way to address this limitation, which may indeed be possible (and just that I'm not seeing the answer to the riddle).

On the other side, let's leverage a VBscipt function from within KiXtart. Going in this direction you get a little more flexibility because of the Eval function in VBscript.

        On Error Resume Next
        Set objKiX = CreateObject("KiXtart.Application")
        If err.Number = 0 Then
                Wscript.Echo "Processor: " & vbTab & Trim(objKiX.CPU)
                Wscript.Echo "UserName: "vbTab &  objKiX.UserId
                Wscript.Echo "Domain: "vbTab &  objKiX.LDomain
                Wscript.Echo "MAC id: "vbTab &  objKiX.Address
                Wscript.Echo "Privilege: "vbTab & objKiX.Priv
                Wscript.Echo "Password Age: "vbTab & objKiX.PwAge
                Wscript.Echo "ProductType: "vbTab & objKiX.ProductType
                Set objKiX = Nothing

        Else
                Wscript.Echo "kixtart.dll has not been registered"
        End If

This can help shorten the script by making use of VBscript features which aren't available in KiXtart unless you employ additional code or UDF additions. Nothing wrong with that though. This just another option. The caveat here is with the type of information returned back. Strings and numbers are one thing. Arrays, Dictionaries and Objects are little different, as you might expect.

Don't forget that you can also execute JavaScript and ActivePerl code this way. Try this out yourself and see what kind of tricks you can teach this dog to do for you.

(geez! formatting code in Blogger sucks!  I'm going to start using Live Writer from now on)

No comments: