How To: Launch a URL in the Visual Studio Internal Browser

For the sample extension that I'm working on, I wanted to have the ability to launch a URL in Visual Studio. This is useful for a more integrated experience in the IDE, but of course, some people may prefer to use their default web browser instead. So, I created a method that will either launch the internal or default web browser depending on a user setting (that way users can change to it to match their desired behavior).

For the internal browser, we use the IVsWebBrowsingService.Navigate method. By passing 0 to the dwNavigateFlags, the browsing service reuses an internal browser window if one already exists, or creates a new one if it does not. For the default browser, we call the Process.Start method with the appropriate flags so that it will behave like the managed equivalent of ShellExecute on the URL. Here's the code I wrote for this:

         private const string verbOpen = "Open";

private IVsWebBrowsingService browserService = null;

 
         /// <summary>
        /// Get the IVsWebBrowserService to use for navigating to the internal browser.
        /// </summary>
        private IVsWebBrowsingService BrowserService
        {
            get
            {
                if (browserService == null)
                {
                    // if we don't already have the internal browser service, get it from the global service provider.
                    browserService = ServiceProvider.GetService(typeof(SVsWebBrowsingService)) as IVsWebBrowsingService;
                }


                return browserService;
            }
        }
         /// <summary>
        /// Gets the initialized instance of ProcessStartInfo for a ShellExecute Open command.
        /// </summary>
        public ProcessStartInfo StartInfo
        {
            get
            {
                if (startInfo == null)
                {
                    startInfo = new ProcessStartInfo();
                    startInfo.UseShellExecute = true;
                    startInfo.Verb = verbOpen;
                }
 
                return startInfo;
            }
        }

/// <summary>
/// Launches the specified Url either in the internal VS browser or the
/// user's default web browser.
/// </summary>
/// <param name="browserService">VS's browser service for interacting with the internal browser.</param>
/// <param name="launchUrl">Url to launch.</param>
/// <param name="useInternalBrowser">true to use the internal browser; false to use the default browser.</param>
private void LaunchWebBrowser(IVsWebBrowsingService browserService, string launchUrl, bool useInternalBrowser)
{
try
{
if (useInternalBrowser == true)
{
// if set to use internal browser, then navigate via the browser service.
IVsWindowFrame ppFrame;

// passing 0 to the NavigateFlags allows the browser service to reuse open instances
// of the internal browser.
browserService.Navigate(launchUrl, 0, out ppFrame);
}
else
{
// if not, launch the user's default browser by starting a new one.
StartInfo.FileName = launchUrl;
Process.Start(StartInfo);
}
}
catch
{
// if the process could not be started, show an error.
MessageBox.Show("Cannot launch this url.", "Extension Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}

 The code above gets the IVsWebBrowsingService by querying a service provider. You can get a service provider in your extension by various methods: for typical extension look in this MSDN article; or if doing it from a StartPage, read my previous article on that subject.

Note: If you look at the IVsWebBrowsingService interface, you will notice it defines a CreateExternalWebBrowser method. I first thought I would use this method, since it was defined on this service. However, when I tried to call it, this method returned E_NOTIMPL. It appears this implementation has been removed, but calling ShellExecute on a URL is easy enough to do.