Code: Select all
js =
(
host.echo(JSON.stringify({foo:'bar'}));
42 // The script's result :)
)
class Host {
echo(s) {
MsgBox %s%
}
}
#NoEnv
; Initialize JsRT
if !DllCall("LoadLibrary", "str", "jscript9")
throw "Failed to load jscript9.dll"
JsRuntimeVersionEdge := -1
if DllCall("jscript9\JsCreateRuntime", "int", 0, "int", JsRuntimeVersionEdge
, "ptr", 0, "ptr*", runtime) != 0
throw "Failed to initialize JsRT; do you really have IE11?"
DllCall("jscript9\JsCreateContext", "ptr", runtime, "ptr", 0, "ptr*", context)
DllCall("jscript9\JsSetCurrentContext", "ptr", context)
; Get the Global object for adding stuff
DllCall("jscript9\JsGetGlobalObject", "ptr*", globalObject)
; Get a property ID for the name "host"
DllCall("jscript9\JsGetPropertyIdFromName", "wstr", "host", "ptr*", hostPropertyId)
; Get a JsValueRef for our Host object
hostRef := ToJsValue(Host)
; Pass our Host object to the script engine
DllCall("jscript9\JsSetProperty", "ptr", globalObject, "ptr", hostPropertyId
, "ptr", hostRef, "int", true)
; Run the script
e := DllCall("jscript9\JsRunScript", "wstr", js, "uptr", 0, "wstr", "source.js"
, "ptr*", result)
; Show the result
if !e {
DllCall("jscript9\JsConvertValueToString", "ptr", result, "ptr*", stringRef)
MsgBox % "Result: " FromJsValue(stringRef)
} else
MsgBox 48,, % format("Error {:#x}", e)
; Clean up
DllCall("jscript9\JsSetCurrentContext", "ptr", 0)
DllCall("jscript9\JsDisposeRuntime", "ptr", runtime)
ToJsValue(val) {
VarSetCapacity(variant, 24, 0)
ref := ComObject(0x400C, &variant) ; VT_BYREF|VT_VARIANT
ref[] := val
DllCall("jscript9\JsVariantToValue", "ptr", &variant, "ptr*", valref)
ref[] := 0
return valref
}
FromJsValue(valref) {
VarSetCapacity(variant, 24, 0)
DllCall("jscript9\JsValueToVariant", "ptr", valref, "ptr", &variant)
ref := ComObject(0x400C, &variant), val := ref[], ref[] := 0
return val
}
- The newer 'Chakra' version of the JScript engine can't officially be hosted any other way, except via a WebBrowser control. Unofficially, it's possible to use it with Active Scripting hosts (like ActiveScript.ahk) or cscript.exe file.js //E:{16d51579-a30b-4c8b-a276-0ff4dc41e755}, but what you get isn't the real deal: ScriptEngineMajorVersion() returns 11, but it's lacking IE11 language features and a few older APIs, like the JSON object.
Update: ActiveScript now includes an IActiveScript-like wrapper for the 'Chakra' JScript engine, class JsRT. - It allegedly has better performance than the older engines available to the ScriptControl, ActiveScript.ahk and the Windows Script Host.
- It looked interesting.
AutoHotkey v1.1.17+ is required for passing objects (like the Host object) to the runtime, and because of ref[] in ToJsValue/FromJsValue. There are alternatives for older versions of AutoHotkey.