从桌面应用程序启动用户的默认浏览器






2.50/5 (2投票s)
查找用户首选的浏览器并安全地启动它,可以有起始 URL,也可以没有。
引言
你可能会认为从桌面应用程序启动用户首选的互联网浏览器很容易,因为许多应用程序都紧密地集成了互联网技术。 可惜,事实并非如此。
我搜索了如何做到这一点,发现了很多复杂,有时甚至是相互矛盾的说明。 然后我了解到微软最近重组了注册表,使管理起来更容易一些。
我不确定这些更改是在较新的浏览器中进行的,还是仅仅在 Vista 操作系统中进行的。 我可以告诉你,我提供的代码在 Vista 上使用 IE 7 和 Firefox 3.0.1 都可以工作。 如果你有不同的配置,我希望你发布回复,让 CodeProject 社区知道什么有效,什么无效。
理论
注册表中的关键更改是添加了 *HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associations\UrlAssociations*。 此键跟踪在调用特定协议时应使用的应用程序。 这在当前用户配置单元中,因此数据将反映登录用户的首选项。 在我的机器上,它有 *ftp*、*http*、*https* 和 *mms* 作为子键。 其中每一个都有一个子键 *UserChoice*,它又有一个名为 *Progid* 的值。 此程序 ID 映射到 *HKEY_CLASSES_ROOT* 下的一个条目,这是查找浏览器命令行的地方。 将其传递给 System.Diagnostics.Process.Start
,并带有起始 URL(如果有)以启动浏览器。
代码
一旦你有了理论,编码就很简单了。 这是我所做的
Imports Microsoft.Win32
Imports System.ComponentModel
Imports System.Text
Private Sub LaunchDefaultBrowser(Optional ByVal URL As String = "")
Dim RegPath As New StringBuilder("Software\Microsoft\" & _
"Windows\Shell\Associations\UrlAssociations\ ")
Dim ThisUrl As String = URL.Trim
Dim Protocol As String = "http" 'Default protocol
'Internet Explorer is the default browser
Dim Browser As String = "IE.HTTP"
Dim AppPath As String = ""
Dim Splitters As String() = {""""c}
If ThisUrl <> String.Empty Then
Dim i As Integer = ThisUrl.IndexOf(":")
If i = -1 Then
'No protocol, so add the default to ThisUrl
ThisUrl= String.Format("{0}://{1}", Protocol, ThisUrl)
Else
'Get the requested protocol
Protocol = ThisUrl.Substring(0, i).ToLower
End If
End If
Select Case Protocol
Case "http", "https"
RegPath.AppendFormat("{0}\UserChoice", Protocol)
Case Else
MsgBox(String.Format("Unsupported protocol: {0}.", Protocol), _
MsgBoxStyle.Exclamation)
Exit Sub
End Select
Dim RegKey As RegistryKey = Registry.CurrentUser.OpenSubKey(RegPath.ToString)
If RegKey IsNot Nothing Then
Browser = RegKey.GetValue("ProgId", "IE.HTTP").ToString
RegKey.Close()
End If
RegKey = Registry.ClassesRoot.OpenSubKey(String.Format("{0}\Shell\Open\Command", Browser))
If RegKey IsNot Nothing Then
AppPath = RegKey.GetValue("").ToString
RegKey.Close()
End If
If AppPath = String.Empty Then
MsgBox("Unable to locate default browser.", MsgBoxStyle.Exclamation)
Exit Sub
End If
Dim s() As String = AppPath.Split(Splitters, StringSplitOptions.RemoveEmptyEntries)
Dim AppToLaunch As String = ""
If s.Length > 0 Then AppToLaunch = s(0)
If AppToLaunch = String.Empty Then
MsgBox("Unable to locate default browser.", MsgBoxStyle.Exclamation)
Else
System.Diagnostics.Process.Start(AppToLaunch, ThisUrl)
End If
End Sub
我首先初始化一些变量。 如果我找不到默认浏览器,我将尝试使用 IE。 请注意,RegPath
的初始化字符串末尾有一个额外的空格; 添加它是为了确保结尾的双引号被视为分隔符。 如果你复制并粘贴代码,则应删除此空格。
接下来,我检索 URL 中找到的协议(如果已给出)。 这是出于安全原因:我不希望我的用户尝试打开 *mailto* 或 *file* 链接。 如果提供了一个 URL 并且它没有协议,则假定为 *http*。 一旦我有了它,我就可以检查协议是否是我支持的协议。
现在我可以使用该协议来检查 UrlAssociations
中是否存在键。 如果它存在,请做个记录;否则,使用我的默认值。
然后它会传递到类根配置单元。 我刚才找到的值应该在此处映射到一个类名; 我想要的命令是子键 *\Shell\Open\Command* 的默认值。 如果你不熟悉如何在 .NET 中读取注册表,请注意,默认值是通过将空字符串传递到 GetValue
方法来获得的。 我将此值放入 AppPath
中。
存储在注册表中的命令字符串通常在双引号内包含主命令行,后跟任何可能带有或不带有引号的参数。 例如,我的 Firefox 命令看起来像这样
"C:\Program Files\Mozilla Firefox\firefox.exe" -requestPending -osint -url "%1"
有很多方法可以解析它; 我选择使用双引号作为分隔符来拆分字符串,并丢弃任何空白字段。 然后,命令行将是结果字符串数组中的第一个条目。
假设此时我有一个值,我可以启动它。 如果 ThisUrl
是一个空字符串,浏览器将启动自身并显示其默认起始页面; 否则,它将启动并显示提供的 Web 链接。
好了,就这样!
演示应用程序
演示应用程序非常基础。 它有一个包含标签、文本框和按钮的单个表单。 单击按钮会将文本框中的文本传递到上面给出的方法中。
这对你有用吗?
我的测试选项有点受限,我不确定微软在哪里进行了这些更改(浏览器?操作系统?) 我希望 CodeProject 成员可以帮助我整理一个使用此代码可以或不能工作的浏览器和操作系统的列表。