none
Opening links from WPF WebBrowser control in default browser instead of IE

    Question

  • I am working on a WPF application that uses System.Windows.Controls.WebBrowser to display an embedded HTML page.
    The problem I have is that all links from that page that are to open an external browser window (with target="_blank") open Internet Explorer instead of the configured default browser.
    How do I tell the WebBrowser control to respect the default browser settings?
    Monday, November 16, 2009 7:31 AM

Answers

  • This code contains a serious security vulnerability. Before you ShellExecute the URL, you should ensure that it starts with either http:// or https://.

    See http://blogs.msdn.com/b/ieinternals/archive/2009/06/19/making-the-web-browser-control-launch-the-default-browser.aspx for an explanation of how to make the Web Browser control launch the system default browser.

    Sunday, October 03, 2010 8:28 PM
  • Hi,


    I came out a relatively simple solution and made a sample based on it:
    http://cid-b5f87dcdf8f1fe53.skydrive.live.com/self.aspx/.Public/WpfIEControl.zip

    Basically I'm hosting a WinForm version of WebBrowser control:

    <Window x:Class="WpfIEControl.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
        Title="Window1" Height="300" Width="300"
        Loaded="Window_Loaded">
        <Grid>
            <WindowsFormsHost Name="windowsFormsHost1">
                <wf:WebBrowser x:Name="webBrowser" />
            </WindowsFormsHost>
        </Grid>
    </Window>
    


    And add a reference to the SHDocVw (Microsoft Internet Controls).

    Then with the following code, it does exactly what you want:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.Diagnostics;
    using System.ComponentModel;
    
    namespace WpfIEControl
    {
        /// <summary>
        /// Interaction logic for Window1.xaml
        /// </summary>
        public partial class Window1 : Window
        {
            public Window1()
            {
                InitializeComponent();
            }
    
            private void Window_Loaded(object sender, RoutedEventArgs e)
            {
                ((SHDocVw.DWebBrowserEvents2_Event)webBrowser.ActiveXInstance).NewWindow3 +=
                    webBrowser_NewWindow3;
    
                webBrowser.Navigate("http://www.microsoft.com");
            }
    
            private void webBrowser_NewWindow3(ref object ppDisp, ref bool Cancel, uint dwFlags, string bstrUrlContext, string bstrUrl)
            {
                ProcessStartInfo psi = new ProcessStartInfo();
    
                psi.FileName = bstrUrl;
                psi.UseShellExecute = true;
    
                try
                {
                    Process.Start(bstrUrl);
                }
                catch (Win32Exception wex)
                {
                    MessageBox.Show(wex.Message, this.Title, MessageBoxButton.OK, MessageBoxImage.Error);
                }
                finally
                {
                    Cancel = true;
                }
            }
        }
    }
    

    I tested it with FF as the default browser.

    Please let me know if that works for you.

    Regards,
    Jie
    MSDN Subscriber Support in Forum
    If you have any feedback on our support, please contact msdnmg@microsoft.com
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    If you have any feedback, please tell us.

    The CodeFx Project
    My Blog (in Simplified Chinese)
    • Marked as answer by qs7000 Friday, November 20, 2009 12:50 PM
    Thursday, November 19, 2009 5:58 AM

All replies

  • Hi,


    How do I tell the WebBrowser control to respect the default browser settings?

    I don't think there is currently an easy way.

    The problem is, the so called "default browser setting" is defined in Shell, not in the IE browser. When the WebBrower control opens a URL in a new window, it is an internal operation (so the cookies can be shared with the new window), it doesn't go through the Shell so it won't and shouldn't use the default browser to open the URL.

    Another example is, if IE is currently the default browser, and you are working in another browser, when that browser encounters target="_blank", will it use IE (the default browser) to open it? Very unlikely.

    Thoughts of workarounds:

    The IE-based WebBrowser actually exposes a NewWindow3 event on its COM interface, unfortunately, the WPF WebBrowser control doesn't implement this event. Otherwise you can just put some code in that event handler, get the URL that is opened in the new window, use ShellExecute to open it with default browser and cancel the NewWindow navigation itself.

    The WinForm version of the WebBrowser control provided the corresponding NewWindow event, but we can't get the target URL from the event arguments, so it is still not enough to implement a workaround.

    Given these, I think a possible solution would be hosting the ActiveX version of the WebBrowser control ourselves, then we can use the NewWindow3 event mentioned above.

    Hope this helps.

    Regards,
    Jie
    MSDN Subscriber Support in Forum
    If you have any feedback on our support, please contact msdnmg@microsoft.com
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    If you have any feedback, please tell us.

    The CodeFx Project
    My Blog (in Simplified Chinese)
    Monday, November 16, 2009 11:25 AM
  • I tried the workaroudn using the NewWindow3 on the IE ActiveX control (as also described in http://windowsteamblog.com/blogs/developers/archive/2009/07/12/windows-7-e-best-practices-for-isvs.aspx), but strangely enough it did not cancel the navigation so the link was opened in both IE and the default browser.
            public void OpenBrowser(string url)
            {
                object o = null;
                InternetExplorer ie = new InternetExplorerClass();
                ie.NewWindow3 += new DWebBrowserEvents2_NewWindow3EventHandler(ie_NewWindow3);
                IWebBrowserApp wb = (IWebBrowserApp)ie;
                wb.Visible = true;
                wb.ToolBar = 0;
                wb.MenuBar = false;
    
    wb.Navigate(url, ref o, ref o, ref o, ref o);
            }
    
            void ie_NewWindow3(ref object ppDisp, ref bool Cancel, uint dwFlags, string bstrUrlContext, string bstrUrl)
            {
                Process.Start(bstrUrl);
                Cancel = true;
            }
    Any idea why this happens and how to avoid it?
    Wednesday, November 18, 2009 3:38 PM
  • Hi,


    I came out a relatively simple solution and made a sample based on it:
    http://cid-b5f87dcdf8f1fe53.skydrive.live.com/self.aspx/.Public/WpfIEControl.zip

    Basically I'm hosting a WinForm version of WebBrowser control:

    <Window x:Class="WpfIEControl.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
        Title="Window1" Height="300" Width="300"
        Loaded="Window_Loaded">
        <Grid>
            <WindowsFormsHost Name="windowsFormsHost1">
                <wf:WebBrowser x:Name="webBrowser" />
            </WindowsFormsHost>
        </Grid>
    </Window>
    


    And add a reference to the SHDocVw (Microsoft Internet Controls).

    Then with the following code, it does exactly what you want:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.Diagnostics;
    using System.ComponentModel;
    
    namespace WpfIEControl
    {
        /// <summary>
        /// Interaction logic for Window1.xaml
        /// </summary>
        public partial class Window1 : Window
        {
            public Window1()
            {
                InitializeComponent();
            }
    
            private void Window_Loaded(object sender, RoutedEventArgs e)
            {
                ((SHDocVw.DWebBrowserEvents2_Event)webBrowser.ActiveXInstance).NewWindow3 +=
                    webBrowser_NewWindow3;
    
                webBrowser.Navigate("http://www.microsoft.com");
            }
    
            private void webBrowser_NewWindow3(ref object ppDisp, ref bool Cancel, uint dwFlags, string bstrUrlContext, string bstrUrl)
            {
                ProcessStartInfo psi = new ProcessStartInfo();
    
                psi.FileName = bstrUrl;
                psi.UseShellExecute = true;
    
                try
                {
                    Process.Start(bstrUrl);
                }
                catch (Win32Exception wex)
                {
                    MessageBox.Show(wex.Message, this.Title, MessageBoxButton.OK, MessageBoxImage.Error);
                }
                finally
                {
                    Cancel = true;
                }
            }
        }
    }
    

    I tested it with FF as the default browser.

    Please let me know if that works for you.

    Regards,
    Jie
    MSDN Subscriber Support in Forum
    If you have any feedback on our support, please contact msdnmg@microsoft.com
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    If you have any feedback, please tell us.

    The CodeFx Project
    My Blog (in Simplified Chinese)
    • Marked as answer by qs7000 Friday, November 20, 2009 12:50 PM
    Thursday, November 19, 2009 5:58 AM
  • Thanks a lot, that worked just fine. :)
    Friday, November 20, 2009 12:52 PM
  • Do you know any way to maintain the session in the opened new window?

     

    Thanks in advance!

     

    Fede

     

     

    Friday, April 30, 2010 2:01 PM
  • i was able to maintain the session in the new opened window,

     

       Window1 win = new Window1();
          ppDisp = win.webBrowser.ActiveXInstance;
          win.Show();
          Cancel = false;

     

    but it seems that i can't run some activex and the window freezes...

     

    Any idea?

     

    Thanks!

    Friday, April 30, 2010 3:11 PM
  • This code contains a serious security vulnerability. Before you ShellExecute the URL, you should ensure that it starts with either http:// or https://.

    See http://blogs.msdn.com/b/ieinternals/archive/2009/06/19/making-the-web-browser-control-launch-the-default-browser.aspx for an explanation of how to make the Web Browser control launch the system default browser.

    Sunday, October 03, 2010 8:28 PM
  • This code contains a serious security vulnerability. Before you ShellExecute the URL, you should ensure that it starts with either http:// or https://.

    See http://blogs.msdn.com/b/ieinternals/archive/2009/06/19/making-the-web-browser-control-launch-the-default-browser.aspx for an explanation of how to make the Web Browser control launch the system default browser.


    Good catch!

    BTW, as described in your blog post, IECMDID_SET_INVOKE_DEFAULT_BROWSER_ON_NEW_WINDOW is defined in Windows 7 SDK, so does that mean it only works with IE 8.0 or later?

    Thanks!


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    If you have any feedback, please tell us.

    The All-In-One Code Framework Project
    My Blog (in Simplified Chinese)

    Monday, October 04, 2010 2:26 AM
  • It's working awesome
    But now i just want to check ma default browser is der any thing
    wen i click open a new window
    a pop or something appear to select different browser and make them default
    Tuesday, August 14, 2012 9:02 AM
  • hi i am having situation where i posting a byte array in webBroser.Navigate meathod. to the server sum thing lik this. then how should i restrict opening it in IE instead of opening it in default browser.

    var bArray = drFirstSettings.SSOLinkInBytes;
              var webBrowser = new WebBrowser();
              webBrowser.Navigate(drFirstSettings.WebBrowserUrl, "_blank", bArray, "");

                return "URL:" + Environment.NewLine + drFirstSettings.WebBrowserUrl +
                    Environment.NewLine + "Request:" + Environment.NewLine + (new UnicodeEncoding()).GetString(bArray);

    Wednesday, July 02, 2014 1:40 PM