Webbrowser wpf ошибка сценария

Thanks to Simon Mourier for elegant way to solve this problem. I made a little improvement and encapsulated Simon’s solution into attached property.

In my application I use WebBrowser control databounded to viewmodel, the webbrowser might be hidden on inactive TabItem, so I have to check that it has been Loaded and Navigated before setting javascript errors silent. And of cource this setting should be done just once, so after setting I release hooked events.

XAML Code:

<TabControl xmlns:b="clr-namespace:MyApplication.Behaviors">
  <TabItem Header="foo">...</TabItem>
  <TabItem Header="Google map">
    <WebBrowser b:BindableSource="{Binding Path=MapUrl}"
                b:DisableJavascriptErrors="True" />
  </TabItem>
</TabControl>

Behavior code:

using System;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;

namespace MyApplication.Behaviors
{
    public class WebBrowserBehavior
    {
        private static readonly Type OwnerType = typeof (WebBrowserBehavior);

        #region BindableSource

        public static readonly DependencyProperty BindableSourceProperty =
            DependencyProperty.RegisterAttached(
                "BindableSource", 
                typeof(string), 
                OwnerType, 
                new UIPropertyMetadata(OnBindableSourcePropertyChanged));

        [AttachedPropertyBrowsableForType(typeof(WebBrowser))]
        public static string GetBindableSource(DependencyObject obj)
        {
            return (string)obj.GetValue(BindableSourceProperty);
        }

        [AttachedPropertyBrowsableForType(typeof(WebBrowser))]
        public static void SetBindableSource(DependencyObject obj, string value)
        {
            obj.SetValue(BindableSourceProperty, value);
        }

        public static void OnBindableSourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var browser = d as WebBrowser;
            if (browser == null) return;

            browser.Source = (e.NewValue != null) ? new Uri(e.NewValue.ToString()) : null;
        }

        #endregion

        #region DisableJavascriptErrors

        #region SilentJavascriptErrorsContext (private DP)

        private static readonly DependencyPropertyKey SilentJavascriptErrorsContextKey =
            DependencyProperty.RegisterAttachedReadOnly(
                "SilentJavascriptErrorsContext",
                typeof (SilentJavascriptErrorsContext),
                OwnerType,
                new FrameworkPropertyMetadata(null));

        private static void SetSilentJavascriptErrorsContext(DependencyObject depObj, SilentJavascriptErrorsContext value)
        {
            depObj.SetValue(SilentJavascriptErrorsContextKey, value);
        }

        private static SilentJavascriptErrorsContext GetSilentJavascriptErrorsContext(DependencyObject depObj)
        {
            return (SilentJavascriptErrorsContext) depObj.GetValue(SilentJavascriptErrorsContextKey.DependencyProperty);
        }

        #endregion

        public static readonly DependencyProperty DisableJavascriptErrorsProperty =
            DependencyProperty.RegisterAttached(
                "DisableJavascriptErrors",
                typeof (bool),
                OwnerType,
                new FrameworkPropertyMetadata(OnDisableJavascriptErrorsChangedCallback));

        [AttachedPropertyBrowsableForType(typeof(WebBrowser))]
        public static void SetDisableJavascriptErrors(DependencyObject depObj, bool value)
        {
            depObj.SetValue(DisableJavascriptErrorsProperty, value);
        }

        [AttachedPropertyBrowsableForType(typeof(WebBrowser))]
        public static bool GetDisableJavascriptErrors(DependencyObject depObj)
        {
            return (bool)depObj.GetValue(DisableJavascriptErrorsProperty);
        }

        private static void OnDisableJavascriptErrorsChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var webBrowser = d as WebBrowser;
            if (webBrowser == null) return;
            if (Equals(e.OldValue, e.NewValue)) return;

            var context = GetSilentJavascriptErrorsContext(webBrowser);
            if (context != null) {
                context.Dispose();
            }

            if (e.NewValue != null) {
                context = new SilentJavascriptErrorsContext(webBrowser);
                SetSilentJavascriptErrorsContext(webBrowser, context);
            }
            else {
                SetSilentJavascriptErrorsContext(webBrowser, null);
            }
        }

        private class SilentJavascriptErrorsContext : IDisposable
        {
            private bool? _silent; 
            private readonly WebBrowser _webBrowser;


            public SilentJavascriptErrorsContext(WebBrowser webBrowser)
            {
                _silent = new bool?();

                _webBrowser = webBrowser;
                _webBrowser.Loaded += OnWebBrowserLoaded;
                _webBrowser.Navigated += OnWebBrowserNavigated;
            }

            private void OnWebBrowserLoaded(object sender, RoutedEventArgs e)
            {
                if (!_silent.HasValue) return;

                SetSilent();
            }

            private void OnWebBrowserNavigated(object sender, NavigationEventArgs e)
            {
                var webBrowser = (WebBrowser)sender;

                if (!_silent.HasValue) {
                    _silent = GetDisableJavascriptErrors(webBrowser);
                }

                if (!webBrowser.IsLoaded) return;

                SetSilent();
            }

            /// <summary>
            /// Solution by Simon Mourier on StackOverflow
            /// http://stackoverflow.com/a/6198700/741414
            /// </summary>
            private void SetSilent()
            {
                _webBrowser.Loaded -= OnWebBrowserLoaded;
                _webBrowser.Navigated -= OnWebBrowserNavigated;

                // get an IWebBrowser2 from the document
                var sp = _webBrowser.Document as IOleServiceProvider;
                if (sp != null)
                {
                    var IID_IWebBrowserApp = new Guid("0002DF05-0000-0000-C000-000000000046");
                    var IID_IWebBrowser2 = new Guid("D30C1661-CDAF-11d0-8A3E-00C04FC9E26E");

                    object webBrowser2;
                    sp.QueryService(ref IID_IWebBrowserApp, ref IID_IWebBrowser2, out webBrowser2);
                    if (webBrowser2 != null)
                    {
                        webBrowser2.GetType().InvokeMember(
                            "Silent",
                            BindingFlags.Instance | BindingFlags.Public | BindingFlags.PutDispProperty,
                            null,
                            webBrowser2,
                            new object[] { _silent });
                    }
                }
            }

            [ComImport, Guid("6D5140C1-7436-11CE-8034-00AA006009FA"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
            private interface IOleServiceProvider
            {
                [PreserveSig]
                int QueryService([In] ref Guid guidService, [In] ref Guid riid, [MarshalAs(UnmanagedType.IDispatch)] out object ppvObject);
            }

            public void Dispose()
            {
                if (_webBrowser != null) {
                    _webBrowser.Loaded -= OnWebBrowserLoaded;
                    _webBrowser.Navigated -= OnWebBrowserNavigated;
                }
            }
        }

        #endregion

    }
}

  • Remove From My Forums
  • Question

  • There is no ScriptErrorsSuppressed property, so how do I suppress them?

    It’s extremely annoying that this control doesn’t have this feature!

Answers

  • Hi,

    Due to time constraints, we were very limited on how many features we could add to the WebBrowser control.  For now, the best option for any script which could throw a script error is to add a try/catch inside the failure-prone areas of the script.  If that’s not possible, the next alternative would be to continue using the WinForms WebBrowser control, though that only works in Full Trust apps.

    Andre

    • Marked as answer by

      Wednesday, July 30, 2008 11:22 AM

0 / 0 / 0

Регистрация: 04.06.2016

Сообщений: 8

1

12.06.2016, 14:47. Показов 6884. Ответов 9


Студворк — интернет-сервис помощи студентам

Помогите кто сталкивался с этой проблемой

Миниатюры

[WPF] Ошибка сценария WebBrowser
 



0



1302 / 1002 / 142

Регистрация: 01.10.2009

Сообщений: 3,235

Записей в блоге: 1

12.06.2016, 14:50

2



0



0 / 0 / 0

Регистрация: 04.06.2016

Сообщений: 8

12.06.2016, 16:42

 [ТС]

3

Я пишу свой браузер, через visual

Миниатюры

[WPF] Ошибка сценария WebBrowser
 



0



0 / 0 / 0

Регистрация: 04.06.2016

Сообщений: 8

12.06.2016, 17:02

 [ТС]

4

Пишу через wpf, а не через Forms



0



Администратор

Эксперт .NET

16310 / 12801 / 5057

Регистрация: 17.03.2014

Сообщений: 26,071

Записей в блоге: 1

12.06.2016, 18:43

5



1



0 / 0 / 0

Регистрация: 04.06.2016

Сообщений: 8

13.06.2016, 06:32

 [ТС]

6

Спасибо!



0



5 / 5 / 4

Регистрация: 20.01.2011

Сообщений: 350

30.10.2017, 23:55

7

А у меня вопрос интереснее — не «Как подавить эти ошибки», а «Как их исправить??»



0



Администратор

Эксперт .NET

16310 / 12801 / 5057

Регистрация: 17.03.2014

Сообщений: 26,071

Записей в блоге: 1

31.10.2017, 00:00

8

Modis, WPF использует тот же WebBrowser что и Windows Forms. Поэтому должно подойти решение описанное здесь — https://www.cyberforum.ru/post8616074.html



0



5 / 5 / 4

Регистрация: 20.01.2011

Сообщений: 350

31.10.2017, 00:15

9

Нашел решение. Может кому пригодится — https://blog.tallan.com/2014/0… b-browser/

Добавлено через 1 минуту

Цитата
Сообщение от OwenGlendower
Посмотреть сообщение

Поэтому должно подойти решение описанное здесь

Спасибо! Более полное решение, нежели я нашел



0



burning1ife

1462 / 1284 / 293

Регистрация: 21.09.2008

Сообщений: 3,438

Записей в блоге: 9

31.10.2017, 03:32

10

Modis, лучше используйте сторонник библиотеки аля cefsharp и awesomium для wpf



1



Все привет! Если вы, как и я приверженцы стандартных контролов framework. И при загрузке сайта возникаю ошибки сценария «На этой странице произошла ошибка сценария. Объект не поддерживает свойство или метод. Вы хотите продолжить выполнения сценария на этой странице?»:

Обычно таких окон всплывает огромное множество, и остановить их нажатием на кнопку Да или Нет ничего не выйдет. Да в конце будет загружен сайт, но выглядеть он будет криво, в прямом смысле этого слова.

Можно попробовать воспользоваться свойством:

webBrowser1.ScriptErrorsSuppressed = true;

После установки свойства значения true окон об ошибках больше мы не увидим, но это не означает что они пропали. Сайт по-прежнему будет выглядеть криво, а часть скриптов на Java Script просто не работает.

Мы даже можем увидеть следующую информацию, к примеру при заходе на сайт вкнонтакте.

Проблема кроется в том, что все современные сайт отказались от поддержки Internet Explorer.

А вот теперь зная проблему, мы можем ее решить, есть два варианта, если мы имеем доступ к сайту к изменению его html разметки, то нам достаточно добавить следующие строчки кода:

<head><meta httpequiv=«X-UA-Compatible» content=«IE=Edge» /></head>

Данный мета тег говорит о том, как загружать страницу, а точнее какой браузер использовать по умолчанию для контента, и как мы видим это Edge. Хочу заранее сказать, что такие теги по умолчанию вставлены во все поисковые системы, или аналоги их, потому при загрузке не возникает не каких JS ошибок.

Но что делать если мы хотим использовать сайт, к которому не имеем доступа для изменений html разметки? 

Ничего сложного, просто надо внести изменения в реестре, я даже не знаю почему этого не сделали по умолчанию в windows 10 для всех приложений, видимо это не возможно, поэтому вначале сделаем вручную, а потом покажу как это сделать программно.

Пример покажу под Windows 10 64  так как не могу протестировать для 32 бит версии или других OS. Но по сути ничего не меняется за исключением ветки для 32 и 64 версии.

//Компьютер\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION

//Компьютер\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION

//Компьютер\HKEY_CURRENT_USER\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION

Вам нужно будет указать имя своего приложения, создать параметр Dword и десятичное значения устанавливаем в 11001.

Вроде как проблема и решена от части, так как webBrowser по умолчанию использует Internet Explorer, и изменить мы это не можем, но что нам говорит MS, а говорит нам о том, что мы можем эмулировать работу Edge, то есть мы будем с функциями Edge использовать Internet Explorer. Нам будут доступны для полноценной работы все теги html и JS. Но, к сожалению, мы так же не сможем зайти на многие сайты, так как они принудительно отключили поддержку Internet Explorer, и сделать уже с этим нечего, возможно MS когда ни будь добавят Edge в webBrowser, хотя уже прошло 10 лет, но ничего не изменилось. И для решения приходится использовать сторонние браузеры.

Как и обещал привожу пример автоматического добавления в реестр значений, в соответствии с вашей системой.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

  private void Form1_Load(object sender, EventArgs e)

        {

            var appName = Process.GetCurrentProcess().ProcessName + «.exe»;

            SetIE8KeyforWebBrowserControl(appName);

            webBrowser1.ScriptErrorsSuppressed = true;

            webBrowser1.Url = new Uri(«https://www.nookery.ru»);

        }

        private void SetIE8KeyforWebBrowserControl(string appName)

        {

            RegistryKey Regkey = null;

            try

            {

                // Для 64-разрядной машины

                if (Environment.Is64BitOperatingSystem)

                    Regkey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@»SOFTWARE\\Wow6432Node\\Microsoft\\Internet Explorer\\Main\\FeatureControl\\FEATURE_BROWSER_EMULATION», true);

                else  //Для 32-разрядной машины

                    Regkey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@»SOFTWARE\\Microsoft\\Internet Explorer\\Main\\FeatureControl\\FEATURE_BROWSER_EMULATION», true);

                //Если путь неправильный или

                //Если у пользователя нет привилегий доступа к реестру

                if (Regkey == null)

                {

                    MessageBox.Show(«Сбой настроек приложения — адрес не найден»);

                    return;

                }

                string FindAppkey = Convert.ToString(Regkey.GetValue(appName));

                // Проверьте, присутствует ли ключ

                if (FindAppkey == «11001»)

                {

                    MessageBox.Show(«Необходимые параметры приложения присутствуют»);

                    Regkey.Close();

                    return;

                }

                // Если ключ отсутствует, добавьте ключ, значение ключа 11001 (десятичное)

                if (string.IsNullOrEmpty(FindAppkey))

                    Regkey.SetValue(appName, unchecked((int)0x1F40), RegistryValueKind.DWord);

                // Проверка наличия ключа после добавления

                FindAppkey = Convert.ToString(Regkey.GetValue(appName));

                if (FindAppkey == «11001»)

                    MessageBox.Show(«Параметры приложения успешно применены»);

                else

                    MessageBox.Show(«Сбой настроек приложения, ссылка: « + FindAppkey);

            }

            catch (Exception ex)

            {

                MessageBox.Show(«Сбой настроек приложения»);

                MessageBox.Show(ex.Message);

            }

            finally

            {

                // Закрываем реестр

                if (Regkey != null)

                    Regkey.Close();

            }

        }

I have already disabled java script errors in wpf webbrowser control on after navigate event by following code.

public static void SetSilent(System.Windows.Controls.WebBrowser browser, bool silent)
        {
            if (browser == null)
                throw new ArgumentNullException("browser");

        // get an IWebBrowser2 from the document
        IOleServiceProvider sp = browser.Document as IOleServiceProvider;
        if (sp != null)
        {
            Guid IID_IWebBrowserApp = new Guid("0002DF05-0000-0000-C000-000000000046");
            Guid IID_IWebBrowser2 = new Guid("D30C1661-CDAF-11d0-8A3E-00C04FC9E26E");

            object webBrowser;
            sp.QueryService(ref IID_IWebBrowserApp, ref IID_IWebBrowser2, out webBrowser);
            if (webBrowser != null)
            {
                webBrowser.GetType().InvokeMember("Silent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.PutDispProperty, null, webBrowser, new object[] { silent });
            }
        }
    }


    [ComImport, Guid("6D5140C1-7436-11CE-8034-00AA006009FA"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    private interface IOleServiceProvider
    {
        [PreserveSig]
        int QueryService([In] ref Guid guidService, [In] ref Guid riid, [MarshalAs(UnmanagedType.IDispatch)] out object ppvObject);
    }

But some java scripts doesn’t work properly and not get any error take no affect. Also future emulation mode is correct on registry.

Thank You.

asked Apr 19, 2016 at 11:01

Batur KILIÇ's user avatar

I found a solution for it. After navigate complete event does not work properly or state is not ready. Have to check first.

var browser = webBrowser1;

        if (browser == null || browser.Document == null)
            return;

        dynamic document = browser.Document;

        if (document.readyState != "complete")
            return;

        SetSilent(webBrowser1, true);

answered Apr 20, 2016 at 14:28

Batur KILIÇ's user avatar

Понравилась статья? Поделить с друзьями:
  • Werefault exe ошибка приложения
  • Wc 34736 3 ошибка ps4
  • Webasyst ошибка 1040
  • Wbase83 dll ошибка 1с
  • Webasyst 500 ошибка