سؤال

لدي .NET 2.0 يتم استخدام عنصر تحكم WebBrowser للتنقل في بعض الصفحات دون أي تفاعل من المستخدم (لا تسأل...قصة طويلة).نظرًا لطبيعة هذا التطبيق الأقل من المستخدم ، قمت بتعيين خاصية ScripterrorsSupressed الخاصة بعنصر WebBrowser إلى True ، والتي ستنشئها الوثائق المضمنة في VS 2005 [...] "إخفاء جميع مربعات الحوار التي تنشأ من عنصر تحكم ActiveX الأساسي ، ، ليس فقط أخطاء النص ". ال مقالة MSDN ومع ذلك، لا يذكر هذا.لقد تمكنت من إلغاء حدث NewWindow، الذي يمنع النوافذ المنبثقة، لذا فقد تم الاهتمام بهذا الأمر.

أي شخص لديه أي خبرة في استخدام واحدة من هذه وحظر بنجاح الجميع مربعات الحوار، وأخطاء البرنامج النصي، وما إلى ذلك؟

يحرر

هذا ليس مثيلًا مستقلاً لـ IE، ولكنه مثيل لعنصر تحكم WebBrowser موجود في تطبيق Windows Form.أي شخص لديه أي خبرة في هذا التحكم، أو التحكم الأساسي، AxSHDocVW?

تحرير مرة أخرى

آسف نسيت أن أذكر هذا ...أحاول منع أ تنبيه جافا سكريبت (), ، بمجرد الضغط على زر "موافق".ربما يمكنني الإرسال إلى كائن IHTMLDocument2 والوصول إلى البرامج النصية بهذه الطريقة، لقد استخدمت MSHTML قليلاً، هل يعرف أحد؟

هل كانت مفيدة؟

المحلول

من المؤكد أن هذا أمر متسلل، ولكن إذا قمت بأي عمل باستخدام عنصر تحكم WebBrowser، فستجد نفسك تقوم بالكثير من الأشياء المتسللة.

هذه هي أسهل طريقة أعرفها للقيام بذلك.تحتاج إلى إدخال JavaScript لتجاوز وظيفة التنبيه...شيء على غرار حقن وظيفة JavaScript هذه:

window.alert = function () { }

هناك طرق عديدة للقيام بذلك, ، ولكن من الممكن جدا القيام به.أحد الاحتمالات هو ربط تنفيذ DWebBrowserEvents2 واجهه المستخدم.بمجرد الانتهاء من ذلك، يمكنك بعد ذلك توصيل NavigateComplete، أو DownloadComplete، أو DocumentComplete (أو، كما نفعل، بعض الأشكال المختلفة منها) ثم استدعاء أسلوب InjectJavaScript الذي قمت بتنفيذه والذي ينفذ هذا التجاوز للنافذة.alert طريقة.

كما قلت، hacky، لكنه يعمل :)

يمكنني الخوض في مزيد من التفاصيل إذا كنت بحاجة لذلك.

نصائح أخرى

وللحصول على طريقة سهلة لحقن هذا الخط السحري من جافا سكريبت، اقرأ كيفية إدخال جافا سكريبت في التحكم في متصفح الويب.

أو فقط استخدم هذا الكود الكامل:

private void InjectAlertBlocker() {
    HtmlElement head = webBrowser1.Document.GetElementsByTagName("head")[0];
    HtmlElement scriptEl = webBrowser1.Document.CreateElement("script");
    string alertBlocker = "window.alert = function () { }";
    scriptEl.SetAttribute("text", alertBlocker);
    head.AppendChild(scriptEl);
}

قد تضطر إلى تخصيص بعض الأشياء، وإلقاء نظرة عليها IDocHostUIHandler, ، ثم تحقق من بعض الواجهات الأخرى ذات الصلة.يمكنك الحصول على قدر لا بأس به من التحكم، حتى إلى حد تخصيص عرض الحوار/واجهة المستخدم (لا أستطيع تذكر الواجهة التي تقوم بذلك).أنا متأكد من أنك تستطيع أن تفعل ما تريد، ولكن ذلك يتطلب العبث في الأجزاء الداخلية MSHTML والقدرة على تنفيذ مختلف COM واجهات.

بعض الأفكار الأخرى:http://msdn.microsoft.com/en-us/library/aa770041.aspx

IHostDialogHelper
IDocHostShowUI

قد تكون هذه هي الأشياء التي تتطلع إلى تنفيذها.

مانع التنبيه المضاد للرصاص:

Browser.Navigated +=
    new WebBrowserNavigatedEventHandler(
        (object sender, WebBrowserNavigatedEventArgs args) => {
            Action<HtmlDocument> blockAlerts = (HtmlDocument d) => {
                HtmlElement h = d.GetElementsByTagName("head")[0];
                HtmlElement s = d.CreateElement("script");
                IHTMLScriptElement e = (IHTMLScriptElement)s.DomElement;
                e.text = "window.alert=function(){};";
                h.AppendChild(s);
            };
            WebBrowser b = sender as WebBrowser;
            blockAlerts(b.Document);
            for (int i = 0; i < b.Document.Window.Frames.Count; i++)
                try { blockAlerts(b.Document.Window.Frames[i].Document); }
                catch (Exception) { };
        }
    );

تفترض هذه العينة أن لديك Microsoft.mshtml وأضاف المرجع "باستخدام م أتش تي أم أل؛" في مساحات الأسماء الخاصة بك و المتصفح هو الخاص بك متصفح الإنترنت مثال.

لماذا هو مضاد للرصاص؟أولا، ذلك يتعامل مع البرامج النصية داخل الإطارات.ثم أنه لا يتعطل عندما خاص "الإطار القاتل" موجود في الوثيقة.أ "الإطار القاتل" هو إطار يثير استثناءً عند محاولة استخدامه ككائن HtmlWindow.قد يتسبب أي "foreach" مستخدم في Document.Window.Frames في حدوث استثناء، لذا يجب استخدام حلقة "for" الأكثر أمانًا مع كتلة المحاولة/التقاط.

ربما لا يكون الجزء الأكثر قابلية للقراءة من التعليمات البرمجية، ولكنه يعمل مع صفحات الحياة الواقعية غير جيدة التنسيق.

webBrowser1.ScriptErrorsSuppressed = true;

فقط قم بإضافة ذلك إلى وظيفة مستوى الدخول الخاص بك.بعد الكثير من البحث، توصلت إلى هذه الطريقة، ولمست الخشب حتى الآن نجحت.هتافات!!

يمكن حظر window.showModelessDialog وwindow.showModalDialog من خلال تطبيق واجهة INewWindowManager، بالإضافة إلى ذلك، يوضح الكود أدناه كيفية حظر مربعات حوار التنبيه من خلال تطبيق IDocHostShowUI

public class MyBrowser : WebBrowser
{

    [PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")]
    public MyBrowser()
    {
    }

    protected override WebBrowserSiteBase CreateWebBrowserSiteBase()
    {
        var manager = new NewWindowManagerWebBrowserSite(this);
        return manager;
    }

    protected class NewWindowManagerWebBrowserSite : WebBrowserSite, IServiceProvider, IDocHostShowUI
    {
        private readonly NewWindowManager _manager;

        public NewWindowManagerWebBrowserSite(WebBrowser host)
            : base(host)
        {
            _manager = new NewWindowManager();
        }

        public int ShowMessage(IntPtr hwnd, string lpstrText, string lpstrCaption, int dwType, string lpstrHelpFile, int dwHelpContext, out int lpResult)
        {
            lpResult = 0;
            return Constants.S_OK; //  S_OK Host displayed its UI. MSHTML does not display its message box.
        }

        // Only files of types .chm and .htm are supported as help files.
        public int ShowHelp(IntPtr hwnd, string pszHelpFile, uint uCommand, uint dwData, POINT ptMouse, object pDispatchObjectHit)
        {
            return Constants.S_OK; //  S_OK Host displayed its UI. MSHTML does not display its message box.
        }

        #region Implementation of IServiceProvider

        public int QueryService(ref Guid guidService, ref Guid riid, out IntPtr ppvObject)
        {
            if ((guidService == Constants.IID_INewWindowManager && riid == Constants.IID_INewWindowManager))
            {
                ppvObject = Marshal.GetComInterfaceForObject(_manager, typeof(INewWindowManager));
                if (ppvObject != IntPtr.Zero)
                {
                    return Constants.S_OK;
                }
            }
            ppvObject = IntPtr.Zero;
            return Constants.E_NOINTERFACE;
        }

        #endregion
    }
 }

[ComVisible(true)]
[Guid("01AFBFE2-CA97-4F72-A0BF-E157038E4118")]
public class NewWindowManager : INewWindowManager
{
    public int EvaluateNewWindow(string pszUrl, string pszName,
        string pszUrlContext, string pszFeatures, bool fReplace, uint dwFlags, uint dwUserActionTime)
    {

        // use E_FAIL to be the same as CoInternetSetFeatureEnabled with FEATURE_WEBOC_POPUPMANAGEMENT
        //int hr = MyBrowser.Constants.E_FAIL; 
        int hr = MyBrowser.Constants.S_FALSE; //Block
        //int hr = MyBrowser.Constants.S_OK; //Allow all
        return hr;
    }
}

لقد قمت للتو بنشر مقالة عن Code Project قد تساعدك.

لطفا أنظر - http://www.codeproject.com/KB/shell/WebBrowserControlDialogs.aspx

أتمنى أن يساعدك هذا.

ال InjectAlertBlocker رمز صحيح تماما هو

private void InjectAlertBlocker() {
    HtmlElement head = webBrowser1.Document.GetElementsByTagName("head")[0];
    HtmlElement scriptEl = webBrowser1.Document.CreateElement("script");
    IHTMLScriptElement element = (IHTMLScriptElement)scriptEl.DomElement;
    string alertBlocker = "window.alert = function () { }";
    element.text = alertBlocker;
    head.AppendChild(scriptEl);
}

المراجع المطلوب إضافتها هي

  1. إضافة مرجع إلى MSHTML, ، والذي سيتم استدعاؤه على الأرجح "مكتبة كائنات Microsoft HTML" تحت COM مراجع.

  2. يضيف using mshtml; إلى مساحات الأسماء الخاصة بك.

  3. احصل على مرجع لعنصر البرنامج النصي الخاص بك IHTMLElement:

ثم يمكنك استخدام Navigated حدث متصفح الويب على النحو التالي:

private void InjectAlertBlocker()
{
    HtmlElement head = webBrowser1.Document.GetElementsByTagName("head")[0];
    HtmlElement scriptEl = webBrowser1.Document.CreateElement("script");
    IHTMLScriptElement element = (IHTMLScriptElement)scriptEl.DomElement;
    string alertBlocker = "window.alert = function () { }";
    element.text = alertBlocker;
    head.AppendChild(scriptEl);
}

private void webDest_Navigated(object sender, WebBrowserNavigatedEventArgs e)
{
    InjectAlertBlocker();
}

هل تحاول تنفيذ روبوت الويب؟لدي خبرة قليلة في استخدام عنصر تحكم IE المستضاف ولكنني أكملت بعض مشاريع Win32 وحاولت استخدام عنصر تحكم IE.يجب أن يتم تعطيل النوافذ المنبثقة عبر معالجات الأحداث الخاصة بعنصر التحكم كما فعلت بالفعل، لكنني وجدت أنك تحتاج أيضًا إلى تغيير "تعطيل تصحيح أخطاء البرنامج النصي xxxx" في خيارات IE (أو يمكنك تعديل السجل في أكوادك) كما يلي: وأشار cjheath بالفعل.ومع ذلك، وجدت أيضًا أنه يجب القيام بخطوات إضافية عند التحقق من عنوان URL للتنقل بحثًا عن أي محتويات قابلة للتنزيل لمنع مربعات حوار الفتح/الحفظ هذه.لكنني لا أعرف كيفية التعامل مع الملفات المتدفقة لأنني لا أستطيع تخطيها من خلال النظر إلى عناوين URL وحدها وفي النهاية التفت إلى مكتبة Indy مما أنقذني من جميع المشاكل في التعامل مع IE.أخيرًا، أتذكر أن Microsoft ذكرت شيئًا عبر الإنترنت وهو أن IE غير مصمم لاستخدامه كعنصر تحكم OLE.وفقًا لتجربتي الخاصة، في كل مرة ينتقل فيها عنصر التحكم إلى صفحة جديدة، يحدث تسرب للذاكرة للبرامج!

كان لدي مشاكل أكبر مع هذا:تحميل صفحة ويب مخصصة للطباعة ويعرض مربع حوار الطباعة المزعج.كان InjectBlocker هو الطريقة الوحيدة التي نجحت، ولكنها غير موثوقة إلى حد ما.في ظل ظروف معينة (أعتبر أن التحكم في WebBrowser يستخدم محرك IE وهذا يعتمد على إصدار IE المثبت) يظل مربع حوار الطباعة يظهر.هذه مشكلة كبيرة، يعمل الحل على Win7 مع تثبيت IE9، لكن WinXP مع IE8 يعرض مربع الحوار، بغض النظر عن الأمر.

أعتقد أن الحل يكمن في تعديل الكود المصدري وإزالة جافا سكريبت للطباعة، قبل أن يعرض التحكم الصفحة.ومع ذلك حاولت ذلك مع:خاصية DocumentText الخاصة بعنصر تحكم متصفح الويب وهي لا تعمل.الخاصية ليست للقراءة فقط، ولكن ليس لها أي تأثير، عندما أقوم بتعديل المصدر.

الحل الذي وجدته لمشكلتي هو البرنامج النصي Exec:

string alertBlocker = "window.print = function emptyMethod() { }; window.alert = function emptyMethod() { }; window.open = function emptyMethod() { };";    
this.Document.InvokeScript("execScript", new Object[] { alertBlocker, "JavaScript" });

تمكنت من إدخال الكود أعلاه عن طريق إنشاء ملف ممتد WebBroswer الطبقة وتجاوز OnNavigated طريقة.

يبدو أن هذا يعمل بشكل جيد:

class WebBrowserEx : WebBrowser
{
  public WebBrowserEx ()
  {
  }

  protected override void OnNavigated( WebBrowserNavigatedEventArgs e )
  {
       HtmlElement he = this.Document.GetElementsByTagName( "head" )[0];
       HtmlElement se = this.Document.CreateElement( "script" );
       mshtml.IHTMLScriptElement element = (mshtml.IHTMLScriptElement)se.DomElement;
       string alertBlocker = "window.alert = function () { }";
       element.text = alertBlocker;
       he.AppendChild( se );
       base.OnNavigated( e );
  }
}

ببساطة من خصائص التحكم في المتصفح:scriptErrorSupressed=true

أسهل طريقة للقيام بذلك هي:في ال :التحكم في متصفح الويب لديك الإجراء (قياسي) BeforeScriptExecute

(المعلمة ل BeforeScriptExecute يكون pdispwindow )

اضف هذا :

pdispwindow.execscript("window.alert = function () { }")

بهذه الطريقة، قبل تنفيذ أي برنامج نصي على نافذة الصفحة، سيتم منع التنبيه عن طريق إدخال التعليمات البرمجية.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top