Skip to content

Instantly share code, notes, and snippets.

@poizan42
Last active October 25, 2019 14:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save poizan42/a46aa7025f5986d07bc08bd8a581ca6d to your computer and use it in GitHub Desktop.
Save poizan42/a46aa7025f5986d07bc08bd8a581ca6d to your computer and use it in GitHub Desktop.
ExecutionEngineException thrown when using ICustomQueryInterface to implement IDocHostUIHandler
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using IComDataObject = System.Runtime.InteropServices.ComTypes.IDataObject;
namespace WebBrowserCustomSiteTest
{
internal class CustomWebBrowser : WebBrowser
{
private class CustomWebBrowserSite : WebBrowserSite,
ICustomQueryInterface,
IDocHostUIHandler
{
private CustomWebBrowser host;
public CustomWebBrowserSite(CustomWebBrowser host)
: base(host)
{
this.host = host;
}
public CustomQueryInterfaceResult GetInterface(ref Guid iid, out IntPtr ppv)
{
if (iid == typeof(IDocHostUIHandler).GUID)
{
ppv = Marshal.GetComInterfaceForObject(this, typeof(IDocHostUIHandler), CustomQueryInterfaceMode.Ignore);
return CustomQueryInterfaceResult.Handled;
}
ppv = IntPtr.Zero;
return CustomQueryInterfaceResult.NotHandled;
}
int IDocHostUIHandler.ShowContextMenu(uint dwID, ref Point pt, object pcmdtReserved, object pdispReserved)
{
return (int)HRESULT.E_NOTIMPL;
}
int IDocHostUIHandler.GetHostInfo(DOCHOSTUIINFO info)
{
return (int)HRESULT.E_NOTIMPL;
}
int IDocHostUIHandler.ShowUI(int dwID, IOleInPlaceActiveObject activeObject, IOleCommandTarget commandTarget, IOleInPlaceFrame frame, IOleInPlaceUIWindow doc)
{
return (int)HRESULT.E_NOTIMPL;
}
int IDocHostUIHandler.HideUI()
{
return (int)HRESULT.E_NOTIMPL;
}
int IDocHostUIHandler.UpdateUI()
{
return (int)HRESULT.E_NOTIMPL;
}
int IDocHostUIHandler.EnableModeless(bool fEnable)
{
return (int)HRESULT.E_NOTIMPL;
}
int IDocHostUIHandler.OnDocWindowActivate(bool fActivate)
{
return (int)HRESULT.E_NOTIMPL;
}
int IDocHostUIHandler.OnFrameWindowActivate(bool fActivate)
{
return (int)HRESULT.E_NOTIMPL;
}
int IDocHostUIHandler.ResizeBorder(COMRECT rect, IOleInPlaceUIWindow doc, bool fFrameWindow)
{
return (int)HRESULT.E_NOTIMPL;
}
int IDocHostUIHandler.TranslateAccelerator(ref MSG msg, ref Guid group, int nCmdID)
{
return (int)HRESULT.E_NOTIMPL;
}
int IDocHostUIHandler.GetOptionKeyPath(string[] pbstrKey, int dw)
{
return (int)HRESULT.E_NOTIMPL;
}
HRESULT IDocHostUIHandler.GetDropTarget(IDropTarget pDropTarget, out IDropTarget ppDropTarget)
{
ppDropTarget = null;
return HRESULT.E_NOTIMPL;
}
int IDocHostUIHandler.GetExternal(out object ppDispatch)
{
ppDispatch = null;
return (int)HRESULT.E_NOTIMPL;
}
int IDocHostUIHandler.TranslateUrl(int dwTranslate, string strURLIn, out string pstrURLOut)
{
pstrURLOut = null;
return (int)HRESULT.E_NOTIMPL;
}
int IDocHostUIHandler.FilterDataObject(IComDataObject pDO, out IComDataObject ppDORet)
{
ppDORet = null;
return (int)HRESULT.E_NOTIMPL;
}
}
protected override WebBrowserSiteBase CreateWebBrowserSiteBase()
{
return new CustomWebBrowserSite(this);
}
}
// Used to control the webbrowser appearance and provide DTE to script via window.external
[ComVisible(true), ComImport(), Guid("BD3F23C0-D43E-11CF-893B-00AA00BDCE1A"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IDocHostUIHandler
{
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int ShowContextMenu(
uint dwID,
ref Point pt,
[In, MarshalAs(UnmanagedType.Interface)]
object pcmdtReserved,
[In, MarshalAs(UnmanagedType.Interface)]
object pdispReserved);
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int GetHostInfo(
[In, Out]
DOCHOSTUIINFO info);
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int ShowUI(
[In, MarshalAs(UnmanagedType.I4)]
int dwID,
[In]
IOleInPlaceActiveObject activeObject,
[In]
IOleCommandTarget commandTarget,
[In]
IOleInPlaceFrame frame,
[In]
IOleInPlaceUIWindow doc);
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int HideUI();
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int UpdateUI();
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int EnableModeless(
[In, MarshalAs(UnmanagedType.Bool)]
bool fEnable);
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int OnDocWindowActivate(
[In, MarshalAs(UnmanagedType.Bool)]
bool fActivate);
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int OnFrameWindowActivate(
[In, MarshalAs(UnmanagedType.Bool)]
bool fActivate);
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int ResizeBorder(
[In]
COMRECT rect,
[In]
IOleInPlaceUIWindow doc,
bool fFrameWindow);
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int TranslateAccelerator(
[In]
ref MSG msg,
[In]
ref Guid group,
[In, MarshalAs(UnmanagedType.I4)]
int nCmdID);
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int GetOptionKeyPath(
[Out, MarshalAs(UnmanagedType.LPArray)]
string[] pbstrKey,
[In, MarshalAs(UnmanagedType.U4)]
int dw);
[PreserveSig]
HRESULT GetDropTarget(
IDropTarget pDropTarget,
out IDropTarget ppDropTarget);
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int GetExternal(
[Out, MarshalAs(UnmanagedType.Interface)]
out object ppDispatch);
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int TranslateUrl(
[In, MarshalAs(UnmanagedType.U4)]
int dwTranslate,
[In, MarshalAs(UnmanagedType.LPWStr)]
string strURLIn,
[Out, MarshalAs(UnmanagedType.LPWStr)]
out string pstrURLOut);
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int FilterDataObject(
IComDataObject pDO,
out IComDataObject ppDORet);
}
[StructLayout(LayoutKind.Sequential)]
public class OLECMD
{
[MarshalAs(UnmanagedType.U4)]
public int cmdID = 0;
[MarshalAs(UnmanagedType.U4)]
public int cmdf = 0;
}
[ComVisible(true)]
[ComImport]
[Guid("B722BCCB-4E68-101B-A2BC-00AA00404770")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IOleCommandTarget
{
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int QueryStatus(
ref Guid pguidCmdGroup,
int cCmds,
[In, Out]
OLECMD prgCmds,
[In, Out]
IntPtr pCmdText);
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int Exec(
ref Guid pguidCmdGroup,
int nCmdID,
int nCmdexecopt,
// we need to have this an array because callers need to be able to specify NULL or VT_NULL
[In, MarshalAs(UnmanagedType.LPArray)]
object[] pvaIn,
int pvaOut);
}
public interface IOleInPlaceFrame
{
IntPtr GetWindow();
[PreserveSig]
int ContextSensitiveHelp(int fEnterMode);
[PreserveSig]
int GetBorder(
[Out]
COMRECT lprectBorder);
[PreserveSig]
int RequestBorderSpace(
[In]
COMRECT pborderwidths);
[PreserveSig]
int SetBorderSpace(
[In]
COMRECT pborderwidths);
[PreserveSig]
int SetActiveObject(
[In, MarshalAs(UnmanagedType.Interface)]
IOleInPlaceActiveObject pActiveObject,
[In, MarshalAs(UnmanagedType.LPWStr)]
string pszObjName);
[PreserveSig]
int InsertMenus(
[In]
IntPtr hmenuShared,
[In, Out]
tagOleMenuGroupWidths lpMenuWidths);
[PreserveSig]
int SetMenu(
[In]
IntPtr hmenuShared,
[In]
IntPtr holemenu,
[In]
IntPtr hwndActiveObject);
[PreserveSig]
int RemoveMenus(
[In]
IntPtr hmenuShared);
[PreserveSig]
int SetStatusText(
[In, MarshalAs(UnmanagedType.LPWStr)]
string pszStatusText);
[PreserveSig]
int EnableModeless(
bool fEnable);
[PreserveSig]
int TranslateAccelerator(
[In]
ref MSG lpmsg,
[In, MarshalAs(UnmanagedType.U2)]
short wID);
}
[StructLayout(LayoutKind.Sequential)/*leftover(noAutoOffset)*/]
public sealed class tagOleMenuGroupWidths
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)/*leftover(offset=0, widths)*/]
public int[] widths = new int[6];
}
[StructLayout(LayoutKind.Sequential)]
public struct MSG
{
public IntPtr hwnd;
public int message;
public IntPtr wParam;
public IntPtr lParam;
public int time;
public Point pt;
}
[StructLayout(LayoutKind.Sequential)]
public class COMRECT
{
public int left;
public int top;
public int right;
public int bottom;
public COMRECT()
{
}
public COMRECT(Rectangle r)
{
left = r.X;
top = r.Y;
right = r.Right;
bottom = r.Bottom;
}
public COMRECT(int left, int top, int right, int bottom)
{
this.left = left;
this.top = top;
this.right = right;
this.bottom = bottom;
}
public static COMRECT FromXYWH(int x, int y, int width, int height)
{
return new COMRECT(x, y, x + width, y + height);
}
public override string ToString()
{
return "Left = " + left + " Top " + top + " Right = " + right + " Bottom = " + bottom;
}
}
[ComImport(), Guid("00000115-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IOleInPlaceUIWindow
{
IntPtr GetWindow();
[PreserveSig]
int ContextSensitiveHelp(
int fEnterMode);
[PreserveSig]
int GetBorder(
[Out]
COMRECT lprectBorder);
[PreserveSig]
int RequestBorderSpace(
[In]
COMRECT pborderwidths);
[PreserveSig]
int SetBorderSpace(
[In]
COMRECT pborderwidths);
void SetActiveObject(
[In, MarshalAs(UnmanagedType.Interface)]
IOleInPlaceActiveObject pActiveObject,
[In, MarshalAs(UnmanagedType.LPWStr)]
string pszObjName);
}
[ComImport(),
Guid("00000117-0000-0000-C000-000000000046"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IOleInPlaceActiveObject
{
[PreserveSig]
int GetWindow(out IntPtr hwnd);
void ContextSensitiveHelp(
int fEnterMode);
[PreserveSig]
int TranslateAccelerator(
[In]
ref MSG lpmsg);
void OnFrameWindowActivate(
bool fActivate);
void OnDocWindowActivate(
int fActivate);
void ResizeBorder(
[In]
COMRECT prcBorder,
[In]
IOleInPlaceUIWindow pUIWindow,
bool fFrameWindow);
void EnableModeless(
int fEnable);
}
[ComImport]
[Guid("00000122-0000-0000-C000-000000000046")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IDropTarget
{
[PreserveSig]
HRESULT DragEnter(
[MarshalAs(UnmanagedType.Interface)]
object pDataObj,
uint grfKeyState,
Point pt,
ref uint pdwEffect);
[PreserveSig]
HRESULT DragOver(
uint grfKeyState,
Point pt,
ref uint pdwEffect);
[PreserveSig]
HRESULT DragLeave();
[PreserveSig]
HRESULT Drop(
[MarshalAs(UnmanagedType.Interface)]
object pDataObj,
uint grfKeyState,
Point pt,
ref uint pdwEffect);
}
public enum HRESULT : int
{
S_OK = 0,
S_FALSE = 1,
E_NOTIMPL = unchecked((int)0x80004001)
}
public class DOCHOSTUIINFO
{
[MarshalAs(UnmanagedType.U4)]
public int cbSize = Marshal.SizeOf(typeof(DOCHOSTUIINFO));
[MarshalAs(UnmanagedType.I4)]
public int dwFlags;
[MarshalAs(UnmanagedType.I4)]
public int dwDoubleClick;
[MarshalAs(UnmanagedType.I4)]
public int dwReserved1 = 0;
[MarshalAs(UnmanagedType.I4)]
public int dwReserved2 = 0;
}
internal enum DOCHOSTUIFLAG
{
DIALOG = 0x1,
DISABLE_HELP_MENU = 0x2,
NO3DBORDER = 0x4,
SCROLL_NO = 0x8,
DISABLE_SCRIPT_INACTIVE = 0x10,
OPENNEWWIN = 0x20,
DISABLE_OFFSCREEN = 0x40,
FLAT_SCROLLBAR = 0x80,
DIV_BLOCKDEFAULT = 0x100,
ACTIVATE_CLIENTHIT_ONLY = 0x200,
NO3DOUTERBORDER = 0x00200000,
THEME = 0x00040000,
NOTHEME = 0x80000,
DISABLE_COOKIE = 0x400
}
internal enum DOCHOSTUIDBLCLICK
{
DEFAULT = 0x0,
SHOWPROPERTIES = 0x1,
SHOWCODE = 0x2
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
CustomWebBrowser wb = new CustomWebBrowser();
wb.Dock = DockStyle.Fill;
Controls.Add(wb);
wb.Navigate("https://bing.com");
}
}
}
namespace WebBrowserCustomSiteTest
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Text = "Form1";
}
#endregion
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WebBrowserCustomSiteTest
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.SetHighDpiMode(HighDpiMode.SystemAware);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
<ApplicationIcon />
<StartupObject />
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
</Project>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment