铸造mshtml.IHTMLImgElement到mshtml.IHTMLElementRender

2019-10-18 04:55发布

我有推出新并且连接到现有的IE 10实例C#的.NET 4个WinForms应用程序(使用MSHTML 7)。 它通过所有的图片和下载他们操纵迭代。 因为图像已经被IE下载这种方法费时和冗余。

我已经找遍只有论坛的讨论屈指可数的主题,但都是能够施展mshtml.IHTMLImgElement对象mshtml.IHTMLElementRender(虽然在C ++代码)。

Unable to cast COM object of type 'mshtml.HTMLImgClass' to interface type 'mshtml.IHTMLElementRender'.
This operation failed because the QueryInterface call on the COM component for the interface with IID '{3050F669-98B5-11CF-BB82-00AA00BDCE0B}' failed due to the following error:
No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).

课程的目的是为了获取完整图像,从而替代方法亦欢迎。 这是导致上述异常的代码。

public static void Main (string [] args)
{
    mshtml.HTMLDocument document = null;
    SHDocVw.InternetExplorer explorer = null;
    System.IntPtr hdc = System.IntPtr.Zero;
    mshtml.IHTMLElementRender render = null;
    mshtml._RemotableHandle handle = default(mshtml._RemotableHandle);

    try
    {
        explorer = new SHDocVw.InternetExplorer();
        explorer.Visible = true;

        try
        {
            explorer.Navigate("http://www.google.com/ncr");

            while (explorer.Busy)
            {
                // Striped events for SO example.
                System.Threading.Thread.Sleep(100);
            }

            document = (mshtml.HTMLDocument) explorer.Document;

            foreach (mshtml.IHTMLImgElement image in document.images)
            {
                Console.WriteLine();

                if ((image.width > 0) && (image.height > 0))
                {
                    // The following [if] will return false if uncommented.
                    //if (image.GetType().GetInterfaces().ToList().Contains(typeof(mshtml.IHTMLElementRender)))
                    {
                        using (Bitmap bitmap = new Bitmap(image.width, image.height))
                        {
                            using (Graphics graphics = Graphics.FromImage(bitmap))
                            {
                                hdc = graphics.GetHdc();
                                handle.fContext = hdc.ToInt32();
                                render = (mshtml.IHTMLElementRender) image; // Causes the exception.
                                //handle = (mshtml._RemotableHandle) Marshal.PtrToStructure(hdc, typeof(mshtml._RemotableHandle));
                                render.DrawToDC(ref handle);
                                graphics.ReleaseHdc(hdc);

                                // Process image here.

                                Console.Write("Press any key to continue...");
                                Console.ReadKey();
                            }
                        }
                    }
                }
            }
        }
        catch (System.Exception e)
        {
            Console.WriteLine(e.Message);
            Console.WriteLine("Stack Trace: " + e.StackTrace);
        }

        explorer.Quit();
    }
    catch (System.Exception e)
    {
        Console.WriteLine(e.Message);
        Console.WriteLine("Stack Trace: " + e.StackTrace);
    }
    finally
    {
    }

#if (DEBUG)
        Console.WriteLine();
        Console.Write("Press any key to continue...");
        Console.ReadKey();
#endif
}

有些我曾经走过没有无济于事的链接:

  • 捕获的HTML文档作为图像
  • 无法转换类型“...”的接口类型COM对象“...”,而使用ExeCOMServer

Answer 1:

你可以很容易地看到与REGEDIT.EXE问题的根源。 为了使接口桥接进程边界之间的大峡谷,它需要实现的代理和接口存根代码。 知道如何序列化接口方法参数转换成可以从一个进程被传输到另一个的RPC分组的代码。

COM通过注册表查找发现的代码。 你也有REGEDIT.EXE可以导航到HKCR \接口和向下滚动相匹配的GUID。 你会看到很多看起来像{305xxxx-98B5-11CF-BB82-00AA00BDCE0B} {}的GUID那里。 是的,微软欺骗他们的GUID,调试容易,IE浏览器有相当多的人。 他们指出,标准编组,包括类型库GUID描述接口。

但你不会找到{3050F669-98B5-11CF-BB82-00AA00BDCE0B}。 这基本上是什么异常消息告诉你,它不能找到一种方法来封送接口指针。 神秘E_NOINTERFACE错误代码是的后退方法不工作或者,未能查询IMarshal结果。

这是一个有点之间“他们忘记”和“他们不能使它的工作”胜负难料的。 这其中很大程度上依靠对“太硬,使其工作”。 序列化渲染界面在这当然从来没有一台机器和另一之间相匹配的视频硬件方式太难了,太多的依赖。 甚至在一台机器,需要有图形流水线前的任何方法调用可以进行正确的初始化是太棘手。

这是真正的老板,你不能使这项工作。 你需要自己的渲染图像,不容易做到的。 对不起,请不要拍的使者。



文章来源: Casting mshtml.IHTMLImgElement to mshtml.IHTMLElementRender fails with E_NOINTERFACE