C# 反编译HtmlDocument';s调用脚本不工作

C# 反编译HtmlDocument';s调用脚本不工作,c#,.net,reflection,webbrowser-control,ilspy,C#,.net,Reflection,Webbrowser Control,Ilspy,以下是我使用ILSpy获得的代码: public static object InvokeScript(this IHTMLDocument2 document, string scriptName, object[] args = null) { object result = null; UnsafeNativeMethods.tagDISPPARAMS tagDISPPARAMS = new UnsafeNativeMethods.tagDISPPARAMS();

以下是我使用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;
}
我还从这个方法中调用了一些其他方法。以下是我如何称呼它(注意是一个扩展方法):

但是行
int-iDsOfNames=dispatch.GetIDsOfNames(ref-empty,rgszNames,1,unsafentiveMethods.GetThreadLCID(),array)抛出一个
AccessViolationException
。有一件事我不确定,
unsafentivemethods.IDispatch dispatch=((IHTMLDocument)文档)行。实际的ILSpy行是
unsafentiveMethods.IDispatch dispatch=this.NativeHtmlDocument2.GetScript()作为unsafentiveMethods.IDispatch
但是由于某些原因,我没有
GetScript
方法

知道我做错了什么吗

编辑

这是我的简历:

    [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);
    }

编辑:GetIDsOfNames中的dispid参数是调用方提供的数组,因此不能使用[out](这意味着被调用方在COM堆上分配数组)

如果没有看到
unsafentiveMethods.IDispatch
的声明,很难判断,但是调用
GetIDsOfNames
而不固定dispid数组或向参数添加引用是错误的。如果通过按值传递地址来封送数组,则垃圾收集器可以在
GetIDsOfNames
调用仍在运行且本机代码返回时将写入一个野生指针时移动数组。如果将数组作为引用传递,那么代码将无法编译-需要向参数添加ref


您可以使用
System.Type.InvokeMember
方法通过脚本对象访问全局变量或函数。此方法为您调用
IDispatch::GetIDsOfNames
IDispatch::Invoke

是否在项目设置中选中了“允许不安全代码”?不确定此代码是否需要它,因为即使正在调用它,程序集中实际上也没有任何不安全的代码。还有,你为什么要将这些代码提取到你自己的程序集中?@karljohansjögren:我已经检查过允许不安全的代码了。我之所以需要它,是因为它将为您提供一个
IHtmlDocument2
,而不是
HtmlDocument
。请记住,您从(System.Windows.Forms.dll)获得此文件的程序集在系统中具有特定的权限。您创建的程序集可能不会。如果您在中等信任环境中运行此代码,您将无权运行不安全的代码。@PeterRitchie我明白了。看来这就是问题所在。这有什么办法吗?(我刚试着以管理员的身份运行它,但遇到了同样的问题,这是否意味着这是另一个问题?)它是.NET4.0中的新功能。看到和
    [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);
    }