Reputation: 503
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
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
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
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
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
Reputation: 81
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
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
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
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
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