40

Is there a way I can find out the name of my default web browser using C#? (Firefox, Google Chrome, etc..)

Can you please show me with an example?

Steven Jeuris
  • 18,274
  • 9
  • 70
  • 161
Hope S
  • 503
  • 2
  • 6
  • 8

9 Answers9

53

The other answer does not work for me when internet explorer is set as the default browser. On my Windows 7 PC the HKEY_CLASSES_ROOT\http\shell\open\command is not updated for IE. The reason behind this might be changes introduced starting from Windows Vista in how default programs are handled.

You can find the default chosen browser in the registry key, Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice, with value Progid. (thanks goes to Broken Pixels)

const string userChoice = @"Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice";
string progId;
BrowserApplication browser;
using ( RegistryKey userChoiceKey = Registry.CurrentUser.OpenSubKey( userChoice ) )
{
    if ( userChoiceKey == null )
    {
        browser = BrowserApplication.Unknown;
        break;
    }
    object progIdValue = userChoiceKey.GetValue( "Progid" );
    if ( progIdValue == null )
    {
        browser = BrowserApplication.Unknown;
        break;
    }
    progId = progIdValue.ToString();
    switch ( progId )
    {
        case "IE.HTTP":
            browser = BrowserApplication.InternetExplorer;
            break;
        case "FirefoxURL":
            browser = BrowserApplication.Firefox;
            break;
        case "ChromeHTML":
            browser = BrowserApplication.Chrome;
            break;
        case "OperaStable":
            browser = BrowserApplication.Opera;
            break;
        case "SafariHTML":
            browser = BrowserApplication.Safari;
            break;
        case "AppXq0fevzme2pys62n3e0fbqa7peapykr8v": // Old Edge version.
        case "MSEdgeHTM": // Newer Edge version.
            browser = BrowserApplication.Edge;
            break;
        default:
            browser = BrowserApplication.Unknown;
            break;
    }
}

In case you also need the path to the executable of the browser you can access it as follows, using the Progid to retrieve it from ClassesRoot.

const string exeSuffix = ".exe";
string path = progId + @"\shell\open\command";
FileInfo browserPath;
using ( RegistryKey pathKey = Registry.ClassesRoot.OpenSubKey( path ) )
{
    if ( pathKey == null )
    {
        return;
    }

    // Trim parameters.
    try
    {
        path = pathKey.GetValue( null ).ToString().ToLower().Replace( "\"", "" );
        if ( !path.EndsWith( exeSuffix ) )
        {
            path = path.Substring( 0, path.LastIndexOf( exeSuffix, StringComparison.Ordinal ) + exeSuffix.Length );
            browserPath = new FileInfo( path );
        }
    }
    catch
    {
        // Assume the registry value is set incorrectly, or some funky browser is used which currently is unknown.
    }
}
Steven Jeuris
  • 18,274
  • 9
  • 70
  • 161
  • 2
    Personally though, I think that rather than retrieving the executable path, it's much more elegant to just fill in the %1 parameter in the retrieved string, split it into program and parameters, and execute it as it's defined in the registry. – Nyerguds Aug 19 '16 at 09:25
  • @Darren Thank you for including Opera, Safari, and Edge! What the hell is up with Edge's name in the registry though? Are you certain this is the same identifier on all systems (it seems like a random string)? – Steven Jeuris May 03 '17 at 14:26
  • 1
    @StevenJeuris I can't be certain of Edge's value and almost didn't add that one. I found this [answer](http://stackoverflow.com/a/32724723/1229237) with the same value, so it hasn't changed in almost two years. Hopefully that's safe-ish, but I'm a little sceptical like yourself. Opera looks good, Safari hasn't been in development since about 2012 for Windows, but still had a copy and thought it would be good to include. – DJH May 03 '17 at 14:37
  • I just installed opera and the "UserChoice" key is empty, so this doesn't seem to work for Opera. Windows 7 Pro 64 bit. – rory.ap Jun 21 '19 at 15:03
  • 1
    The value for Edge has changed. Currently on Windows 10 22H2 and Edge v115 this code reports `MSEdgeHTM` instead. – Impworks Aug 14 '23 at 13:53
  • @Impworks Updated accordingly. Thanks. – Steven Jeuris Aug 14 '23 at 15:08
27

You can look here for an example, but mainly it can be done like this:

internal string GetSystemDefaultBrowser()
{
    string name = string.Empty;
    RegistryKey regKey = null;

    try
    {
        //set the registry key we want to open
        regKey = Registry.ClassesRoot.OpenSubKey("HTTP\\shell\\open\\command", false);

        //get rid of the enclosing quotes
        name = regKey.GetValue(null).ToString().ToLower().Replace("" + (char)34, "");

        //check to see if the value ends with .exe (this way we can remove any command line arguments)
        if (!name.EndsWith("exe"))
            //get rid of all command line arguments (anything after the .exe must go)
            name = name.Substring(0, name.LastIndexOf(".exe") + 4);

    }
    catch (Exception ex)
    {
        name = string.Format("ERROR: An exception of type: {0} occurred in method: {1} in the following module: {2}", ex.GetType(), ex.TargetSite, this.GetType());
    }
    finally
    {
        //check and see if the key is still open, if so
        //then close it
        if (regKey != null)
            regKey.Close();
    }
    //return the value
    return name;

}
Mario S
  • 11,715
  • 24
  • 39
  • 47
  • 3
    When I set internet explorer as default browser, it doesn't seem to work for me. :/ That particular registry location isn't updated to point to IE. – Steven Jeuris Jul 11 '13 at 13:35
  • @tofutim Could you elaborate that a bit more? – Mario S Jan 17 '14 at 07:52
  • 3
    On my Win 8.1 machine, this technique pulls up Firefox (with the accompanying message that Firefox is NOT the default browser). This should be a fallback (for older OS) to Jeuris' answer (requires a bit of editing to work). – tofutim Jan 17 '14 at 17:49
  • 1
    I would offer a solution which could be usefull in some cases - open a page `System.Diagnostics.Process.Start("http://google.com");` then check runned processes for chrome, opera, ie, firefox, safary. This is an answer because you want "the name" not the path. – vinsa Mar 05 '18 at 21:45
13

I just made a function for this:

    public void launchBrowser(string url)
    {
        string browserName = "iexplore.exe";
        using (RegistryKey userChoiceKey = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice"))
        {
            if (userChoiceKey != null)
            {
                object progIdValue = userChoiceKey.GetValue("Progid");
                if (progIdValue != null)
                {
                    if(progIdValue.ToString().ToLower().Contains("chrome"))
                        browserName = "chrome.exe";
                    else if(progIdValue.ToString().ToLower().Contains("firefox"))
                        browserName = "firefox.exe";
                    else if (progIdValue.ToString().ToLower().Contains("safari"))
                        browserName = "safari.exe";
                    else if (progIdValue.ToString().ToLower().Contains("opera"))
                        browserName = "opera.exe";
                }
            }
        }

        Process.Start(new ProcessStartInfo(browserName, url));
    }
winsetter
  • 191
  • 1
  • 4
6

This is getting old, but I'll just add my own findings for others to use. The value of HKEY_CURRENT_USER\Software\Clients\StartMenuInternet should give you the default browser name for this user.

If you want to enumerate all installed browsers, use HKEY_LOCAL_MACHINE\SOFTWARE\Clients\StartMenuInternet

You can use the name found in HKEY_CURRENT_USER to identify the default browser in HKEY_LOCAL_MACHINE and then find the path that way.

  • Nope. Not doing it in Win10. It says Firefox, while my default is Chrome. – Nyerguds Aug 19 '16 at 08:45
  • This method isn't bad. The list of browsers under `HKEY_LOCAL_MACHINE\SOFTWARE\Clients\StartMenuInternet` is great for showing what's installed, while it's got some helpful info like `...StartMenuInternet\\Capabilities\FileAssociations`, and install strings which can be used to change the default browser. – u8it Sep 27 '17 at 16:13
  • 1
    However, the actual "default browser" is most functionally determined by the progid under HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associati‌​ons\UrlAssociations\‌​http\UserChoice. From my testing, this is how the browsers themselves determine if they're "defaults" or not. Firefox considers itself a default with just http, Chrome also checks https, and IE wants all its possible defaults filled – u8it Sep 27 '17 at 16:14
  • Also, this method doesn't seem to work well on Windows 10... works OK on Windows 7. – u8it Sep 27 '17 at 16:21
5

WINDOWS 10

internal string GetSystemDefaultBrowser()
    {
        string name = string.Empty;
        RegistryKey regKey = null;

        try
        {
            var regDefault = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\.htm\\UserChoice", false);
            var stringDefault = regDefault.GetValue("ProgId");

            regKey = Registry.ClassesRoot.OpenSubKey(stringDefault + "\\shell\\open\\command", false);
            name = regKey.GetValue(null).ToString().ToLower().Replace("" + (char)34, "");

            if (!name.EndsWith("exe"))
                name = name.Substring(0, name.LastIndexOf(".exe") + 4);

        }
        catch (Exception ex)
        {
            name = string.Format("ERROR: An exception of type: {0} occurred in method: {1} in the following module: {2}", ex.GetType(), ex.TargetSite, this.GetType());
        }
        finally
        {
            if (regKey != null)
                regKey.Close();
        }

        return name;
    }
1

Here's something I cooked up from combining the responses here with correct protocol handling:

/// <summary>
///     Opens a local file or url in the default web browser.
///     Can be used both for opening urls, or html readme docs.
/// </summary>
/// <param name="pathOrUrl">Path of the local file or url</param>
/// <returns>False if the default browser could not be opened.</returns>
public static Boolean OpenInDefaultBrowser(String pathOrUrl)
{
    // Trim any surrounding quotes and spaces.
    pathOrUrl = pathOrUrl.Trim().Trim('"').Trim();
    // Default protocol to "http"
    String protocol = Uri.UriSchemeHttp;
    // Correct the protocol to that in the actual url
    if (Regex.IsMatch(pathOrUrl, "^[a-z]+" + Regex.Escape(Uri.SchemeDelimiter), RegexOptions.IgnoreCase))
    {
        Int32 schemeEnd = pathOrUrl.IndexOf(Uri.SchemeDelimiter, StringComparison.Ordinal);
        if (schemeEnd > -1)
            protocol = pathOrUrl.Substring(0, schemeEnd).ToLowerInvariant();
    }
    // Surround with quotes
    pathOrUrl = "\"" + pathOrUrl + "\"";
    Object fetchedVal;
    String defBrowser = null;
    // Look up user choice translation of protocol to program id
    using (RegistryKey userDefBrowserKey = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\Shell\Associations\UrlAssociations\" + protocol + @"\UserChoice"))
        if (userDefBrowserKey != null && (fetchedVal = userDefBrowserKey.GetValue("Progid")) != null)
            // Programs are looked up the same way as protocols in the later code, so we just overwrite the protocol variable.
            protocol = fetchedVal as String;
    // Look up protocol (or programId from UserChoice) in the registry, in priority order.
    // Current User registry
    using (RegistryKey defBrowserKey = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Classes\" + protocol + @"\shell\open\command"))
        if (defBrowserKey != null && (fetchedVal = defBrowserKey.GetValue(null)) != null)
            defBrowser = fetchedVal as String;
    // Local Machine registry
    if (defBrowser == null)
        using (RegistryKey defBrowserKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Classes\" + protocol + @"\shell\open\command"))
            if (defBrowserKey != null && (fetchedVal = defBrowserKey.GetValue(null)) != null)
                defBrowser = fetchedVal as String;
    // Root registry
    if (defBrowser == null)
        using (RegistryKey defBrowserKey = Registry.ClassesRoot.OpenSubKey(protocol + @"\shell\open\command"))
            if (defBrowserKey != null && (fetchedVal = defBrowserKey.GetValue(null)) != null)
                defBrowser = fetchedVal as String;
    // Nothing found. Return.
    if (String.IsNullOrEmpty(defBrowser))
        return false;
    String defBrowserProcess;
    // Parse browser parameters. This code first assembles the full command line, and then splits it into the program and its parameters.
    Boolean hasArg = false;
    if (defBrowser.Contains("%1"))
    {
        // If url in the command line is surrounded by quotes, ignore those; our url already has quotes.
        if (defBrowser.Contains("\"%1\""))
            defBrowser = defBrowser.Replace("\"%1\"", pathOrUrl);
        else
            defBrowser = defBrowser.Replace("%1", pathOrUrl);
        hasArg = true;
    }
    Int32 spIndex;
    if (defBrowser[0] == '"')
        defBrowserProcess = defBrowser.Substring(0, defBrowser.IndexOf('"', 1) + 2).Trim();
    else if ((spIndex = defBrowser.IndexOf(" ", StringComparison.Ordinal)) > -1)
        defBrowserProcess = defBrowser.Substring(0, spIndex).Trim();
    else
        defBrowserProcess = defBrowser;

    String defBrowserArgs = defBrowser.Substring(defBrowserProcess.Length).TrimStart();
    // Not sure if this is possible / allowed, but better support it anyway.
    if (!hasArg)
    {
        if (defBrowserArgs.Length > 0)
            defBrowserArgs += " ";
        defBrowserArgs += pathOrUrl;
    }
    // Run the process.
    defBrowserProcess = defBrowserProcess.Trim('"');
    if (!File.Exists(defBrowserProcess))
        return false;
    ProcessStartInfo psi = new ProcessStartInfo(defBrowserProcess, defBrowserArgs);
    psi.WorkingDirectory = Path.GetDirectoryName(defBrowserProcess);
    Process.Start(psi);
    return true;
}
Nyerguds
  • 5,360
  • 1
  • 31
  • 63
  • This was really useful for my solution, although on a Client's Windows 10 machine I had to switch the Process.Start out for a ProcessStartInfo to be able to set the working directory. However, it's not picked up Yandex as a default browser, something I've yet to look into. – VorTechS Feb 07 '17 at 12:10
  • Honestly, I've had _Visual Studio_ open two different browsers when clicking exactly the same link twice. The whole thing is a giant mess. Fair point ont he working directory, though. I'll edit that in. – Nyerguds Feb 08 '17 at 13:09
1

As I commented under Steven's answer, I experienced a case where that method did not work. I am running Windows 7 Pro SP1 64-bit. I downloaded and installed the Opera browser and discovered that the HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\https\UserChoice reg key described in his answer was empty, i.e. there was no ProgId value.

I used Process Monitor to observe just what happens when I opened a URL in the default browser (by clicking Start > Run and typing "https://www.google.com") and discovered that after it checked the above-mentioned registry key and failed to find the ProgId value, it found what it needed in HKEY_CLASSES_ROOT\https\shell\open\command (after also checking and failing to find it in a handful of other keys). While Opera is set as the default browser, the Default value in that key contains the following:

"C:\Users\{username}\AppData\Local\Programs\Opera\launcher.exe" -noautoupdate -- "%1"

I went on to test this on Windows 10, and it behaves differently -- more in line with Steven's answer. It found the "OperaStable" ProgId value in HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\https\UserChoice. Furthermore, the HKEY_CLASSES_ROOT\https\shell\open\command key on the Windows 10 computer does not store the default browser's command line path in HKEY_CLASSES_ROOT\https\shell\open\command -- The value I found there is

"C:\Program Files\Internet Explorer\iexplore.exe" %1

So here is my recommendation based on what I've observed in Process Monitor:

First try Steven's process, and if there's no ProgID in HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\https\UserChoice, then look at the default value in HKEY_CLASSES_ROOT\https\shell\open\command. I can't guarrantee this will work, of course, mostly because I saw it looking in a bunch of other spots before finding it in that key. However, the algorithm can certainly be improved and documented here if and when I or someone else encounters a scenario that doesn't fit the model I've described.

rory.ap
  • 34,009
  • 10
  • 83
  • 174
0
    public void launchBrowser(string url)
    {
        using (RegistryKey userChoiceKey = Registry.CurrentUser.OpenSubKey(@"Software\Clients\StartMenuInternet"))
        {
            var first = userChoiceKey?.GetSubKeyNames().FirstOrDefault();
            if (userChoiceKey == null || first == null) return;
            var reg = userChoiceKey.OpenSubKey(first + @"\shell\open\command");
            var prog = (string)reg?.GetValue(null);
            if (prog == null) return;
            Process.Start(new ProcessStartInfo(prog, url));
        }
    }
Sasha Bond
  • 984
  • 10
  • 13
0

Following rory.ap (below), I found this to be working for Firefox, iexplore and edge in Windows 10 today.

I checked changing default apps in Settings changed the registry key correctly.

You will probably get into trouble with spaces in your hmtl file name for iexplore and edge. So "C#" something about it when using the returned string.

private string FindBrowser()
{
    using var key = Registry.CurrentUser.OpenSubKey(
        @"SOFTWARE\Microsoft\Windows\Shell\Associations\URLAssociations\http\UserChoice");
    var s = (string) key?.GetValue("ProgId");
    using var command = Registry.ClassesRoot.OpenSubKey($"{s}\\shell\\open\\command");
    // command == null if not found
    // GetValue(null) for default value.
    // returned string looks like one of the following:
    // "C:\Program Files\Mozilla Firefox\firefox.exe" -osint -url "%1"
    // "C:\Program Files\Internet Explorer\iexplore.exe" %1
    // "C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --single-argument %1
    return (string) command?.GetValue(null);
}
Erik
  • 894
  • 1
  • 8
  • 25