How interesting. When we return the oGizmo object back to doSomethingWith , it is of type Windows Runtime Object . This behavior is compatible with JavaScript and VBScript.
Now, if we explicitly point MarshalAs(UnmanagedType.IUnknown) to the return value of the GiveMeAGizmo() method, everything works fine , the object can be dropped on Gizmo inside doSomethingWith :
[ComVisible(true), ClassInterface(ClassInterfaceType.AutoDispatch)] public class ObjectForScripting { [return: MarshalAs(UnmanagedType.IUnknown)] public object GiveMeAGizmo() { return new Gizmo(); } public object GiveMeAGizmoUser() { return new GizmoUser(); } }
However, if we specify UnmanagedType.IDispatch or UnmanagedType.Struct (by default this will marshal the object as COM VARIANT ), the problem will return.
Thus, there is a workaround, but so far there has not been a reasonable explanation for this interaction with the COM interface.
[UPDATE] A few experiments below. Please note that getting gizmo1 was successful, but gizmo2 is not:
C # :
// pass a Gizmo object to JavaScript this.webBrowser.Document.InvokeScript("SetGizmo", new Object[] { new Gizmo()}); // get it back, this works var gizmo1 = (Gizmo)this.webBrowser.Document.InvokeScript("GetGizmo"); // get a new Gizmo, via window.external.GiveMeAGizmo() // this fails var gizmo2 = (Gizmo)this.webBrowser.Document.InvokeScript("GetGizmo2");
JavaScript:
var _gizmo; function SetGizmo(gizmo) { _gizmo = gizmo; } function GetGizmo() { return _gizmo; } function GetGizmo2() { return window.external.GiveMeAGizmo(); }
This is just an assumption, but I think this behavior may have something to do with the .NET security permission sets imposed by WebBrowser.ObjectForScripting .
Noseratio
source share