# OLE Automation Objects

OLE Automation is a Windows feature that lets scripting languages access system functions and features in other applications. This is also known as "Scripting Objects", but that's a vague term that can mean other things as well. Automation was created originally for the Visual Basic language, and is most often used in VB. Windows Power Users will be familiar with this from working with Visual Basic scripts in programs like Excel, Word, or WScript. If you've done any work creating Visual Pinball tables, you might have used automation objects in VP's Visual Basic scripts.

In Javascript, you create an OLE scripting object like this:

let fs = createAutomationObject("Scripting.FileSystemObject");

If you're a Visual Basic user, it might be helpful if we mention that this is the equivalent of VB's CreateObject() function.

The object name in quotes is the "class name" of the object you wish to create. This isn't defined by Javascript; it's defined by whatever application or system facility provides the automation object. Windows provides a set of pre-installed "Scripting" objects, including "Scripting.FileSystemObject", which provides functions to access files and folders on the local hard disks. Many other objects come from separate applications, such as Excel or Word.

If the named class is installed on your system, createAutomationObject() returns a Javascript object that provides the set of methods and properties defined by the system object. You can now simply call methods on the returned object to access the system features provided by the object.

// list the files in the Windows folder for (let file of fs.GetSpecialFolder(0).Files) console.log(file.Name);

One common Windows OLE object that you shouldn't use is MSXML.XMLHTTP (or any of its several versions). You should use PinballY's HttpRequest instead, as it has provisions for asynchronous event handling that can't be easily reproduced with the generic Automation facility.

## "Variant" arguments

Many Automation objects work in terms of "Variant" variables, which is a special object formatted the same way that Visual Basic represents its variable values. (Microsoft originally designed Automation around Visual Basic's needs, so the whole system is very VB-centric.) When you call a method on an automation object, any Javascript arguments you pass to slots expecting Variant values have to be converted to Variant before being passed to the external object.

Javascript will perform the conversion to Variant automatically if you use regular Javascript values as arguments, so in most cases you can just call methods on these objects without worrying about special data types.

There's a snag, though. The automatic conversion can't always figure out which type the callee expects, so it always uses a standard conversion from each Javascript type to a suitable corresponding Variant type. For example, if you pass a Javascript number value as an argument, it will always be converted to a Variant "double", which is the VB equivalent of a Javascript number. The snag is that some automation methods are picky about the exact types they receive as arguments, and will return an error if you pass the "default" type used in the standard conversion from Javascript.

In such cases, you can solve the mismatch by explicitly creating your own Variant variable, and setting it to the expected type. You can do this as follows:

// create a Variant variable and set its "short int" value let v = new Variant(); v.iVal = 7; // now pass "short int" 7 to an automation method let x = createAutomationObject("Example.Object"); x.RequiresShortInt(v);

See Variants for details on the special Variant type.

## OUT parameters

Some automation object methods take "Out" parameters, which are arguments that the callee uses to return data to the caller.

There's no direct equivalent of "Out" parameters in normal Javascript, as all arguments in Javascript function and method calls are passed by value. The data transfer in Javascript is always one-way, from caller to callee. When calling an automation method that returns information through an "Out" parameter, therefore, we have to do something a little unusual.

Specifically, we use Variant objects. If an automation method passes information back through an Out parameter, simply pass a Variant to the method for that parameter. On return, the Variant will be modified to contain the returned information.

let v = new Variant(); autoObj.FuncThatChangesArgument(v); // v now contains the updated value

Note that you don't have to use a Variant for such arguments, but if you don't, any updated value will simply be discarded. If you pass any other value type to a method taking an Out parameter, the value you specify will be sent to the callee as usual, using the normal type conversions, and any update to the value will be ignored.

## Limitations

Unsupported types: The Automation system doesn't currently support calling methods taking the following VARIANT argument types. The VARIANT argument types are specified in the IDispatch COM interface provided by the automation object's native code, so this isn't a question of the argument values you pass from Javascript code; it's a fixed feature of each automation object's method interfaces. Functions that require unsupported argument types will throw a Javascript error to that effect if you attempt to call them.

- Pointer ("by reference") types
- Array types

Event handling: There's no built-in provision for the COM "event sink" system, which is used in some of the more complex automation objects to send asynchronous events back to the host program. Objects with event callbacks therefore can't easily be used, or at least can't easily be used with their full event systems.