Hope S
Hope S

Reputation: 503

How to find default web browser using C#?

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?

Upvotes: 40

Views: 37062

Answers (9)

Steven Jeuris
Steven Jeuris

Reputation: 19100

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.
    }
}

Upvotes: 54

Erik
Erik

Reputation: 954

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);
}

Upvotes: 0

Sasha Bond
Sasha Bond

Reputation: 1176

    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));
        }
    }

Upvotes: 0

rory.ap
rory.ap

Reputation: 35270

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.

Upvotes: 1

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;
    }

Upvotes: 5

Nyerguds
Nyerguds

Reputation: 5629

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;
}

Upvotes: 1

Joackim Pennerup
Joackim Pennerup

Reputation: 81

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.

Upvotes: 6

winsetter
winsetter

Reputation: 301

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));
    }

Upvotes: 13

Mario S
Mario S

Reputation: 11945

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;

}

Upvotes: 28

Related Questions