getElementById on element within an iframe

让人想犯罪 __ 提交于 2019-11-27 20:55:58

Try this:

Windows.Forms.HtmlWindow frame = WebBrowser1.Document.GetElementById("decrpt_ifr").Document.Window.Frames["decrpt_ifr"];
HtmlElement body = frame.Document.GetElementById("tinymce");
body.InnerHtml = "Hello, World!";

That gets the frame and treats it as a different document (because it is) and then it tries to get the element from its id. Good luck.

Edit: This should do the trick taking advantage of the dynamic datatype, and InternetExplorer interface:

private void Form1_Load(object sender, EventArgs e)
{
    foreach (InternetExplorer ie in new ShellWindows())
    {
        if (ie.LocationURL.ToString().IndexOf("tinymce") != -1)
        {
            IWebBrowserApp wb = (IWebBrowserApp)ie;
            wb.Document.Frames.Item[0].document.body.InnerHtml = "<p>Hello, World at </p> " + DateTime.Now.ToString();
        }
    }
}
noseratio

This answer was inspired by some research I recently did on using eval to inject script into an out-of-proc instance of Internet Explorer.

The idea is to bypass MSHTML DOM interop interfaces and use dynamic JavaScript to obtain a DOM object of interest. There are some implications:

To address the question itself, it should be quite easy to get the desired body element, using the approach illustrated below:

var tinymceBody = DispExInvoker.Invoke(ie.Document.parentWindow, "eval", "document.getElementById('decrpt_ifr').contentWindow.document.getElementById('tinymce')");

Here's a sample which executes alert(document.URL) in the context of a child frame of jsfiddle.net, by automating an out-of-proc instance of InternetExplorer.Application:

private async void Form1_Load(object sender, EventArgs ev)
{
    SHDocVw.InternetExplorer ie = new SHDocVw.InternetExplorer();
    ie.Visible = true;

    var documentCompleteTcs = new TaskCompletionSource<bool>();
    ie.DocumentComplete += delegate
    {
        if (documentCompleteTcs.Task.IsCompleted)
            return;
        documentCompleteTcs.SetResult(true);
    };

    ie.Navigate("http://jsfiddle.net/");
    await documentCompleteTcs.Task;

    // inject __execScript code into the top window
    var execScriptCode = "(window.__execScript = function(exp) { return eval(exp); }, window.self)";
    var window = DispExInvoker.Invoke(ie.Document.parentWindow, "eval", execScriptCode);

    // inject __execScript into a child iframe
    var iframe = DispExInvoker.Invoke(window, "__execScript", 
        String.Format("document.all.tags('iframe')[0].contentWindow.eval('{0}')",  execScriptCode));

    // invoke 'alert(document.URL)' in the context of the child frame
    DispExInvoker.Invoke(iframe, "__execScript", "alert(document.URL)");
}

/// <summary>
/// Managed wrapper for calling IDispatchEx::Invoke
/// https://stackoverflow.com/a/18349546/1768303
/// </summary>
public class DispExInvoker
{
    // check is the object supports IsDispatchEx
    public static bool IsDispatchEx(object target)
    {
        return target is IDispatchEx;
    }

    // invoke a method on the target IDispatchEx object
    public static object Invoke(object target, string method, params object[] args)
    {
        var dispEx = target as IDispatchEx;
        if (dispEx == null)
            throw new InvalidComObjectException();

        var dp = new System.Runtime.InteropServices.ComTypes.DISPPARAMS();
        try
        {
            // repack arguments
            if (args.Length > 0)
            {
                // should be using stackalloc for DISPPARAMS arguments, but don't want enforce "/unsafe"
                int size = SIZE_OF_VARIANT * args.Length;
                dp.rgvarg = Marshal.AllocCoTaskMem(size);
                ZeroMemory(dp.rgvarg, size); // zero'ing is equal to VariantInit
                dp.cArgs = args.Length;
                for (var i = 0; i < dp.cArgs; i++)
                    Marshal.GetNativeVariantForObject(args[i], dp.rgvarg + SIZE_OF_VARIANT * (args.Length - i - 1));
            }

            int dispid;
            dispEx.GetDispID(method, fdexNameCaseSensitive, out dispid);

            var ei = new System.Runtime.InteropServices.ComTypes.EXCEPINFO();
            var result = Type.Missing;
            dispEx.InvokeEx(dispid, 0, DISPATCH_METHOD, ref dp, ref result, ref ei, null);
            return result;
        }
        finally
        {
            if (dp.rgvarg != IntPtr.Zero)
            {
                for (var i = 0; i < dp.cArgs; i++)
                    VariantClear(dp.rgvarg + SIZE_OF_VARIANT * i);
                Marshal.FreeCoTaskMem(dp.rgvarg);
            }
        }
    }

    // interop declarations

    [DllImport("oleaut32.dll", PreserveSig = false)]
    static extern void VariantClear(IntPtr pvarg);
    [DllImport("Kernel32.dll", EntryPoint = "RtlZeroMemory", SetLastError = false)]
    static extern void ZeroMemory(IntPtr dest, int size);

    const uint fdexNameCaseSensitive = 0x00000001;
    const ushort DISPATCH_METHOD = 1;
    const int SIZE_OF_VARIANT = 16;

    // IDispatchEx interface

    [ComImport()]
    [Guid("A6EF9860-C720-11D0-9337-00A0C90DCAA9")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    internal interface IDispatchEx
    {
        // IDispatch
        int GetTypeInfoCount();
        [return: MarshalAs(UnmanagedType.Interface)]
        System.Runtime.InteropServices.ComTypes.ITypeInfo GetTypeInfo([In, MarshalAs(UnmanagedType.U4)] int iTInfo, [In, MarshalAs(UnmanagedType.U4)] int lcid);
        void GetIDsOfNames([In] ref Guid riid, [In, MarshalAs(UnmanagedType.LPArray)] string[] rgszNames, [In, MarshalAs(UnmanagedType.U4)] int cNames, [In, MarshalAs(UnmanagedType.U4)] int lcid, [Out, MarshalAs(UnmanagedType.LPArray)] int[] rgDispId);
        void Invoke(int dispIdMember, ref Guid riid, uint lcid, ushort wFlags, ref System.Runtime.InteropServices.ComTypes.DISPPARAMS pDispParams, out object pVarResult, ref System.Runtime.InteropServices.ComTypes.EXCEPINFO pExcepInfo, IntPtr[] pArgErr);

        // IDispatchEx
        void GetDispID([MarshalAs(UnmanagedType.BStr)] string bstrName, uint grfdex, [Out] out int pid);
        void InvokeEx(int id, uint lcid, ushort wFlags,
            [In] ref System.Runtime.InteropServices.ComTypes.DISPPARAMS pdp,
            [In, Out] ref object pvarRes,
            [In, Out] ref System.Runtime.InteropServices.ComTypes.EXCEPINFO pei,
            System.IServiceProvider pspCaller);
        void DeleteMemberByName([MarshalAs(UnmanagedType.BStr)] string bstrName, uint grfdex);
        void DeleteMemberByDispID(int id);
        void GetMemberProperties(int id, uint grfdexFetch, [Out] out uint pgrfdex);
        void GetMemberName(int id, [Out, MarshalAs(UnmanagedType.BStr)] out string pbstrName);
        [PreserveSig]
        [return: MarshalAs(UnmanagedType.I4)]
        int GetNextDispID(uint grfdex, int id, [In, Out] ref int pid);
        void GetNameSpaceParent([Out, MarshalAs(UnmanagedType.IUnknown)] out object ppunk);
    }
}
Vepa Durdiyev

Also another way would be to get url of that iframe and load that into your browser.

For me accepted solution is giving "Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))" error.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!