Using the Script Control with Director
This document gives some examples for using the Microsoft Script Control ActiveX-Object with Director. For the examples to work they have to reside in a moviescript, the Script Control has to be present as sprite 1, and the movie has to run.
The Microsoft Script Control offers a simple method to add a script engine to Windows-based applications. It's possible to embed the Script Control in a director movie (Insert: Control: AcitiveX: ScriptControl Object), and then dynamically execute script code and, if necessary, return results back to lingo. In addition to VBScript and JScript, which are available on every PC with the windows scripting host (WSH) installed (as far as I know, default on Windows XP and 2k, non-default option with Win98 installation, don't know about 95 and NT), also other script languages like PerlScript (ActivePerl), PythonScript (ActivePython), REXXScript (Object REXX) or VideoScript (http://www.videoscript.com) can be used, if they are installed, which could be the case under Terminal/POI circumstances.
There are several ways to do execute the script code. The code can reside
within the lingo code, which results in hybrid code, similar to the PHP approach
(see examples below), or in separate field or text members:
sprite(1).ExecuteStatement(member("code").text)
Instead of
interpreting/executing the code as a whole with the ExecuteStatement() method,
it can also be done line by line with the AddCode() method, which might be
advantageous for debugging. To return a result back to lingo, you have to use
the Run() method.
For more information about the Script Control see Exploring the Microsoft Script Control.
For futher experiments here a list of JScript methods and VBScript Functions.
Things you can do:
· obtain the path to special system folders
· obtain environment variables
· create a message window, e.g. a yes/no dialog window, and return which button the user has clicked
· create an InputBox and return the entered string
· obtain information about the network
· run applications with specified window state, e.g. hidden
· execute commands/programms with the command-processor, return the results (STDOUT) to lingo.
· get information about drives
· execute VideoScript, export to QuickTime
-- The following handler reads the text from a specified file.
-- It can be used as an alternative to fileIO xtra.
-- The parts in the path have to be separated with double backslashes.
-- Example: put readTextFile("C:\\README.TXT")
on readTextFile fp -- filepath with double-backslashes!
s=sprite(1) -- ScriptControl-Sprite
s.Language="JScript"
code=""
code = code & "function sReadTextFile(){"
code = code & " var fso = new ActiveXObject(""E&"Scripting.FileSystemObject""E&");"
code = code & " var ts = fso.OpenTextFile(""E&fp"E&");"
code = code & " return ts.ReadAll();"
code = code & "}"
s.ExecuteStatement(code)
return s.Run("sReadTextFile")
end
-- The following handler writes a text (more than on line allowed) to a specified file.
-- It can be used as an alternative to fileIO xtra.
-- The folders in the path have to be separated with double backslashes.
-- Example: writeTextFile("C:\\README.TXT",member("myText").text))
on writeTextFile fp, txt -- filepath with double-backslashes!
s=sprite(1) -- ScriptControl-Sprite
s.Language="JScript"
code=""
code = code & "var fso = new ActiveXObject(""E&"Scripting.FileSystemObject""E&");"
code = code & "var ts = fso.CreateTextFile(""E&fp"E&", true);"
repeat with i = 1 to txt.line.count
code = code & "ts.WriteLine(""E&txt.line[i]"E&");"
end repeat
code = code & "ts.Close();"
s.ExecuteStatement(code)
end
-- The following handler returns the path to some system folders.
-- Name of the system folder has to be passed as parameter.
-- Example: put getSpecialFolder("Desktop")
on getSpecialFolder nam
-- where nam can be:
-- AllUsersStartMenu
-- AllUsersPrograms
-- AllUsersStartup
-- Desktop
-- Favorites
-- Fonts
-- My Documents
-- NetHood
-- PrintHood
-- Programs
-- Recent
-- SendTo
-- Start Menu
-- StartupB
-- Templates
s=sprite(1) -- ScriptControl-Sprite
s.Language="JScript"
code=""
code = code & "function sGetSpecialFolder(){"
code = code & " var WshShell = new ActiveXObject(""E&"WScript.Shell""E&");"
code = code & " return WshShell.SpecialFolders(""E&nam"E&");"
code = code & "}"
s.ExecuteStatement(code)
return s.Run("sGetSpecialFolder")
end
-- The following handler returns environment variables.
-- Name of the variable has to be passed as parameter.
-- Example: put getEnvironment("COMSPEC")
on getEnvironment var
-- where var can be:
-- NUMBER_OF_PROCESSORS
-- PROCESSOR_ARCHITECTURE
-- PROCESSOR_IDENTIFIER
-- PROCESSOR_LEVEL
-- PROCESSOR_REVISION
-- OS
-- COMSPEC
-- HOMEDRIVE
-- HOMEPATH
-- PATH
-- PATHEXT
-- PROMPT
-- SYSTEMDRIVE
-- SYSTEMROOT
-- WINDIR
-- TEMP
-- TMP
s=sprite(1) -- ScriptControl-Sprite
s.Language="JScript"
code = ""
code = code & "function sGetEnvironment(){"
code = code & " var WshShell = new ActiveXObject(""E&"WScript.Shell""E&");"
code = code & " var WshSysEnv = WshShell.Environment(""E&"SYSTEM""E&");"
code = code & " return WshSysEnv(""E&var"E&");"
code = code & "}"
s.ExecuteStatement(code)
return s.Run("sGetEnvironment")
end
5. Creating message windows/dialog windows
-- The following handler creates a popup window with a "Yes" and a "No"-Button (JScript version)
-- The pressed button is returned as value: 6 for "Yes", 7 for "No", -1 for timeout
-- (alternative to MUI xtra).
-- Example: put popup()
on popup
s=sprite(1) -- ScriptControl-Sprite
s.Language="JScript"
code = ""
code = code & "function sPopup(){"
code = code & " var WshShell = new ActiveXObject(""E&"WScript.Shell""E&");"
code = code & " return WshShell.Popup(""E&"Do you feel alright?""E&",\
7, ""E&"Answer This Question:""E&", 4 + 32);"
code = code & "}"
s.ExecuteStatement(code)
return s.Run("sPopup")
end
-- The following handler creates a message window (VBScript version)
on msg
s=sprite(1) -- ScriptControl
s.Language="VBScript"
code = ""
--code = code & "MsgBox(""E&"Hello World!""E&")" &RETURN
code = code & "Dim MyVar" &RETURN
code = code & "MyVar = MsgBox (""E&"Hello World!""E&", 65, \
""E&"MsgBox Example""E&")" &RETURN
s.ExecuteStatement(code)
end
6. Creating an InputBox and return entered string
-- The following handler creates an InputBox and returns the string the user has entered.
-- (alternative to MUI xtra)
-- Example: put input("Enter your name")
on input str
s=sprite(1) -- ScriptControl
s.Language="VBScript"
code = ""
code = code & "Function Input(s)" &RETURN
code = code & " Input = InputBox(s)" &RETURN
code = code & "End Function" &RETURN
s.ExecuteStatement(code)
return s.Run("Input",str)
end
-- The following handler returns some network information.
-- Example: put getNetworkInfo("UserName ")
on getNetworkInfo nam
-- where nam can be:
-- UserDomain
-- ComputerName
-- UserName
s=sprite(1) -- ScriptControl-Sprite
s.Language="JScript"
code = ""
code = code & "function sGetNetworkInfo(){"
code = code & " var WshNetwork = new ActiveXObject(""E&"WScript.Network""E&");"
code = code & " return WshNetwork[""E&nam"E&"];"
code = code & "}"
s.ExecuteStatement(code)
return s.Run("sGetNetworkInfo")
end
8. Run an Application (hidden)
-- The following handler demonstrates how to run a hidden application.
-- A listing of c: is written to c:\listing.txt.
on runHiddenTest
s=sprite(1) -- ScriptControl
s.Language="JScript"
code = ""
code = code & "var Shell = new ActiveXObject(""E&"WScript.Shell""E&");"
code = code & "Shell.Run(""E&"cmd.exe /c dir c:\\>c:\\listing.txt""E&",0);" -- 0 for hidden!
s.ExecuteStatement(code)
end
9. Execute a (DOS-)command and return the result
-- The following handler executes a command passed as paramter and returns the result.
-- Example: put shellExec("ipconfig")
-- Example: put shellExec("net share")
on shellExec cmd
s=sprite(1) -- ScriptControl-Sprite
s.Language="JScript"
code = ""
code = code & "function sShellExec(){"
code = code & " var Shell = new ActiveXObject(""E&"WScript.Shell""E&");"
code = code & " var ExecObj = Shell.Exec(""E&cmd"E&");"
code = code & " return ExecObj.StdOut.ReadAll();"
code = code & "}"
s.ExecuteStatement(code)
return s.Run("sShellExec")
end
10. Send Keys to an application
-- Example:
-- Opens the calculator and sends some keys to it
on calc
s=sprite(1) -- ScriptControl-Sprite
s.Language="JScript"
code = ""
code = code & "function sleep(n){" -- SLEEP
code = code & " var ms=new Date();"
code = code & " while (new Date()-ms<n);"
code = code & "}"
code = code & "var WshShell = new ActiveXObject(""E&"WScript.Shell""E&");"
code = code & "WshShell.Run(""E&"calc""E&");"
--code = code & "WshShell.AppActivate(""E&"Calculator""E&");"
code = code & "sleep(250);"
code = code & "WshShell.SendKeys(""E&"123454321""E&");"
s.ExecuteStatement(code)
end
11. Export data as an excel file
-- The following handler exports a 2-dimensional array of data - a list of lists - as an
-- Excel file with specified filepath. Excel has to be installed.
-- Example: exportExcel("c:\\data.xls",[["aaa", "bbb", "ccc"],[1, 2 , 3.1415]])
on exportExcel fp, listOfLists -- filepath with double-backslashes!
s=sprite(1) -- ScriptControl-Sprite
s.Language="JScript"
code = ""
code = code & "var ExcelApp = new ActiveXObject(""E&"Excel.Application""E&");"
code = code & "var ExcelSheet = new ActiveXObject(""E&"Excel.Sheet""E&");"
repeat with i = 1 to listOfLists.count
l=listOfLists[i]
repeat with j = 1 to l.count
code = code & "ExcelSheet.ActiveSheet.Cells("&i&","&j&").Value = ""E&l[j]"E&";"
end repeat
end repeat
code = code & "ExcelSheet.SaveAs(""E&fp"E&");"
code = code & "ExcelApp.Quit();"
s.ExecuteStatement(code)
end
-- The following handler checks a passed string with word's spell checking.
-- Word has to be installed.
-- Example: put checkSpelling("neccesarily")
on checkSpelling txt -- filepath with double-backslashes!
s=sprite(1) -- ScriptControl-Sprite
s.Language="JScript"
code = ""
code = code & "function sCheckSpelling(Uncorrected){"
code = code & " var Word, Doc, Uncorrected, Corrected;"
code = code & " var wdDialogToolsSpellingAndGrammar = 828;"
code = code & " var wdDoNotSaveChanges = 0;"
code = code & " Word = new ActiveXObject(""E&"Word.Application""E&");"
code = code & " Doc = Word.Documents.Add();"
code = code & " Word.Selection.Text = Uncorrected;"
code = code & " Word.Dialogs(wdDialogToolsSpellingAndGrammar).Show();"
code = code & " if (Word.Selection.Text.length != 1) Corrected = Word.Selection.Text;"
code = code & " else Corrected = Uncorrected;"
code = code & " Doc.Close(wdDoNotSaveChanges);"
code = code & " Word.Quit();"
code = code & " return Corrected;"
code = code & "}"
s.ExecuteStatement(code)
return s.Run("sCheckSpelling",txt)
end
-- The following handler reads a key from the registry.
-- the registry path has to be separated with double backslashes.
-- Example:
-- put readReg("HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\ProxyServer")
on readReg regKey -- regpath with double-backslashes!
s=sprite(1) -- ScriptControl
s.Language="JScript"
code = ""
code = code & "function sReadReg(){"
code = code & " var WshShell = new ActiveXObject(""E&"WScript.Shell""E&");"
code = code & " return WshShell.RegRead(""E®Key"E&");"
code = code & "}"
s.ExecuteStatement(code)
return s.Run("sReadReg")
end
-- Example:
-- Creates a new registry key and fills it with " Hello world!"
on writeRegTest
s=sprite(1) -- ScriptControl
s.Language="JScript"
code = ""
code = code & "var WshShell = new ActiveXObject(""E&"WScript.Shell""E&");"
code = code & "WshShell.RegWrite(""E&"HKCU\\MyNewKey\\""E&",1,""E&"REG_DWORD""E&");"
code = code & "WshShell.RegWrite(""E&"HKCU\\MyNewKey\\MyValue""E&",""E&\
"Hello world!""E&");"
s.ExecuteStatement(code)
end
-- The following handler demonstrates error handling with VBScript
on errVBS
s=sprite(1) -- ScriptControl
s.Language="VBScript"
code = ""
code = code & "Dim WshShell" &RETURN
code = code & "Set WshShell = CreateObject(""E&"WScript.Shell""E&")" &RETURN
code = code & "On Error Resume Next" &RETURN
-- CREATE AN ERROR: Try to read non existent regkey
code = code & "WshShell.RegRead(""E&"HKKK""E&")" &RETURN
--code = code & " Err.Raise 6" &RETURN -- this creates an arbitrary error of type 6
code = code & "MsgBox(""E&"Error: ""E&" & Err.Description)" &RETURN
code = code & "Err.Clear" &RETURN
s.ExecuteStatement(code)
end
-- The following handler demonstrates error handling with JScript
on errJS
s=sprite(1) -- ScriptControl
s.Language="JScript"
code = ""
code = code & "var WshShell = new ActiveXObject(""E&"WScript.Shell""E&");"
code = code & "try{"
-- CREATE AN ERROR: Try to read non existent regkey
code = code & " WshShell.RegRead(""E&"HKKK""E&");"
code = code & "}catch(e){"
code = code & " WshShell.Popup(""E&"Error: ""E&" + e.description);"
code = code & "}"
s.ExecuteStatement(code)
end
16. Use Regular Expressions (e.g. for syntactical check of email adress)
-- The following handler uses the JScript-RegExp-Object to check if a passed string is a syntactical
-- correct email-adress.
-- It can be used as an alternative to the (great!) PRegEx Regular Expression Xtra.
on isEmail str
s=sprite(1) -- ScriptControl
s.Language="JScript"
code = ""
code = code & "function is_email(email) {;"
code = code & " var reg1 = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9._-]{2,}[.][a-zA-Z0-9]{2,4}$/;"
code = code & " var reg2 = /[.@]{2,}/;"
code = code & " return ((reg1.exec(email)!=null)&&(reg2.exec(email)==null))?1:0;"
code = code & "}"
s.ExecuteStatement(code)
return s.Run("is_email",str)
End
17. Get information about local and network drives
-- The following handler retrieves information about local and network drives
-- and presents it in a popup window (JScript version)
on drivesJS
s=sprite(1) -- ScriptControl
s.Language="JScript"
code = ""
code = code & "var WshShell = new ActiveXObject(""E&"WScript.Shell""E&");"
code = code & "var fso = new ActiveXObject(""E&"Scripting.FileSystemObject""E&");"
code = code & "var e = new Enumerator(fso.Drives);"
code = code & "var s='Drive\tType\t\tName\n\n';"
code = code & "for (;!e.atEnd();e.moveNext()){"
code = code & " drive = e.item();"
code = code & " nam=(drive.DriveType==3)?drive.ShareName:((drive.IsReady)?drive.VolumeName:'');"
code = code & " typ=['Removable','Fixed','Network','CD-ROM','RAM Disk','Unknown'][drive.DriveType-1];"
code = code & " s += drive.DriveLetter+'\t'+typ+'\t\t'+nam+""E&"\n""E&";"
code = code & "}"
code = code & "WshShell.Popup(s);"
s.ExecuteStatement(code)
end
-- The following handler retrieves information about local and network drives
-- and presents it in a popup window (VBScript version)
on drivesVBS
s=sprite(1) -- ScriptControl
s.Language="VBScript"
code = ""
code = code & "Dim NL" &RETURN
code = code & "Dim TAB" &RETURN
code = code & "Dim FSO" &RETURN
code = code & "Dim Drives" &RETURN
code = code & "Dim Drive" &RETURN
code = code & "Dim S" &RETURN
code = code & "NL=Chr(10) & Chr(13)" &RETURN
code = code & "TAB=Chr(9)" &RETURN
code = code & "Function ShowDriveType(Drive)" &RETURN
code = code & " Dim S" &RETURN
code = code & " Select Case Drive.DriveType" &RETURN
code = code & " Case 1" &RETURN
code = code & " S = ""E&"Removable""E &RETURN
code = code & " Case 2" &RETURN
code = code & " S = ""E&"Fixed""E &RETURN
code = code & " Case 3" &RETURN
code = code & " S = ""E&"Network""E &RETURN
code = code & " Case 4" &RETURN
code = code & " S = ""E&"CD-ROM""E &RETURN
code = code & " Case 5" &RETURN
code = code & " S = ""E&"RAM Disk""E &RETURN
code = code & " Case Else" &RETURN
code = code & " S = ""E&"Unknown""E &RETURN
code = code & " End Select" &RETURN
code = code & " ShowDriveType = S" &RETURN
code = code & "End Function" &RETURN
code = code & "Set FSO = CreateObject(""E&"Scripting.FileSystemObject""E&")" &RETURN
code = code & "Set Drives = FSO.Drives" &RETURN
code = code & "S = ""E&"Number of drives:""E&" & TAB & Drives.Count & NL & NL" &RETURN
code = code & "S = S & ""E&"Drive""E &RETURN
code = code & "S = S & TAB & ""E&"Letter""E &RETURN
code = code & "S = S & TAB & ""E&"Type""E &RETURN
code = code & "S = S & TAB & TAB & ""E&"Name""E &RETURN
code = code & "S = S & TAB & TAB & ""E&"Filesystem""E &RETURN
code = code & "S = S & TAB & ""E&"Size [MB]""E &RETURN
code = code & "S = S & TAB & TAB & ""E&"Free Space [MB]""E&"&NL" &RETURN
code = code & "S = S & String(140, ""E&"-""E&") & NL" &RETURN
code = code & "For Each Drive In Drives" &RETURN
code = code & " S = S & Drive.DriveLetter" &RETURN
code = code & " S = S & TAB & Drive.Path" &RETURN
code = code & " S = S & TAB & ShowDriveType(Drive)" &RETURN
code = code & " If Drive.IsReady Then" &RETURN
code = code & " If DriveTypeNetwork = Drive.DriveType Then" &RETURN
code = code & " S = S & TAB & TAB & Drive.ShareName" &RETURN
code = code & " Else" &RETURN
code = code & " S = S & TAB & TAB & Drive.VolumeName" &RETURN
code = code & " End If" &RETURN
code = code & " S = S & TAB & TAB & Drive.FileSystem" &RETURN
code = code & " S = S & TAB & TAB & Int(Drive.TotalSize/1024/1024)" &RETURN
code = code & " S = S & TAB & TAB & Int(Drive.FreeSpace/1024/1024)" &RETURN
code = code & " End If" &RETURN
code = code & " S = S & NL" &RETURN
code = code & "Next" &RETURN
code = code & "MsgBox(S)" &RETURN
s.ExecuteStatement(code)
End
18. Creating shortcuts on the desktop or in the start menu
-- The following handler creates a shortcut to the projector ("start.exe") on the desktop
-- (or in the startmenu).
on createShortcut
-- create applicationPath with double backslashes
tmp=the applicationPath
ap=""
the itemdelimiter="\"
repeat with i = 1 to tmp.item.count
ap=ap&tmp.item[i]&"\\"
end repeat
s=sprite(1) -- ScriptControl
s.Language="JScript"
code = ""
code = code & "var WshShell = new ActiveXObject(""E&"WScript.Shell""E&");"
-- code = code & "var where = WshShell.SpecialFolders(""E&"Start Menu""E&");"
code = code & "var where = WshShell.SpecialFolders(""E&"Desktop""E&");"
code = code & "var oShellLink = WshShell.CreateShortcut(where+""E&"\\start.lnk""E&");"
code = code & "oShellLink.TargetPath = ""E&ap&"start.exe""E&";"
code = code & "oShellLink.WindowStyle = 1;"
code = code & "oShellLink.IconLocation = ""E&ap&"start.exe, 0""E&";"
code = code & "oShellLink.Description = ""E&"My Projector""E&";"
code = code & "oShellLink.WorkingDirectory = strDesktop;"
code = code & "oShellLink.Save();"
s.ExecuteStatement(code)
End
-- The following handler generates a mandelbrot image sequence and saves it as a quicktime movie.
-- The application "VideoScript" has to be installed on the computer.
-- (http://www.videoscript.com/Win32/VsWin_Latest.exe)
on videoScriptTest1 me
s=sprite(1) -- ScriptControl
s.Language="VideoScript"
code = ""
code = code & "set scale to 1;" &RETURN
code = code & "set x to -0.710005;" &RETURN
code = code & "set y to 0.353278;" &RETURN
code = code & "set picture to Fractal.Mandelbrot(x, y, scale, 320, 240,\
colortype->""E&"fade""E&");" &RETURN
code = code & "set window ""E&"picture""E&" to reference picture;" &RETURN
code = code & "set m to movie;" &RETURN
code = code & "repeat 50 times" &RETURN
code = code & " begin" &RETURN
code = code & " set scale to scale/1.05;"
code = code & " set picture to Fractal.Mandelbrot(x, y, scale, 320, 240,\
colortype->""E&"fade""E&");" &RETURN
code = code & " append picture to m;" &RETURN
code = code & "end" &RETURN
code = code & "set file ""E&"c:\\mandel.mov""E&" to m;" &RETURN
s.ExecuteStatement(code)
end
-- The following handler captures images from an attached videodevice
-- and saves the sequence as a quicktime movie.
-- The application "VideoScript" has to be installed on the computer.
-- (http://www.videoscript.com/Win32/VsWin_Latest.exe)
on videoScriptTest2 me
s=sprite(1) -- ScriptControl
s.Language="VideoScript"
code = ""
code = code & "set m to movie;" &RETURN
code = code & "set vs to videosource;" &RETURN
code = code & "repeat 20 times every 1 seconds" &RETURN
code = code & " begin" &RETURN
code = code & " append (frame of vs) to m;" &RETURN
code = code & "end" &RETURN
code = code & "set file ""E&"c:\\webcam.mov""E&" to m;" &RETURN
s.ExecuteStatement(code)
end