【发布时间】:2012-08-09 01:48:09
【问题描述】:
这是我使用 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;
}
我还得到了他们的一些其他方法,这些方法是从这个方法中调用的。我是这样称呼它的(注意是扩展方法):
var doc = Browser.Document.DomDocument as IHTMLDocument2;
doc.InvokeScript("alert", new object[] { "hi" });
但是int iDsOfNames = dispatch.GetIDsOfNames(ref empty, rgszNames, 1, UnsafeNativeMethods.GetThreadLCID(), array); 会抛出AccessViolationException。我不确定的一件事是UnsafeNativeMethods.IDispatch dispatch = ((IHTMLDocument)document).Script as UnsafeNativeMethods.IDispatch; 行。实际的 ILSpy 行是 UnsafeNativeMethods.IDispatch dispatch = this.NativeHtmlDocument2.GetScript() as UnsafeNativeMethods.IDispatch;,但由于某种原因,我没有 GetScript 方法。
知道我做错了什么吗?
编辑
这是我的 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);
}
【问题讨论】:
-
您是否在项目设置中选中了“允许不安全代码”?不确定此代码是否需要它,因为即使正在调用它,您的程序集中实际上也没有任何不安全的代码。另外,你为什么要把这段代码提取到你自己的程序集中?
-
@Karl-JohanSjögren:我已经检查了允许不安全代码。我需要这个的原因是因为this method 会给你一个
IHtmlDocument2而不是HtmlDocument。 -
请记住,您从 (System.Windows.Forms.dll) 获得的程序集在系统中具有特定权限。您创建的程序集可能不会。如果您在中等信任环境中运行此代码,您将无权运行不安全代码。
-
@PeterRitchie 我明白了。好像这就是问题所在。有没有办法解决? (我刚刚尝试以管理员身份运行它,但遇到了同样的问题,这是否意味着这是另一个问题?)
标签: c# .net reflection webbrowser-control ilspy