Here is the code I got using ILSpy:
public static object InvokeScript(this IHTMLDocument2 document, string scriptName, object[] args = null)
{
object result = null;
UnsafeNativeMethods.tagDISPPARAMS tagDISPPARAMS = new UnsafeNativeMethods.tagDISPPARAMS();
tagDISPPARAMS.rgvarg = IntPtr.Zero;
try
{
UnsafeNativeMethods.IDispatch dispatch = ((IHTMLDocument)document).Script as UnsafeNativeMethods.IDispatch;
if (dispatch != null)
{
Guid empty = Guid.Empty;
string[] rgszNames = new string[]
{
scriptName
};
int[] array = new int[]
{
-1
};
int iDsOfNames = dispatch.GetIDsOfNames(ref empty, rgszNames, 1, UnsafeNativeMethods.GetThreadLCID(), array);
if (UnsafeNativeMethods.Succeeded(iDsOfNames) && array[0] != -1)
{
if (args != null)
{
Array.Reverse(args);
}
tagDISPPARAMS.rgvarg = ((args == null) ? IntPtr.Zero : ArrayToVARIANTVector(args));
tagDISPPARAMS.cArgs = ((args == null) ? 0 : args.Length);
tagDISPPARAMS.rgdispidNamedArgs = IntPtr.Zero;
tagDISPPARAMS.cNamedArgs = 0;
object[] array2 = new object[1];
if (dispatch.Invoke(array[0], ref empty, UnsafeNativeMethods.GetThreadLCID(), 1, tagDISPPARAMS, array2, new UnsafeNativeMethods.tagEXCEPINFO(), null) == 0)
{
result = array2[0];
}
}
}
}
catch (Exception ex)
{
if (IsSecurityOrCriticalException(ex))
{
throw;
}
}
finally
{
if (tagDISPPARAMS.rgvarg != IntPtr.Zero)
{
FreeVARIANTVector(tagDISPPARAMS.rgvarg, args.Length);
}
}
return result;
}
I also got some of their other methods that are being called from this method. Here is how I call it (note is an extension method):
var doc = Browser.Document.DomDocument as IHTMLDocument2;
doc.InvokeScript("alert", new object[] { "hi" });
But the line int iDsOfNames = dispatch.GetIDsOfNames(ref empty, rgszNames, 1, UnsafeNativeMethods.GetThreadLCID(), array);
throws an AccessViolationException
. One thing I'm not sure about is the UnsafeNativeMethods.IDispatch dispatch = ((IHTMLDocument)document).Script as UnsafeNativeMethods.IDispatch;
line. The actual ILSpy line is UnsafeNativeMethods.IDispatch dispatch = this.NativeHtmlDocument2.GetScript() as UnsafeNativeMethods.IDispatch;
but for some reason I don't have the GetScript
method.
Any idea what am I doing wrong?
Edit
Here is my IDispatch:
[Guid("00020400-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), SuppressUnmanagedCodeSecurity]
[ComImport]
internal interface IDispatch
{
[SecurityCritical]
void GetTypeInfoCount(out uint pctinfo);
[SecurityCritical]
void GetTypeInfo(uint iTInfo, int lcid, out IntPtr info);
[SecurityCritical]
void GetIDsOfNames(ref Guid iid, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr, SizeParamIndex = 2)] string[] names, uint cNames, int lcid, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.I4, SizeParamIndex = 2)] [Out] int[] rgDispId);
[PreserveSig]
int GetIDsOfNames([In] ref Guid riid, [MarshalAs(UnmanagedType.LPArray)] [In] string[] rgszNames, [MarshalAs(UnmanagedType.U4)] [In] int cNames, [MarshalAs(UnmanagedType.U4)] [In] int lcid, [MarshalAs(UnmanagedType.LPArray)] [Out] int[] rgDispId);
[SecurityCritical]
void Invoke(int dispIdMember, ref Guid riid, int lcid, System.Runtime.InteropServices.ComTypes.INVOKEKIND wFlags, ref System.Runtime.InteropServices.ComTypes.DISPPARAMS pDispParams, IntPtr pvarResult, IntPtr pExcepInfo, IntPtr puArgErr);
[PreserveSig]
int Invoke(int dispIdMember, [In] ref Guid riid, [MarshalAs(UnmanagedType.U4)] [In] int lcid, [MarshalAs(UnmanagedType.U4)] [In] int dwFlags, [In] [Out] tagDISPPARAMS pDispParams, [MarshalAs(UnmanagedType.LPArray)] [Out] object[] pVarResult, [In] [Out] tagEXCEPINFO pExcepInfo, [MarshalAs(UnmanagedType.LPArray)] [Out] IntPtr[] pArgErr);
}