如何使用 C# 找到默认的 Web 浏览器?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13621467/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 09:12:54  来源:igfitidea点击:

How to find default web browser using C#?

c#

提问by Hope S

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

有没有办法可以使用 C# 找出默认 Web 浏览器的名称?(火狐、谷歌浏览器等。)

Can you please show me with an example?

你能给我举个例子吗?

采纳答案by Mario Sannum

You can look herefor 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;

}

回答by Steven Jeuris

The currently accepted 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\commandis not updated for IE. The reason behind this might be changes introduced starting from Windows Vista in how default programs are handled.

当 Internet Explorer 设置为默认浏览器时,当前接受的答案对我不起作用。在我的 Windows 7 PC 上,HKEY_CLASSES_ROOT\http\shell\open\command没有针对 IE 进行更新。这背后的原因可能是从 Windows Vista 开始引入了默认程序处理方式的更改。

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)

您可以在注册表项 中找到默认选择的浏览器 Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice,其值为Progid。(感谢破碎像素

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":
            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 Progidto retrieve it from ClassesRoot.

如果您还需要浏览器可执行文件的路径,您可以按如下方式访问它,使用从Progid中检索它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.
    }
}

回答by winsetter

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

回答by Joackim Pennerup

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

这已经过时了,但我只会添加我自己的发现供其他人使用。的值HKEY_CURRENT_USER\Software\Clients\StartMenuInternet应该为您提供此用户的默认浏览器名称。

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

如果要枚举所有已安装的浏览器,请使用 HKEY_LOCAL_MACHINE\SOFTWARE\Clients\StartMenuInternet

You can use the name found in HKEY_CURRENT_USERto identify the default browser in HKEY_LOCAL_MACHINEand then find the path that way.

您可以使用找到的名称HKEY_CURRENT_USER来标识默认浏览器HKEY_LOCAL_MACHINE,然后以这种方式找到路径。

回答by Nyerguds

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

回答by Pedro Fabián More Barrios

WINDOWS 10

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

回答by rory.ap

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 browserand discovered that the HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\https\UserChoicereg key described in his answer was empty, i.e. there was no ProgIdvalue.

正如我在史蒂文的回答下评论的那样,我遇到了这种方法不起作用的情况。我正在运行 Windows 7 Pro SP1 64 位。我下载并安装了Opera浏览器,发现HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\https\UserChoice他的回答中描述的reg键是空的,即没有ProgId值。

I used Process Monitorto 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 ProgIdvalue, 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 Defaultvalue in that key contains the following:

我使用Process Monitor观察当我在默认浏览器中打开 URL 时会发生什么(通过单击“开始”>“运行”并输入“ https://www.google.com”),并在检查了上述注册表项后发现并且未能找到该ProgId值,它找到了它需要的东西HKEY_CLASSES_ROOT\https\shell\open\command(在检查并未能在少数其他键中找到它之后)。当 Opera 设置为默认浏览器时,该Default键中的值包含以下内容:

"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" ProgIdvalue in HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\https\UserChoice. Furthermore, the HKEY_CLASSES_ROOT\https\shell\open\commandkey on the Windows 10 computer does notstore the default browser's command line path in HKEY_CLASSES_ROOT\https\shell\open\command-- The value I found there is

我继续在 Windows 10 上对此进行了测试,它的行为有所不同——更符合史蒂文的回答。它ProgIdHKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\https\UserChoice. 此外,HKEY_CLASSES_ROOT\https\shell\open\commandWindows 10 计算机上的密钥不会将默认浏览器的命令行路径存储在HKEY_CLASSES_ROOT\https\shell\open\command-- 我在那里找到的值

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

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

所以这是我根据我在 Process Monitor 中观察到的内容的建议:

First try Steven's process, and if there's no ProgIDin 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.

先试试Steven的流程,如果没有ProgIDin HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\https\UserChoice,再看看in的默认值HKEY_CLASSES_ROOT\https\shell\open\command。当然,我不能保证这会起作用,主要是因为我在该键中找到它之前在一堆其他位置看到了它。但是,如果我或其他人遇到不适合我所描述的模型的场景,当然可以在此处改进和记录该算法。