c# 跨域(CROSS-DOMAIN)取得Document对象

   1: // FREE code from CODECENTRIX
   2: // http://www.codecentrix.com/
   3: // http://codecentrix.blogspot.com/
   4: using System;
   5: using System.Runtime.InteropServices;
   6: using mshtml;
   7:  
   8:  
   9: namespace CodecentrixSample
  10: {
  11: public class CrossFrameIE
  12:     {
  13: // Returns null in case of failure.
  14: public static IHTMLDocument2 GetDocumentFromWindow(IHTMLWindow2 htmlWindow)
  15:         {
  16: if (htmlWindow == null)
  17:             {
  18: return null;
  19:             }
  20:  
  21: // First try the usual way to get the document.
  22: try
  23:             {
  24:                 IHTMLDocument2 doc = htmlWindow.document;
  25: return doc;
  26:             }
  27: catch (COMException comEx)
  28:             {
  29: // I think COMException won't be ever fired but just to be sure ...
  30: if (comEx.ErrorCode != E_ACCESSDENIED)
  31:                 {
  32: return null;
  33:                 }
  34:             }
  35: catch (System.UnauthorizedAccessException)
  36:             {
  37:             }
  38: catch
  39:             {
  40: // Any other error.
  41: return null;
  42:             }
  43:  
  44: // At this point the error was E_ACCESSDENIED because the frame contains a document from another domain.
  45: // IE tries to prevent a cross frame scripting security issue.
  46: try
  47:             {
  48: // Convert IHTMLWindow2 to IWebBrowser2 using IServiceProvider.
  49:                 IServiceProvider sp = (IServiceProvider)htmlWindow;
  50:  
  51: // Use IServiceProvider.QueryService to get IWebBrowser2 object.
  52:                 Object brws = null;
  53:                 sp.QueryService(ref IID_IWebBrowserApp, ref IID_IWebBrowser2, out brws);
  54:  
  55: // Get the document from IWebBrowser2.
  56:                 SHDocVw.IWebBrowser2 browser = (SHDocVw.IWebBrowser2)(brws);
  57:  
  58: return (IHTMLDocument2)browser.Document;
  59:             }
  60: catch
  61:             {
  62:             }
  63:  
  64: return null;
  65:         }
  66:  
  67: private const int  E_ACCESSDENIED      = unchecked((int)0x80070005L);
  68: private static Guid IID_IWebBrowserApp = new Guid("0002DF05-0000-0000-C000-000000000046");
  69: private static Guid IID_IWebBrowser2   = new Guid("D30C1661-CDAF-11D0-8A3E-00C04FC9E26E");
  70:     }
  71:  
  72: // This is the COM IServiceProvider interface, not System.IServiceProvider .Net interface!
  73:     [ComImport(), ComVisible(true), Guid("6D5140C1-7436-11CE-8034-00AA006009FA"),
  74:     InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
  75: public interface IServiceProvider
  76:     {
  77:             [return: MarshalAs(UnmanagedType.I4)][PreserveSig]
  78: int QueryService(ref Guid guidService, ref Guid riid, [MarshalAs(UnmanagedType.Interface)] out object ppvObject);
  79:     }
  80: }

[以上代码及以下内容,都是从墙外弄来的]

When IHTMLWindow2.document throws UnauthorizedAccessException

This is basically a C# translation of one of my older articles "When IHTMLWindow2::get_document returns E_ACCESSDENIED". Some .Net people encountered difficulties to use it, so I decided to make their life easier.
The main problem is the confusion created by System.IServiceProvider .Net interface because it has the same name as the COM interface. Once this issue is passed the code translation is straightforward. Here’s the interop code to declare the COM interface IServiceProvider.

// This is the COM IServiceProvider interface, not System.IServiceProvider .Net interface!
[ComImport(), ComVisible(true), Guid("6D5140C1-7436-11CE-8034-00AA006009FA"),
InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
public interface IServiceProvider
{
[return: MarshalAs(UnmanagedType.I4)][PreserveSig]
int QueryService(ref Guid guidService, ref Guid riid, [MarshalAs(UnmanagedType.Interface)] out object ppvObject);
}

You find here full source code of the sample assembly.
This technique was successfully implemented and tested in
Twebst web automation library.

[原文出处:http://codecentrix.blogspot.com/2008/02/when-ihtmlwindow2document-throws.html]