ActiveScript - Host VBScript and JScript in-process

Post your working scripts, libraries and tools for AHK v1.1 and older
lexikos
Posts: 9494
Joined: 30 Sep 2013, 04:07
Contact:

Re: ActiveScript - Host VBScript and JScript in-process

26 Apr 2017, 21:37

(Replying only because of a PM.)

Perhaps if you say what the problem is, or ask an actual question, I might be interested enough to answer it. As it is, I'm not nearly interested enough to figure out what the problem is, let alone the solution.
icuurd12b42
Posts: 202
Joined: 14 Aug 2016, 04:08

Re: ActiveScript - Host VBScript and JScript in-process

16 Sep 2017, 05:48

anyone knows how to setup that dispatch table? I'm trying to expose more than on method of my object

Code: Select all

js.AddObject("myObj", ComDispatch(new MyClass, MyClass.DispTable))
js.Exec("myObj.Method(['first value', 'second value'])")

class MyClass
{
    Method1(x)
    {
        ; Just to show we can pass arrays from JScript to AHK:
        Debug.MsgBox("Method1: " . x)
    }
    Method2(x)
    {
        ; Just to show we can pass arrays from JScript to AHK:
        Debug.MsgBox("Method2: " . x)
    }
    static DispTable := [[MyClass.Method1], {Method1:1}
                               , [MyClass.Method2], {Method2:2}]
}
I assumed to add another entry... though I dont know what this :1 does either, there is no documentation on this dispatch table
I'm getting a Method is not supported exception calling myObj.Method2("text") from my code. Method1 works just fine

While typing this I had an idea of trying Comdispatch0, there has to be a reason for it's existance right? It works and seems to do the discovery of the object methods itself to define the interface, Yeah. the good news is I wont have to type all this dispatch information...
FIX:
js.AddObject("myObj", ComDispatch0(new MyClass))
lexikos
Posts: 9494
Joined: 30 Sep 2013, 04:07
Contact:

Re: ActiveScript - Host VBScript and JScript in-process

17 Oct 2017, 00:53

icuurd12b42 wrote:While typing this I had an idea of trying Comdispatch0, there has to be a reason for it's existance right?
Yes. It removes the need to define the object's interface.

But they are both obsolete. Just pass the object directly to AddObject.
I wrote:ComObject := ComDispatch0(Object) - not needed in AutoHotkey v1.1.17+
icuurd12b42
Posts: 202
Joined: 14 Aug 2016, 04:08

Re: ActiveScript - Host VBScript and JScript in-process

19 Oct 2017, 03:46

Your answer is a little short in context...

are you saying
his.m_Js := new ActiveScript("JScript")
;My Objects
this.m_Js.AddObject("HKS", ComDispatch0(HKS))

can be changed to
his.m_Js := new ActiveScript("JScript")
;My Objects
this.m_Js.AddObject(HKS)

HKS is an object.... with get properties that further adds more objects to the structure

Code: Select all

class HKS
{
    Debug {
        get {
            return Debug
        }
    }
    Resource {
        get {
            return Resource
        }
    }
    VoiceAgent {
        get {
            return VoiceAgent
        }
    }
    Recognition {
        get {
            return Recognition
        }
    }
}
icuurd12b42
Posts: 202
Joined: 14 Aug 2016, 04:08

Re: ActiveScript - Host VBScript and JScript in-process

19 Oct 2017, 08:40

I just chased a bug where a AHK function returning a number called from the Jscript code has the number turned into a string on the JScript side... I solved it calling parseInt on the js side but it's really clumsy looking
icuurd12b42
Posts: 202
Joined: 14 Aug 2016, 04:08

Re: ActiveScript - Host VBScript and JScript in-process

19 Oct 2017, 21:15

I would like to call this function
https://docs.microsoft.com/en-us/script ... riptthread
It does not look to be available, or if it is at what level it would be.
lexikos
Posts: 9494
Joined: 30 Sep 2013, 04:07
Contact:

Re: ActiveScript - Host VBScript and JScript in-process

27 Oct 2017, 20:38

icuurd12b42 wrote:are you saying [...]
this.m_Js.AddObject("HKS", ComDispatch0(HKS))

can be changed to [...]
this.m_Js.AddObject(HKS)
No. I am saying you can replace ComDispatch0(HKS) with HKS. You still need to tell AddObject which name to bind in the JavaScript context.
I would like to call this function
If you want to call a function not supported by the wrapper, you will need to figure out its v-table offset and call it via DllCall. For instance, SetScriptSite uses 3*A_PtrSize because it is the fourth method in the plain C interface (search for "IActiveScriptVtbl" in the Windows SDK or on the web).

AutoHotkey v1 functions return strings in many cases, for backward-compatibility (i.e. 0x100 produces the string "0x100", not "256"). You can generally avoid it by adding an operation, such as return 0x100 + 0 instead of return 0x100.
icuurd12b42
Posts: 202
Joined: 14 Aug 2016, 04:08

Re: ActiveScript - Host VBScript and JScript in-process

30 Oct 2017, 06:09

Thanks I looks into these
Bunny the Dummy

Re: ActiveScript - Host VBScript and JScript in-process

17 Nov 2017, 06:49

does anyone know how to add an onclick even so if I click on the traytip i can open excel?
User avatar
FanaticGuru
Posts: 1905
Joined: 30 Sep 2013, 22:25

Re: ActiveScript - Host VBScript and JScript in-process

07 Jun 2018, 19:50

lexikos wrote:I've added a method for enabling the use of WinRT (the framework used by Windows 10 apps) with JsRT.Edge, and an example for displaying a toast notification.

Image
How would you detect a click on the toast notification.

I want when I click on a toast notification, a function in my AHK script will be called.

I have went round and round with addEventListener("activated", onActivatedHandler, false); as well as every other thing I could google.

Here is what I got for displaying the toast notification:

Code: Select all

#NoEnv
#Include <ActiveScript>
#Include <JsRT>

; Get image file if needed
if !FileExist("sample.png")
    URLDownloadToFile https://autohotkey.com/boards/styles/simplicity/theme/images/announce_unread.png
        , % A_ScriptDir "\sample.png"

Toast_Notification(["Folder: " A_MyDocuments, "2 Files Saved"], A_ScriptDir "\sample.png")
return

Toast_Notification(toast_text := "", toast_image := "", toast_template := "toastImageAndText02" )
{
	static
	if !js
	{
		; This assumes AutoHotkey is installed in the default location:
		toast_appid := (A_Is64bitOS ? "{6D809377-6AF0-444b-8957-A3773F02200E}"
									: "{905e63b6-c1bf-494e-b29c-65b732d3d21a}")
			. "\AutoHotkey\AutoHotkey.exe"

		; Only the Edge version of JsRT supports WinRT.
		js := new JsRT.Edge

		; Enable use of WinRT.  "Windows.UI" or "Windows" would also work.
		js.ProjectWinRTNamespace("Windows.UI.Notifications")
		code =
		(
			function toast(template, image, text, app) {
				// Alias for convenience.
				var N = Windows.UI.Notifications;
				// Get the template XML as an XmlDocument.
				var toastXml = N.ToastNotificationManager.getTemplateContent(N.ToastTemplateType[template]);
				// Insert our content.
				var i = 0;
				for (let el of toastXml.getElementsByTagName("text")) {
					if (typeof text == 'string') {
						el.innerText = text;
						break;
					}
					el.innerText = text[++i];
				}
				toastXml.getElementsByTagName("image")[0].setAttribute("src", image);
				// Show the notification.
				var toastNotifier = N.ToastNotificationManager.createToastNotifier(app || "AutoHotkey");
				var notification = new N.ToastNotification(toastXml);
				toastNotifier.show(notification);
			}
		)
		try 
		{
			; Define the toast function.
			js.Exec(code)
		}
		catch ex 
		{
			try errmsg := ex.stack
			if !errmsg
				errmsg := "Error: " ex.message
			MsgBox % errmsg
		}
	}
	try 
	{
		; Show a toast notification.
		js.toast(toast_template, toast_image, toast_text, toast_appid)
	}
	catch ex 
	{
		try errmsg := ex.stack
		if !errmsg
			errmsg := "Error: " ex.message
		MsgBox % errmsg
	}
}

stuff(s)
{
	MsgBox % s
}
That part works fine but I cannot figure out what to put where to get the "stuff(s)" function at the end to run when the notification is clicked, preferably with the s containing the text of the notification.

I feel like it would only take a few lines in the JavaScript code. Any help would be very much appreciated.

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks
User avatar
FanaticGuru
Posts: 1905
Joined: 30 Sep 2013, 22:25

Re: ActiveScript - Host VBScript and JScript in-process

08 Jun 2018, 17:23

After spending way too much time on unraveling this, I finally got it to work to handle clicks on a toast notification.

Code: Select all

#NoEnv
#Include <ActiveScript>
#Include <JsRT>

; get image
if !FileExist("sample.png")
    URLDownloadToFile https://autohotkey.com/boards/styles/simplicity/theme/images/announce_unread.png
        , % A_ScriptDir "\sample.png"

F1::Toast_Notification(["Folder: " A_MyDocuments, "2 Files Saved"], A_ScriptDir "\sample.png")
Esc::ExitApp

return

Toast_Notification(toast_text, toast_image , toast_template := "toastImageAndText02" )
{
	static
	if !js
	{
		; This assumes AutoHotkey is installed in the default location:
		toast_appid := (A_Is64bitOS ? "{6D809377-6AF0-444b-8957-A3773F02200E}"
									: "{905e63b6-c1bf-494e-b29c-65b732d3d21a}")
			. "\AutoHotkey\AutoHotkey.exe"

		; Only the Edge version of JsRT supports WinRT.
		js := new JsRT.Edge
		js.AddObject("JS_ToastActivated", Func("AHK_ToastActivated"))

		; Enable use of WinRT.  "Windows.UI" or "Windows" would also work.
		js.ProjectWinRTNamespace("Windows.UI.Notifications")
		code =
		(
			function toast(template, image, text, app) {
				// Alias for convenience.
				var N = Windows.UI.Notifications;
				// Get the template XML as an XmlDocument.
				var toastXml = N.ToastNotificationManager.getTemplateContent(N.ToastTemplateType[template]);
				// Create toastNode to launch on click
				var toastNode = toastXml.selectSingleNode('/toast');
				toastNode.setAttribute('launch', text[1]);
				// Insert our content.
				var i = 0;
				for (let el of toastXml.getElementsByTagName("text")) {
					if (typeof text == 'string') {
						el.innerText = text;
						break;
					}
					el.innerText = text[++i];
				}
				toastXml.getElementsByTagName("image")[0].setAttribute("src", image);
				// Show the notification.
				var toastNotifier = N.ToastNotificationManager.createToastNotifier(app || "AutoHotkey");
				var notification = new N.ToastNotification(toastXml);
				notification.addEventListener("activated", toastActivatedHandler);
				toastNotifier.show(notification);
			}
			function toastActivatedHandler(a) {
				JS_ToastActivated(a.arguments);
			}

		)
		try 
		{
			; Define the toast function.
			js.Exec(code)
		}
		catch ex 
		{
			try errmsg := ex.stack
			if !errmsg
				errmsg := "Error: " ex.message
			MsgBox % errmsg
		}
	}
	try 
	{
		; Show a toast notification.
		js.toast(toast_template, toast_image, toast_text, toast_appid)
	}
	catch ex 
	{
		try errmsg := ex.stack
		if !errmsg
			errmsg := "Error: " ex.message
		MsgBox % errmsg
	}
}

AHK_ToastActivated(a)
{
	MsgBox % a
}
This will create a toast notification and when clicked on the function AHK_ToastActivated(a) will be called which will display the first line of the toast notification.

It seems so simple now but getting all the parts right was a real challenge when starting with zero knowledge of JavaScript especially with the added layer of funneling it through AHK. On the plus side I did learn some basics of JavaScript.

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks
User avatar
joedf
Posts: 8937
Joined: 29 Sep 2013, 17:08
Location: Canada
Contact:

Re: ActiveScript - Host VBScript and JScript in-process

08 Jun 2018, 20:55

Coolio! I haven't used this but it's good you provided this example!
Thanks FanaticGuru :)
Image Image Image Image Image
Windows 10 x64 Professional, Intel i5-8500, NVIDIA GTX 1060 6GB, 2x16GB Kingston FURY Beast - DDR4 3200 MHz | [About Me] | [About the AHK Foundation] | [Courses on AutoHotkey]
[ASPDM - StdLib Distribution] | [Qonsole - Quake-like console emulator] | [LibCon - Autohotkey Console Library]
User avatar
kczx3
Posts: 1640
Joined: 06 Oct 2015, 21:39

Re: ActiveScript - Host VBScript and JScript in-process

04 Nov 2019, 20:47

A little fun with JsRT and JSON. I'm contemplating using something like this in AHKv2 (if I can convert ActiveScript and JsRT, of course).

Code: Select all

#include ActiveScript.ahk
#Include JsRT.ahk

JsRT := new JsRT.Edge
JSON := JsRT.JSON

obj := JSON.parse("{""stuff"": ""things"", ""manyThings"": [""my"", ""name"", ""is"", ""sparta""], ""myBool"": true}")

msgbox, % JSON.stringify(obj, , 4)

msgbox, % obj.manyThings.reduce(Func("totalCharacters"), 0)

obj.manyThings.forEach(Func("MsgBox"))

JsRT.Object.entries(obj).forEach(Func("MsgBox"))

MsgBox(str) {
    if (str is string) {
        msgbox, % str
        return
    }

    key := str[0], val := str[1]
    if (val is string) {
        MsgBox, % key " = " val
    }
    else {
        if (JsRT.Array.isArray(val)) {
            MsgBox, % key " = [" val.join(", ") "]"
        }
    }
}

totalCharacters(acc, next, index) {
    return acc + StrLen(next)
}
joreli
Posts: 8
Joined: 13 Jul 2021, 15:33

Re: ActiveScript - Host VBScript and JScript in-process

13 Jul 2021, 16:03

Hi..

Having trouble with JSON and ActiveXObject. It seems by default they are not enabled with the latest IE11 runtime.

When I instantiate the class as

Code: Select all

js := new MyActiveScript("JScript9") ; I have added the registry setting 
or

Code: Select all

js := new MyActiveScript("{16d51579-a30b-4c8b-a276-0ff4dc41e755}")
ActiveXObject is working, but JSON is undefined (tested with typeof operator) and the version returns 11.0

With this

Code: Select all

js := new JsRT.IE
JSON is working, but ActiveXObject and GetObject are undefined. Version returns 11.0

Is it possible to support these functions using JScript9.dll version?
lexikos
Posts: 9494
Joined: 30 Sep 2013, 04:07
Contact:

Re: ActiveScript - Host VBScript and JScript in-process

16 Jul 2021, 06:11

If you want an IE11-like environment, create a WebBrowser control or InternetExplorer.Application and inject script. ActiveScript only gives you the scripting engine, not the application model.

Alternatively, you can insert whatever functions you want into the ActiveScript instance by using AddObject or an assignment; e.g. js.AddObject("ComObjCreate", Func("ComObjCreate")).
joreli
Posts: 8
Joined: 13 Jul 2021, 15:33

Re: ActiveScript - Host VBScript and JScript in-process

17 Jul 2021, 00:33

Thank you @lexikos.
Instead of WebBrowser control, "HtmlFile" object seems lightweight (less memory usage) and rather than hosting full WebBrowser control.

Code: Select all

oHtml := ComObjCreate("HtmlFile")
oHtml.write("<meta http-equiv='X-UA-Compatible' content='IE=edge'>")
oJs :=  oHtml.parentWindow
User avatar
lmstearn
Posts: 681
Joined: 11 Aug 2016, 02:32
Contact:

Re: ActiveScript - Host VBScript and JScript in-process

22 Oct 2021, 04:35

Thanks for the script, how Coco Lexikos got to make _OnScriptError work is amazing. :) The version for V1.1 Luddites here.
Edit: Attempting to paste VBScript code in with object references to WScript won't work AFAIK unless there are tricks.
:arrow: itros "ylbbub eht tuO kaerB" a ni kcuts m'I pleH
malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: ActiveScript - Host VBScript and JScript in-process

12 Apr 2023, 13:56

@lexikos, could You please tell why if We eval number > int32, then We get Double as result?

Code: Select all

js := new JsRT.Edge
msgbox % js.Eval("2147483648")
The same also is with v2:

Code: Select all

js := (JsRT.Edge)()
msgbox js.Eval("2147483648")

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: JoeWinograd, return and 76 guests