c# Webbrowsercontrol与代理和调用从Javascript到c#
本文关键字:Javascript 调用 Webbrowsercontrol 代理 | 更新日期: 2023-09-27 18:15:14
我结合了webbrowsercontrol ObjectForScripting(源)的功能,从javascript调用c#函数,并为该webbrowser控件(源)提供代理。
每个函数各自工作。但是当我把它们结合起来时,javascript的调用不再工作了。Errormessage is
对象不支持"Test"属性或方法
示例的源代码在底部。
您可以在Form1_Load
// Comment this block for Callback working
object obj = webBrowser1.ActiveXInstance;
IOleObject oc = obj as IOleObject;
oc.SetClientSite(Proxy as IOleClientSite);
我猜问题是接口IServiceProvider
的功能QueryService
。我试图用Scriptmanager
的GUID来确定它,但没有找到解决方案。
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace ProxyTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
proxy Proxy = new proxy();
private void Form1_Load(object sender, EventArgs e)
{
webBrowser1.Navigate("about:blank");
// Comment this block for Callback working
object obj = webBrowser1.ActiveXInstance;
IOleObject oc = obj as IOleObject;
oc.SetClientSite(Proxy as IOleClientSite);
//Proxy settings are not necessary
Proxy._currentUsername = ""; // Username
Proxy._currentPassword = ""; // Password
Proxy.SetProxyServer(""); //IP:PORT
webBrowser1.ObjectForScripting = new Scriptmanager();
Application.DoEvents();
webBrowser1.DocumentText =
"<html><head><script>" +
"function test(message) { alert(message); }" +
"</script></head><body><button " +
"onclick='"window.external.Test('called from script code')'">" +
"call client code from script code</button>" +
"</body></html>";
}
}
[ComVisible(true)]
public class Scriptmanager
{
public void Test(string text)
{
MessageBox.Show(text);
}
}
public class proxy : IOleClientSite, IServiceProvider, IAuthenticate
{
[DllImport("wininet.dll", SetLastError = true)]
private static extern bool InternetSetOption(IntPtr hInternet, int dwOption,
IntPtr lpBuffer, int lpdwBufferLength);
private Guid IID_IAuthenticate = new Guid("79eac9d0-baf9-11ce-8c82-00aa004ba90b");
private const int INET_E_DEFAULT_ACTION = unchecked((int)0x800C0011);
private const int S_OK = unchecked((int)0x00000000);
private const int INTERNET_OPTION_PROXY = 38;
private const int INTERNET_OPEN_TYPE_DIRECT = 1;
private const int INTERNET_OPEN_TYPE_PROXY = 3;
internal string _currentUsername;
internal string _currentPassword;
internal void SetProxyServer(string proxy)
{
//Create structure
INTERNET_PROXY_INFO proxyInfo = new INTERNET_PROXY_INFO();
if (proxy == null)
{
proxyInfo.dwAccessType = INTERNET_OPEN_TYPE_DIRECT;
}
else
{
proxyInfo.dwAccessType = INTERNET_OPEN_TYPE_PROXY;
proxyInfo.proxy = Marshal.StringToHGlobalAnsi(proxy);
proxyInfo.proxyBypass = Marshal.StringToHGlobalAnsi("local");
}
// Allocate memory
IntPtr proxyInfoPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(proxyInfo));
// Convert structure to IntPtr
Marshal.StructureToPtr(proxyInfo, proxyInfoPtr, true);
bool returnValue = InternetSetOption(IntPtr.Zero, INTERNET_OPTION_PROXY,
proxyInfoPtr, Marshal.SizeOf(proxyInfo));
}
#region IOleClientSite Members
public void SaveObject()
{
// TODO: Add Form1.SaveObject implementation
}
public void GetMoniker(uint dwAssign, uint dwWhichMoniker, object ppmk)
{
// TODO: Add Form1.GetMoniker implementation
}
public void GetContainer(object ppContainer)
{
ppContainer = this;
}
public void ShowObject()
{
// TODO: Add Form1.ShowObject implementation
}
public void OnShowWindow(bool fShow)
{
// TODO: Add Form1.OnShowWindow implementation
}
public void RequestNewObjectLayout()
{
// TODO: Add Form1.RequestNewObjectLayout implementation
}
#endregion
#region IServiceProvider Members
public int QueryService(ref Guid guidService, ref Guid riid, out IntPtr ppvObject)
{
int nRet = guidService.CompareTo(IID_IAuthenticate);
if (nRet == 0)
{
nRet = riid.CompareTo(IID_IAuthenticate);
if (nRet == 0)
{
ppvObject = Marshal.GetComInterfaceForObject(this, typeof(IAuthenticate));
return S_OK;
}
}
ppvObject = new IntPtr();
return INET_E_DEFAULT_ACTION;
}
#endregion
#region IAuthenticate Members
public int Authenticate(ref IntPtr phwnd, ref IntPtr pszUsername, ref IntPtr pszPassword)
{
IntPtr sUser = Marshal.StringToCoTaskMemAuto(_currentUsername);
IntPtr sPassword = Marshal.StringToCoTaskMemAuto(_currentPassword);
pszUsername = sUser;
pszPassword = sPassword;
return S_OK;
}
#endregion
}
public struct INTERNET_PROXY_INFO
{
public int dwAccessType;
public IntPtr proxy;
public IntPtr proxyBypass;
}
#region COM Interfaces
[ComImport, Guid("00000112-0000-0000-C000-000000000046"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IOleObject
{
void SetClientSite(IOleClientSite pClientSite);
void GetClientSite(IOleClientSite ppClientSite);
void SetHostNames(object szContainerApp, object szContainerObj);
void Close(uint dwSaveOption);
void SetMoniker(uint dwWhichMoniker, object pmk);
void GetMoniker(uint dwAssign, uint dwWhichMoniker, object ppmk);
void InitFromData(IDataObject pDataObject, bool
fCreation, uint dwReserved);
void GetClipboardData(uint dwReserved, IDataObject ppDataObject);
void DoVerb(uint iVerb, uint lpmsg, object pActiveSite,
uint lindex, uint hwndParent, uint lprcPosRect);
void EnumVerbs(object ppEnumOleVerb);
void Update();
void IsUpToDate();
void GetUserClassID(uint pClsid);
void GetUserType(uint dwFormOfType, uint pszUserType);
void SetExtent(uint dwDrawAspect, uint psizel);
void GetExtent(uint dwDrawAspect, uint psizel);
void Advise(object pAdvSink, uint pdwConnection);
void Unadvise(uint dwConnection);
void EnumAdvise(object ppenumAdvise);
void GetMiscStatus(uint dwAspect, uint pdwStatus);
void SetColorScheme(object pLogpal);
}
[ComImport, Guid("00000118-0000-0000-C000-000000000046"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IOleClientSite
{
void SaveObject();
void GetMoniker(uint dwAssign, uint dwWhichMoniker, object ppmk);
void GetContainer(object ppContainer);
void ShowObject();
void OnShowWindow(bool fShow);
void RequestNewObjectLayout();
}
[ComImport, GuidAttribute("6d5140c1-7436-11ce-8034-00aa006009fa"),
InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown),
ComVisible(false)]
public interface IServiceProvider
{
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int QueryService(ref Guid guidService, ref Guid riid, out IntPtr ppvObject);
}
[ComImport, GuidAttribute("79EAC9D0-BAF9-11CE-8C82-00AA004BA90B"),
InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown),
ComVisible(false)]
public interface IAuthenticate
{
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int Authenticate(ref IntPtr phwnd, ref IntPtr pszUsername, ref IntPtr pszPassword);
}
#endregion
}
更新01.11.2016 盛江的这个建议真的很好。我差不多有一个可行的例子了。单击后显示消息框。不幸的是,之后会出现InvalidVariant异常。有人能猜出是怎么回事吗?我又卡住了。下面是当前代码:
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace ProxyTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
proxy Proxy = new proxy();
private void Form1_Load(object sender, EventArgs e)
{
webBrowser1.Navigate("about:blank");
// Comment this block for Callback working
object obj = webBrowser1.ActiveXInstance;
IOleObject oc = obj as IOleObject;
oc.SetClientSite(Proxy as IOleClientSite);
//Proxy settings are not necessary
Proxy._currentUsername = ""; // Username
Proxy._currentPassword = ""; // Password
Proxy.SetProxyServer(""); //IP:PORT
webBrowser1.ObjectForScripting = new Scriptmanager();
Application.DoEvents();
webBrowser1.DocumentText =
"<html><head><script>" +
"function test(message) { alert(message); }" +
"</script></head><body><button " +
"onclick='"window.external.Test('called from script code')'">" +
"call client code from script code</button>" +
"</body></html>";
}
}
[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IScriptmanager
{
void Test(string text);
}
[ComVisible(true)]
public class Scriptmanager : IScriptmanager
{
public void Test(string text)
{
MessageBox.Show(text);
}
}
public class proxy : IOleClientSite, IServiceProvider, IAuthenticate, IDocHostUIHandler
{
[DllImport("wininet.dll", SetLastError = true)]
private static extern bool InternetSetOption(IntPtr hInternet, int dwOption,
IntPtr lpBuffer, int lpdwBufferLength);
private Guid IID_IAuthenticate = new Guid("79eac9d0-baf9-11ce-8c82-00aa004ba90b");
private const int INET_E_DEFAULT_ACTION = unchecked((int)0x800C0011);
private const int S_OK = unchecked((int)0x00000000);
private const int INTERNET_OPTION_PROXY = 38;
private const int INTERNET_OPEN_TYPE_DIRECT = 1;
private const int INTERNET_OPEN_TYPE_PROXY = 3;
internal string _currentUsername;
internal string _currentPassword;
IDocHostUIHandler _baseIDocHostUIHandler;
internal void SetProxyServer(string proxy)
{
//Create structure
INTERNET_PROXY_INFO proxyInfo = new INTERNET_PROXY_INFO();
if (proxy == null)
{
proxyInfo.dwAccessType = INTERNET_OPEN_TYPE_DIRECT;
}
else
{
proxyInfo.dwAccessType = INTERNET_OPEN_TYPE_PROXY;
proxyInfo.proxy = Marshal.StringToHGlobalAnsi(proxy);
proxyInfo.proxyBypass = Marshal.StringToHGlobalAnsi("local");
}
// Allocate memory
IntPtr proxyInfoPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(proxyInfo));
// Convert structure to IntPtr
Marshal.StructureToPtr(proxyInfo, proxyInfoPtr, true);
bool returnValue = InternetSetOption(IntPtr.Zero, INTERNET_OPTION_PROXY,
proxyInfoPtr, Marshal.SizeOf(proxyInfo));
}
#region IOleClientSite Members
public void SaveObject()
{
// TODO: Add Form1.SaveObject implementation
}
public void GetMoniker(uint dwAssign, uint dwWhichMoniker, object ppmk)
{
// TODO: Add Form1.GetMoniker implementation
}
public void GetContainer(object ppContainer)
{
ppContainer = this;
}
public void ShowObject()
{
// TODO: Add Form1.ShowObject implementation
}
public void OnShowWindow(bool fShow)
{
// TODO: Add Form1.OnShowWindow implementation
}
public void RequestNewObjectLayout()
{
// TODO: Add Form1.RequestNewObjectLayout implementation
}
#endregion
#region IServiceProvider Members
public int QueryService(ref Guid guidService, ref Guid riid, out IntPtr ppvObject)
{
int nRet = guidService.CompareTo(IID_IAuthenticate);
if (nRet == 0)
{
nRet = riid.CompareTo(IID_IAuthenticate);
if (nRet == 0)
{
ppvObject = Marshal.GetComInterfaceForObject(this, typeof(IAuthenticate));
return S_OK;
}
}
ppvObject = new IntPtr();
return INET_E_DEFAULT_ACTION;
}
#endregion
#region IAuthenticate Members
public int Authenticate(ref IntPtr phwnd, ref IntPtr pszUsername, ref IntPtr pszPassword)
{
IntPtr sUser = Marshal.StringToCoTaskMemAuto(_currentUsername);
IntPtr sPassword = Marshal.StringToCoTaskMemAuto(_currentPassword);
pszUsername = sUser;
pszPassword = sPassword;
return S_OK;
}
#endregion
#region IDocHostUIHandler Members
public uint ShowContextMenu(uint dwID, ref tagPOINT ppt, [MarshalAs(UnmanagedType.IUnknown)] object pcmdtReserved, [MarshalAs(UnmanagedType.IDispatch)] object pdispReserved)
{
const int MenuNotHandled = 1;
return MenuNotHandled;
}
public void GetHostInfo(ref DOCHOSTUIINFO pInfo)
{
// turn three flags on
pInfo.dwFlags |= (uint)(DOCHOSTUIFLAG.DOCHOSTUIFLAG_SCROLL_NO |
DOCHOSTUIFLAG.DOCHOSTUIFLAG_NO3DBORDER |
DOCHOSTUIFLAG.DOCHOSTUIFLAG_DISABLE_SCRIPT_INACTIVE);
}
public void ShowUI(uint dwID, ref object pActiveObject, ref object pCommandTarget, ref object pFrame, ref object pDoc)
{
//throw new NotImplementedException();
}
public void HideUI()
{
// throw new NotImplementedException();
}
public void UpdateUI()
{
// throw new NotImplementedException();
}
public void EnableModeless(int fEnable)
{
//throw new NotImplementedException();
}
public void OnDocWindowActivate(int fActivate)
{
//throw new NotImplementedException();
}
public void OnFrameWindowActivate(int fActivate)
{
//throw new NotImplementedException();
}
public void ResizeBorder(ref tagRECT prcBorder, int pUIWindow, int fFrameWindow)
{
//throw new NotImplementedException();
}
public uint TranslateAccelerator(ref tagMSG lpMsg, ref Guid pguidCmdGroup, uint nCmdID)
{
const int KillAccelerator = 0;
const int AllowAccelerator = 1;
const int WM_KEYDOWN = 0x0100;
if (lpMsg.message != WM_KEYDOWN)
// allow message
return AllowAccelerator;
if ((Control.ModifierKeys & Keys.Control) != Keys.Control)
return AllowAccelerator;
// disable the Ctrl-N and Ctrl-P accelerators
lpMsg.wParam &= 0xFF; // get the virtual keycode
if ((lpMsg.wParam == 'N') || ((lpMsg.wParam == 'P')))
return KillAccelerator;
// allow everything else
return AllowAccelerator;
}
public void GetOptionKeyPath([MarshalAs(UnmanagedType.BStr)] ref string pchKey, uint dw)
{
// throw new NotImplementedException();
}
public uint GetDropTarget(int pDropTarget, ref int ppDropTarget)
{
const int S_OK = 0;
return S_OK;
}
//public object GetDropTarget(ref object pDropTarget)
//{
// return pDropTarget;
//}
public void GetExternal([MarshalAs(UnmanagedType.IDispatch)] out object ppDispatch)
{
ppDispatch = new Scriptmanager();
}
public uint TranslateUrl(uint dwTranslate, [MarshalAs(UnmanagedType.BStr)] string pchURLIn, [MarshalAs(UnmanagedType.BStr)] ref string ppchURLOut)
{
const int NotTranslated = 1;
return NotTranslated;
}
public IDataObject FilterDataObject(IDataObject pDO)
{
return null;
}
#endregion
}
public struct INTERNET_PROXY_INFO
{
public int dwAccessType;
public IntPtr proxy;
public IntPtr proxyBypass;
}
public struct tagRECT
{
public int left;
public int top;
public int right;
public int bottom;
}
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct tagPOINT
{
public int x;
public int y;
}
public enum DOCHOSTUITYPE
{
DOCHOSTUITYPE_BROWSE = 0,
DOCHOSTUITYPE_AUTHOR = 1
}
public enum DOCHOSTUIDBLCLK
{
DOCHOSTUIDBLCLK_DEFAULT = 0,
DOCHOSTUIDBLCLK_SHOWPROPERTIES = 1,
DOCHOSTUIDBLCLK_SHOWCODE = 2
}
[Flags()]
public enum DOCHOSTUIFLAG
{
DOCHOSTUIFLAG_DIALOG = 0x00000001,
DOCHOSTUIFLAG_DISABLE_HELP_MENU = 0x00000002,
DOCHOSTUIFLAG_NO3DBORDER = 0x00000004,
DOCHOSTUIFLAG_SCROLL_NO = 0x00000008,
DOCHOSTUIFLAG_DISABLE_SCRIPT_INACTIVE = 0x00000010,
DOCHOSTUIFLAG_OPENNEWWIN = 0x00000020,
DOCHOSTUIFLAG_DISABLE_OFFSCREEN = 0x00000040,
DOCHOSTUIFLAG_FLAT_SCROLLBAR = 0x00000080,
DOCHOSTUIFLAG_DIV_BLOCKDEFAULT = 0x00000100,
DOCHOSTUIFLAG_ACTIVATE_CLIENTHIT_ONLY = 0x00000200,
DOCHOSTUIFLAG_OVERRIDEBEHAVIORFACTORY = 0x00000400,
DOCHOSTUIFLAG_CODEPAGELINKEDFONTS = 0x00000800,
DOCHOSTUIFLAG_URL_ENCODING_DISABLE_UTF8 = 0x00001000,
DOCHOSTUIFLAG_URL_ENCODING_ENABLE_UTF8 = 0x00002000,
DOCHOSTUIFLAG_ENABLE_FORMS_AUTOCOMPLETE = 0x00004000,
DOCHOSTUIFLAG_ENABLE_INPLACE_NAVIGATION = 0x00010000,
DOCHOSTUIFLAG_IME_ENABLE_RECONVERSION = 0x00020000,
DOCHOSTUIFLAG_THEME = 0x00040000,
DOCHOSTUIFLAG_NOTHEME = 0x00080000,
DOCHOSTUIFLAG_NOPICS = 0x00100000,
DOCHOSTUIFLAG_NO3DOUTERBORDER = 0x00200000,
DOCHOSTUIFLAG_DISABLE_EDIT_NS_FIXUP = 0x400000,
DOCHOSTUIFLAG_LOCAL_MACHINE_ACCESS_CHECK = 0x800000,
DOCHOSTUIFLAG_DISABLE_UNTRUSTEDPROTOCOL = 0x1000000
}
[StructLayout(LayoutKind.Sequential)]
public struct DOCHOSTUIINFO
{
public uint cbSize;
public uint dwFlags;
public uint dwDoubleClick;
[MarshalAs(UnmanagedType.BStr)]
public string pchHostCss;
[MarshalAs(UnmanagedType.BStr)]
public string pchHostNS;
}
[StructLayout(LayoutKind.Sequential)]
public struct tagMSG
{
public IntPtr hwnd;
public uint message;
public uint wParam;
public int lParam;
public uint time;
public tagPOINT pt;
}
#region COM Interfaces
[ComImport, Guid("00000112-0000-0000-C000-000000000046"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IOleObject
{
void SetClientSite(IOleClientSite pClientSite);
void GetClientSite(IOleClientSite ppClientSite);
void SetHostNames(object szContainerApp, object szContainerObj);
void Close(uint dwSaveOption);
void SetMoniker(uint dwWhichMoniker, object pmk);
void GetMoniker(uint dwAssign, uint dwWhichMoniker, object ppmk);
void InitFromData(IDataObject pDataObject, bool
fCreation, uint dwReserved);
void GetClipboardData(uint dwReserved, IDataObject ppDataObject);
void DoVerb(uint iVerb, uint lpmsg, object pActiveSite,
uint lindex, uint hwndParent, uint lprcPosRect);
void EnumVerbs(object ppEnumOleVerb);
void Update();
void IsUpToDate();
void GetUserClassID(uint pClsid);
void GetUserType(uint dwFormOfType, uint pszUserType);
void SetExtent(uint dwDrawAspect, uint psizel);
void GetExtent(uint dwDrawAspect, uint psizel);
void Advise(object pAdvSink, uint pdwConnection);
void Unadvise(uint dwConnection);
void EnumAdvise(object ppenumAdvise);
void GetMiscStatus(uint dwAspect, uint pdwStatus);
void SetColorScheme(object pLogpal);
}
[ComImport, Guid("00000118-0000-0000-C000-000000000046"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IOleClientSite
{
void SaveObject();
void GetMoniker(uint dwAssign, uint dwWhichMoniker, object ppmk);
void GetContainer(object ppContainer);
void ShowObject();
void OnShowWindow(bool fShow);
void RequestNewObjectLayout();
}
[ComImport, GuidAttribute("6d5140c1-7436-11ce-8034-00aa006009fa"),
InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown),
ComVisible(false)]
public interface IServiceProvider
{
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int QueryService(ref Guid guidService, ref Guid riid, out IntPtr ppvObject);
}
[ComImport, GuidAttribute("79EAC9D0-BAF9-11CE-8C82-00AA004BA90B"),
InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown),
ComVisible(false)]
public interface IAuthenticate
{
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int Authenticate(ref IntPtr phwnd, ref IntPtr pszUsername, ref IntPtr pszPassword);
}
[ComImport()]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[GuidAttribute("bd3f23c0-d43e-11cf-893b-00aa00bdce1a")]
public interface IDocHostUIHandler
{
[PreserveSig]
uint ShowContextMenu(
uint dwID,
ref tagPOINT ppt,
[MarshalAs(UnmanagedType.IUnknown)] object pcmdtReserved,
[MarshalAs(UnmanagedType.IDispatch)] object pdispReserved
);
void GetHostInfo(ref DOCHOSTUIINFO pInfo);
void ShowUI(uint dwID, ref object pActiveObject, ref object pCommandTarget, ref object pFrame, ref object pDoc);
void HideUI();
void UpdateUI();
void EnableModeless(int fEnable);
void OnDocWindowActivate(int fActivate);
void OnFrameWindowActivate(int fActivate);
void ResizeBorder(ref tagRECT prcBorder, int pUIWindow, int fFrameWindow);
[PreserveSig]
uint TranslateAccelerator(ref tagMSG lpMsg, ref Guid pguidCmdGroup, uint nCmdID);
void GetOptionKeyPath([MarshalAs(UnmanagedType.BStr)] ref string pchKey, uint dw);
uint GetDropTarget(int pDropTarget, ref int ppDropTarget);
//object GetDropTarget(ref object pDropTarget);
[PreserveSig]
void GetExternal([MarshalAs(UnmanagedType.IDispatch)] out object ppDispatch);
[PreserveSig]
uint TranslateUrl(
uint dwTranslate,
[MarshalAs(UnmanagedType.BStr)] string pchURLIn,
[MarshalAs(UnmanagedType.BStr)] ref string ppchURLOut
);
IDataObject FilterDataObject(IDataObject pDO);
}
#endregion
}
webBrowser1。ObjectForScripting没有效果,因为您正在替换客户端站点。WinForms中的默认客户端站点实现了IDocHostUIHandler::GetExternal并返回ObjectForScripting的值。您可以在代理类中做同样的事情。