C# 反编译HtmlDocument';s调用脚本不工作
以下是我使用ILSpy获得的代码: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();
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);
}