microsoft / ClearScript

A library for adding scripting to .NET applications. Supports V8 (Windows, Linux, macOS) and JScript/VBScript (Windows).
https://microsoft.github.io/ClearScript/
MIT License
1.74k stars 148 forks source link

Overwriting existing objects.. bug? #597

Closed juan-nxlevel closed 2 weeks ago

juan-nxlevel commented 2 weeks ago

Dear ClearScript: In the following code: Dim Script As VBScriptEngine = New VBScriptEngine(WindowsScriptEngineFlags.EnableDebugging) Script.NullExportValue = Microsoft.ClearScript.Windows.Nothing.Value Script.UndefinedImportValue = Nothing Script.AddHostType(GetType(Console))

    Dim doc1 As XmlDocument = New XmlDocument()
    doc1.LoadXml("<root id=""A""><page id=""1""/></root>")
    Script.AddHostObject("page", doc1.DocumentElement)
    Script.Execute("
        console.write(page.attributes(""id"").value)
    ")

    Dim doc2 As XmlDocument = New XmlDocument()
    doc2.LoadXml("<root id=""B""><page id=""2""/></root>")
    Script.AddHostObject("page", doc2.DocumentElement)
    Script.Execute("
        console.write(page.attributes(""id"").value)
    ")

The code above results in:

A A

So it appears that the 2nd AddHostObject did not overwrite the existing object doc1 with doc2. Since I am using the same object name of "page" then I would expect that the old "page" object be replaced by the new doc2, however this is not happening.
Would you have any suggestion to make it return "A", then "B" with the same object name of "page". ? Thanks!

ClearScriptLib commented 2 weeks ago

Hi @juan-nxlevel,

So it appears that the 2nd AddHostObject did not overwrite the existing object doc1 with doc2. Since I am using the same object name of "page" then I would expect that the old "page" object be replaced by the new doc2, however this is not happening.

When you call a Windows Script engine's AddHostObject or AddHostType method, you're creating a so-called host item. One of the ways in which a host item differs from other external objects is that the engine expects it not to change.

Because of that assumption, the engine retrieves a host item's value only once – the first time a script accesses it – and caches it thereafter. That's why the scripts in your example always see the same page object.

Host items are a very old Windows Script feature that's meant to be used for host APIs rather than data. ClearScript uses them because it's the only way to access certain functionality – e.g., GlobalMembers.

Would you have any suggestion to make it return "A", then "B" with the same object name of "page". ?

Yes! Instead of creating host items, you can set global properties:

Dim doc1 As XmlDocument = New XmlDocument()
doc1.LoadXml("<root id=""A""><page id=""1""/></root>")
Script.Global.SetProperty("page", doc1.DocumentElement)
Script.Execute("
    console.write(page.attributes(""id"").value)
")
Dim doc2 As XmlDocument = New XmlDocument()
doc2.LoadXml("<root id=""B""><page id=""2""/></root>")
Script.Global.SetProperty("page", doc2.DocumentElement)
Script.Execute("
    console.write(page.attributes(""id"").value)
")

Good luck!

juan-nxlevel commented 2 weeks ago

That works!. Thank you!