有没有办法可以使用 C# 找出我的默认 Web 浏览器的名称?(火狐、谷歌浏览器等)
你能给我举个例子吗?
当Internet Explorer 设置为默认浏览器时,另一个答案对我不起作用。在我的 Windows 7 PC 上,HKEY_CLASSES_ROOT\http\shell\open\command
没有为 IE 更新。这背后的原因可能是从 Windows Vista 开始对默认程序的处理方式进行了更改。
您可以在注册表项 中找到默认选择的浏览器 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;
}
}
如果您还需要浏览器可执行文件的路径,您可以按如下方式访问它,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.
}
}
您可以在此处查看示例,但主要可以这样做:
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;
}
我刚刚为此做了一个函数:
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));
}
这已经过时了,但我只会添加我自己的发现供其他人使用。的值HKEY_CURRENT_USER\Software\Clients\StartMenuInternet
应该为您提供此用户的默认浏览器名称。
如果要枚举所有已安装的浏览器,请使用
HKEY_LOCAL_MACHINE\SOFTWARE\Clients\StartMenuInternet
您可以使用在中找到的名称HKEY_CURRENT_USER
来识别默认浏览器,HKEY_LOCAL_MACHINE
然后以这种方式查找路径。
视窗 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;
}
这是我将这里的响应与正确的协议处理结合起来的东西:
/// <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;
}
正如我在史蒂文的回答下评论的那样,我遇到了这种方法不起作用的情况。我正在运行 Windows 7 Pro SP1 64 位。我下载并安装了Opera浏览器,发现HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\https\UserChoice
他的回答中描述的reg键是空的,即没有ProgId
值。
我使用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"
我继续在 Windows 10 上对此进行了测试,它的行为有所不同——更符合 Steven 的回答。它ProgId
在HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\https\UserChoice
. 此外,HKEY_CLASSES_ROOT\https\shell\open\command
Windows 10 计算机上的密钥不会将默认浏览器的命令行路径存储在HKEY_CLASSES_ROOT\https\shell\open\command
-- 我在那里找到的值是
"C:\Program Files\Internet Explorer\iexplore.exe" %1
因此,根据我在 Process Monitor 中观察到的情况,这是我的建议:
先试试 Steven 的流程,如果没有ProgID
in HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\https\UserChoice
,再看 in 的默认值HKEY_CLASSES_ROOT\https\shell\open\command
。当然,我不能保证这会起作用,主要是因为我在找到它之前看到它在一堆其他位置中查找。但是,如果我或其他人遇到不符合我描述的模型的场景,当然可以在此处改进和记录该算法。
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));
}
}
在 rory.ap(下)之后,我发现这适用于今天的 Windows 10 中的 Firefox、iexplore 和 edge。
我检查了在设置中更改默认应用程序正确更改了注册表项。
您可能会因为 iexplore 和 edge 的 hmtl 文件名中的空格而遇到麻烦。所以“C#”在使用返回的字符串时会有所作为。
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);
}