winform只屏蔽js脚本错误弹框,不屏蔽证书弹框

新手在使用WinForm时遇到JS脚本错误和证书弹框不能同时处理的问题。尝试了网上提供的屏蔽脚本错误代码和引入SHDocVw库的方法,发现仍存在问题。最终通过创建NativeMethods类和自定义MyWebBrowser类来继承WebBrowser,参考了相关博客文章解决了问题。此外,还需要引用shdocvw.dll和Microsoft.mshtml.dll,并重写NavigateComplete2方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

新手第一次用winform。遇到的js脚本错误跟证书弹框两者不可兼得的问题。以下是网上搜索遇到的坑跟最终的解决方案

坑一:将ScriptErrorsSuppressed设置为true。就是这个导致证书无法弹出来。进不了一些需要证书的网站。

private void browser_DocumentCompleted(object sender, 
WebBrowserDocumentCompletedEventArgs e)
{
    ((WebBrowser)sender).Document.Window.Error 
+= new HtmlElementErrorEventHandler(Window_Error);
}


private void Window_Error(object sender, HtmlElementErrorEventArgs 
e)
{
    // Ignore the error and suppress the error dialog box. 

e.Handled = true;
}

网上给出的上面这段代码。不设置true然后加上这段代码。我觉得是能屏蔽掉一些脚本错误的。但是大部分的js报错还是无法屏蔽。

坑二:引入SHDocVw。可以屏蔽脚本错误。但是证书弹不出来

实际解决方案:

1、添加类NativeMethods

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace AuthClient
{
    public static class NativeMethods
    {
        public enum OLECMDF
        {
            // Fields
            OLECMDF_DEFHIDEONCTXTMENU = 0x20,
            OLECMDF_ENABLED = 2,
            OLECMDF_INVISIBLE = 0x10,
            OLECMDF_LATCHED = 4,
            OLECMDF_NINCHED = 8,
            OLECMDF_SUPPORTED = 1
        }

        public enum OLECMDID
        {
            // Fields
            OLECMDID_PAGESETUP = 8,
            OLECMDID_PRINT = 6,
            OLECMDID_PRINTPREVIEW = 7,
            OLECMDID_PROPERTIES = 10,
            OLECMDID_SAVEAS = 4,
            OLECMDID_SHOWSCRIPTERROR = 40
        }
        public enum OLECMDEXECOPT
        {
            // Fields
            OLECMDEXECOPT_DODEFAULT = 0,
            OLECMDEXECOPT_DONTPROMPTUSER = 2,
            OLECMDEXECOPT_PROMPTUSER = 1,
            OLECMDEXECOPT_SHOWHELP = 3
        }

        [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("B722BCCB-4E68-101B-A2BC-00AA00404770"), ComVisible(true)]
        public interface IOleCommandTarget
        {
            [return: MarshalAs(UnmanagedType.I4)]
            [PreserveSig]
            int QueryStatus(ref Guid pguidCmdGroup, int cCmds, [In, Out] NativeMethods.OLECMD prgCmds, [In, Out] IntPtr pCmdText);
            [return: MarshalAs(UnmanagedType.I4)]
            [PreserveSig]
            int Exec(ref Guid pguidCmdGroup, int nCmdID, int nCmdexecopt, [In, MarshalAs(UnmanagedType.LPArray)] object[] pvaIn, ref int pvaOut);
        }

        [StructLayout(LayoutKind.Sequential)]
        public class OLECMD
        {
            [MarshalAs(UnmanagedType.U4)]
            public int cmdID;
            [MarshalAs(UnmanagedType.U4)]
            public int cmdf;
            public OLECMD()
            {
            }
        }

        public const int S_FALSE = 1;
        public const int S_OK = 0;

        public static readonly Guid CGID_DocHostCommandHandler = new Guid("f38bc242-b950-11d1-8918-00c04fc2c836");

        public const int VARIANT_TRUE = -1;
        public const int VARIANT_FALSE = 0;
        public const int OLECMDERR_E_NOTSUPPORTED = -2147221244;


    }


}

2、写一个自己的mywebbrowser类继承webbrowser

    public class WygIeWebBrowser : WebBrowser
    {
        System.Windows.Forms.AxHost.ConnectionPointCookie cookie;
        NewWebBrowserEvent events;

        public event EventHandler BeforeNavigate;

        public delegate void OnNewWindow2(WebBrowserUrlForWygIe webPra, WebBrowserEvent cancel);

        public event OnNewWindow2 BeforeNewWindowForWygIe;


        protected override void CreateSink()
        {
            base.CreateSink();//还是需要源
            events = new NewWebBrowserEvent(this);
            cookie = new System.Windows.Forms.AxHost.ConnectionPointCookie(this.ActiveXInstance, events, typeof(INewDWWebBrowserEvent));
        }
        

        protected override void DetachSink()
        {
            if (null != cookie)
            {
                cookie.Disconnect();
                cookie = null;
            }
            base.DetachSink();
        }
        public void OnBeforeNavigate(string url, string frame, out bool cancel)
        {
            var Arg = BeforeNavigate;
            WebBrowserUrl webBrowserUrl = new WebBrowserUrl(url, frame);
            Arg?.Invoke(this, webBrowserUrl);
            cancel = webBrowserUrl.Cancel;
        }
        public void OnBeforeNewWindow(string url, out bool cancel)
        {
            //var Arg = BeforeNewWindow;
            //WebBrowserUrl webBrowserUrl = new WebBrowserUrl(url, null);
            //Arg?.Invoke(this, webBrowserUrl);
            //cancel = webBrowserUrl.Cancel;
            var Arg = BeforeNewWindowForWygIe;
            WebBrowserUrlForWygIe webBrowserUrl = new WebBrowserUrlForWygIe(url, null);
            WebBrowserEvent webBrowserEvent = new WebBrowserEvent();
            Arg?.Invoke(webBrowserUrl, webBrowserEvent);
            cancel = webBrowserEvent.cancel;
        }

        class ExtendedWebBrowserSite : WebBrowser.WebBrowserSite, NativeMethods.IOleCommandTarget
        {
            /// <summary>
            /// Creates a new instance of the <see cref="ExtendedWebBrowserSite"/> class
            /// </summary>
            /// <param name="host">The <see cref="ExtendedWebBrowser"/> hosting the browser</param>
            public ExtendedWebBrowserSite(WebBrowser host)
                : base(host)
            {
                _host = host;
            }


            private WebBrowser _host;
            private WebBrowser Host
            {
                get
                {
                    return _host;
                }
            }

            #region IOleCommandTarget Members

            int NativeMethods.IOleCommandTarget.QueryStatus(ref Guid pguidCmdGroup, int cCmds, NativeMethods.OLECMD prgCmds, IntPtr pCmdText)
            {
                return NativeMethods.S_FALSE;
            }

            int NativeMethods.IOleCommandTarget.Exec(ref Guid pguidCmdGroup, int nCmdID, int nCmdexecopt, object[] pvaIn, ref int pvaOut)
            {
                int hResult = NativeMethods.S_OK;
                if (pguidCmdGroup == null)
                    return hResult;
                // Check for invalid pointers (or get a NullReferenceException on a value type???)
                //if (NativeMethods.CGID_DocHostCommandHandler.Equals(pguidCmdGroup))
                {
                    switch (nCmdID)
                    {
                        case (int)NativeMethods.OLECMDID.OLECMDID_SHOWSCRIPTERROR:
                            // Hide the dialog
                            pvaOut = NativeMethods.VARIANT_TRUE;


                            break;
                        default:
                            hResult = NativeMethods.OLECMDERR_E_NOTSUPPORTED;
                            break;
                    }
                }
                return hResult;
            }
            #endregion
        }
        protected override WebBrowserSiteBase CreateWebBrowserSiteBase()
        {
            return new ExtendedWebBrowserSite(this);
        }

    }

这种解决方案是参考了文档:https://www.cnblogs.com/qq1223558/p/3431736.html

https://www.xuebuyuan.com/180680.html。引入代码后解决了一些报错。实际上可行。

另外上面这一段加入后有一点不完美的地方忘记是什么了。我把最开始尝试屏蔽js脚本错误但没作用的一段代码打开了就可以了。尝试的方法是下面这段代码。

访问链接后获取SHDocVw.WebBrowser对象

SHDocVw.WebBrowser wb; 
wygIeWebBrowser.Navigate(url);
 wb = (SHDocVw.WebBrowser)wygIeWebBrowser.ActiveXInstance;
 wb.NavigateComplete2 += new DWebBrowserEvents2_NavigateComplete2EventHandler(wb_NavigateComplete2);//wb是一个Webbrowser控件
                

重写NavigateComplete2 方法。

void wb_NavigateComplete2(object pDisp, ref object URL)
        {
            mshtml.IHTMLDocument2 doc = wb.Document as mshtml.IHTMLDocument2;
            doc.parentWindow.execScript("window.alert=null", "javascript");
            doc.parentWindow.execScript("window.confirm=null", "javascript");
            doc.parentWindow.execScript("window.open=null", "javascript");
            doc.parentWindow.execScript("window.showModalDialog=null", "javascript");
            doc.parentWindow.execScript("window.close=null", "javascript");
            doc.parentWindow.execScript("function alert(str){return ''}", "javascript");

        }

需要引入两个dll文件shdocvw.dll跟Microsoft.mshtml.dll

第一个文件在你系统目录C:\Windows\System32下面可以找到

第二个文件在vs里面能找到

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值