I need to confirm programatically (i.e, answer 'yes') to a script error dialog box into WebBrowser otherwise the page will stop working. I have no code to show because I have no idea how I could do this.
Here's a image from dialog box I'm talking about:
(take from this, btw)
According to the "How to handle script errors as a WebBrowser control host" MSKB article, you need to handle CGID_DocHostCommandHandler/OLECMDID_SHOWSCRIPTERROR command in the WebBrowser host.
With a bit of coding, here is how it can be done for the WinForms WebBrowser version, and it actually works:
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public class WebBrowserEx: WebBrowser
{
class WebBrowserSiteEx : WebBrowserSite, NativeMethods.IOleCommandTarget
{
public WebBrowserSiteEx(WebBrowser browser): base(browser)
{
}
public int QueryStatus(IntPtr pguidCmdGroup, uint cCmds, NativeMethods.OLECMD[] prgCmds, ref NativeMethods.OLECMDTEXT CmdText)
{
return NativeMethods.OLECMDERR_E_UNKNOWNGROUP;
}
public int Exec(IntPtr pguidCmdGroup, uint nCmdId, uint nCmdExecOpt, IntPtr pvaIn, IntPtr pvaOut)
{
if (pguidCmdGroup != IntPtr.Zero)
{
Guid guid = (Guid)Marshal.PtrToStructure(pguidCmdGroup, typeof(Guid));
if (guid == NativeMethods.CGID_DocHostCommandHandler)
{
if (nCmdId == NativeMethods.OLECMDID_SHOWSCRIPTERROR)
{
// if DOM needed: dynamic document = Marshal.GetObjectForNativeVariant(pvaIn);
// continue running scripts
if (pvaOut != IntPtr.Zero)
Marshal.GetNativeVariantForObject(true, pvaOut);
return NativeMethods.S_OK;
}
}
}
return NativeMethods.OLECMDERR_E_UNKNOWNGROUP;
}
}
protected override WebBrowserSiteBase CreateWebBrowserSiteBase()
{
return new WebBrowserSiteEx(this);
}
}
public partial class Form1 : Form
{
WebBrowserEx _browser;
public Form1()
{
InitializeComponent();
_browser = new WebBrowserEx();
_browser.Dock = DockStyle.Fill;
this.Controls.Add(_browser);
}
private void Form1_Load(object sender, EventArgs e)
{
// testing
_browser.DocumentText = "<script>alert(bad.bad)</script>";
}
}
static class NativeMethods
{
[StructLayout(LayoutKind.Sequential)]
public struct OLECMD
{
public uint cmdID;
public uint cmdf;
}
[StructLayout(LayoutKind.Sequential)]
public struct OLECMDTEXT
{
public UInt32 cmdtextf;
public UInt32 cwActual;
public UInt32 cwBuf;
public char rgwz;
}
public const int OLECMDERR_E_UNKNOWNGROUP = unchecked((int)0x80040102);
public const int OLECMDID_SHOWSCRIPTERROR = 40;
public static readonly Guid CGID_DocHostCommandHandler = new Guid("f38bc242-b950-11d1-8918-00c04fc2c836");
public const int S_OK = 0;
[ComImport, Guid("b722bccb-4e68-101b-a2bc-00aa00404770"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IOleCommandTarget
{
[PreserveSig]
int QueryStatus(
IntPtr pguidCmdGroup,
UInt32 cCmds,
[In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] OLECMD[] prgCmds,
ref OLECMDTEXT CmdText);
[PreserveSig]
int Exec(
IntPtr pguidCmdGroup,
uint nCmdId,
uint nCmdExecOpt,
IntPtr pvaIn,
IntPtr pvaOut);
}
}
}
I need to capture the JavaScript error info in order to log it while still not displaying it to the user. I looked at the document object (the commented out line) and didn't see anything there. Is there an easy way to capture this info?
Check the article I linked at the beginning. There are special properties errorLine, errorCharacter, errorCode, errorMessage, errorUrl available on document.parentWindow.event object.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With