如何在C#中使用默认浏览器打开页面

367
我正在设计一个小型的C#应用程序,其中包含一个Web浏览器。我当前在我的电脑上将所有默认设置都设置为Google Chrome是我的默认浏览器,但是当我在应用程序中单击链接以在新窗口中打开时,它会打开Internet Explorer。是否有办法使这些链接在默认浏览器中打开?或者我的电脑有什么问题吗?
我的问题是应用程序中有一个Web浏览器,所以假设你去Google并键入“堆栈溢出”,然后右键点击第一个链接并单击“在新窗口中打开”,它会在IE中而不是Chrome中打开。这是我编码不当还是我的计算机设置不正确?
===编辑===
这真的很烦人。我已经知道浏览器是IE了,但以前一切都运行正常。当我单击链接时,它会在Chrome中打开。当时我使用SharpDevelop制作应用程序,因为我无法启动C# Express。我进行了全新的Windows安装,并且由于我在应用程序中还没有走得太远,所以我决定重新开始,现在我遇到了这个问题。这就是为什么我不确定它是我的电脑出了问题还是其他原因。为什么IE会在单击链接时启动整个浏览器,而不是仅在默认浏览器中打开新链接?

呵呵,说服IE为您打开Chrome会是一场艰苦的战斗。嗯,不只是有点困难。如果直接运行IE,这也不起作用。同样,如果IE是默认浏览器,Chrome也不行。 - Hans Passant
  1. 获取开始菜单目录,搜索 Firefox 或 Chrome 的标准名称,请确保找到。如果未找到,则执行第 2 步。
  2. 获取标准安装位置列表,无论是 32 位还是 64 位,使用 Chrome 或 FF 存在的任何一个。如果没有,则执行第 3 步。
  3. 最后的手段是使用答案。
- bh_earth0
21个回答

620
在.NET Framework上(而不是在.Net Core或net50+上),你只需要写下以下代码即可:
System.Diagnostics.Process.Start("http://google.com");
编辑WebBrowser 控件是 IE 的嵌入副本。
因此,其中的任何链接都将在 IE 中打开。

要更改此行为,您可以处理 Navigating 事件。


2
试一下。使用Taskmgr.exe,你会看到两个 iexporer.exe 的副本在运行。导航不会触发外部进程的副本。 - Hans Passant
5
@Sean: 是的。Process.Start(e.Url.ToString()) - SLaks
3
除非指定浏览器可执行文件作为第一个参数,否则带有查询字符串的本地URL(file:///) 将无法正常工作。 - HerrimanCoder
7
请注意,这种方法也可能会引入安全问题,因为如果将“url”替换为应用程序的物理路径,则该应用程序也将被执行。 - Gerrie Pretorius
29
不适用于.NET Core。被接受的答案应支持.NET Core,请参见Mayank Tripathi在下面的答案。 - Andi
显示剩余11条评论

160

对于在 dotnet core 中遇到此问题的人,我在这里找到了一个解决方案here

代码:

private void OpenUrl(string url)
{
    try
    {
        Process.Start(url);
    }
    catch
    {
        // hack because of this: https://github.com/dotnet/corefx/issues/10361
        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
        {
            url = url.Replace("&", "^&");
            Process.Start(new ProcessStartInfo(url) { UseShellExecute = true });
        }
        else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
        {
            Process.Start("xdg-open", url);
        }
        else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
        {
            Process.Start("open", url);
        }
        else
        {
            throw;
        }
    }
}

1
我想不是这样的...我的解决方案有点不同。 - equiman
7
针对Windows操作系统,我建议使用Process.Start(new ProcessStartInfo { FileName = url, UseShellExecute = true });代码。 - Matt Jenkins
2
这应该是最佳答案,因为原始回答已经过时,只适用于 Windows 平台。 - ForeverZer0
1
很棒的答案Joel。在Windows和VS 2019 WPF(.NET Core)应用程序上也适用于我。我想知道如何在指定的浏览器中打开URL。具体来说,只从Microsoft Edge打开URL。在您的代码片段中,我需要做哪些更改? - NikSp
1
在一些禁止运行 cmd.exe 的企业环境中,这段代码在 Windows 上会失败。 - user555
显示剩余6条评论

60

经过大量研究后,我觉得大多数给出的答案在dotnet core上不起作用。 1.System.Diagnostics.Process.Start("http://google.com"); -- 在dotnet core中无法使用。

2.这个方法可以使用,但是如果默认浏览器是chrome,它将阻止新窗口的打开。

 myProcess.StartInfo.UseShellExecute = true; 
    myProcess.StartInfo.FileName = "http://some.domain.tld/bla";
    myProcess.Start();

以下是最简单的方法,适用于所有情况。

Process.Start("explorer", url);

适用于控制台应用程序 .Net Core 3.1 - Kozbara
我也无法在WinUI 3中使用System.Diagnostics.Process.Start("http://google.com")。但是,我成功地使用了这个解决方案。此外,Windows.System.Launcher.LaunchUriAsync(new Uri("http://google.com"));可以正常工作。 - Michael Kintscher they-them
实际上,这个方法并不适用于所有情况。例如,它无法处理带有查询字符串的URL。尝试使用Process.Start("explorer", "https://google.com/search?q=C#");,Windows会显示你的文档文件夹。 - undefined
@MustafaÖzçetin - 也许查询字符串需要将 # 编码为 %23"https://google.com/search?q=C%23". - undefined
@ToolmakerSteve:我试过你的方法,但没有任何区别。我尝试了使用.NET Framework 4.7.2和.NET 5,结果都是一样的。 - undefined

44
public static void GoToSite(string url)
{
     System.Diagnostics.Process.Start(url);
}

那应该会解决你的问题。


7
应该是"静态无返回类型的GotoSite函数"。 - Behrooz
在我的情况下,只有在使用提升的权限运行Windows应用程序时才能正常工作。我正在使用Windows 10上的Excel WPF应用程序,并将Chrome设置为默认浏览器。有什么办法可以解决这个问题,以便我不必使用提升的权限来运行? - Gagan

37

你是否尝试过像这里提到的Process一样使用: http://msdn.microsoft.com/de-de/library/system.diagnostics.process.aspx

您可以使用

Process myProcess = new Process();

try
{
    // true is the default, but it is important not to set it to false
    myProcess.StartInfo.UseShellExecute = true; 
    myProcess.StartInfo.FileName = "http://some.domain.tld/bla";
    myProcess.Start();
}
catch (Exception e)
{
    Console.WriteLine(e.Message);
}

1
UseShellExecute 默认为 true。 - SLaks
4
@SLaks,谢谢。另一方面,重要的是要提到它必须是“真实的”。 - Andreas
1
对于那些懒得检查的人...进程需要“using System.Diagnostics”。 - Nick Roberts
1
这似乎是WPF所需的路由。如果你只是执行 Process.Start(url),它不会打开一个新的浏览器窗口。 - Scott Salyer
13
иҜ·жіЁж„Ҹ - .NET CoreдёҚеҶҚй»ҳи®Өе°ҶUseShellExecuteи®ҫзҪ®дёәtrueпјҢеӣ жӯӨйңҖиҰҒж·»еҠ иҝҷиЎҢд»Јз ҒгҖӮ - Mike Marynowski
显示剩余2条评论

24

我的默认浏览器是Google Chrome,但采纳的答案出现了以下错误:

系统找不到指定的文件。

我解决了这个问题,并成功使用以下代码打开了默认浏览器中的URL:

System.Diagnostics.Process.Start("explorer.exe", "http://google.com");

18

我在使用.NET 5,在Windows平台上,结合Windows Forms。它甚至可以与其他默认浏览器(如Firefox)一起使用:

Process.Start(new ProcessStartInfo { FileName = url, UseShellExecute = true });

基于这个这个


8

试试这个老派的方式 ;)

public static void openit(string x)
    {
        System.Diagnostics.Process.Start("cmd", "/C start" + " " + x);
    }

using : openit("www.google.com");


4
这个能不能被利用,比如“Shellshock”? - Joseph Lennox
1
@JosephLennox 非常好的观点!值得一提的是,直接在 URL 上使用 System.Diagnostics.Process.Start 并不更加安全(甚至可能更不安全)。但另一方面,如果用户正在他们自己的计算机上运行您的应用程序(很可能如此),最糟糕的情况也只是破坏了他们自己的系统 :P - Ben
4
取决于输入来源。如果是共享数据源,一个用户可以输入恶意命令,所有其他点击“Go”的用户都将受到该用户的控制。 - Dan Bechard

8

我是不是唯一一个太害怕在从互联网读取的字符串上调用 System.Diagnostics.Process.Start() 的人?

        public bool OnBeforeBrowse(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, bool userGesture, bool isRedirect)
        {
            Request = request;
            string url = Request.Url;
            
            if (Request.TransitionType != TransitionType.LinkClicked)
            {   // We are only changing the behavoir when someone clicks on a link.
                // Let the embedded browser handle this request itself.
                return false;
            }
            else
            {   // The user clicked on a link.  Something like a filter icon, which links to the help for that filter.
                // We open a new window for that request.  This window cannot change.  It is running a JavaScript
                // application that is talking with the C# main program.
                Uri uri = new Uri(url);
                try
                {
                    switch (uri.Scheme)
                    {
                        case "http":
                        case "https":
                            {   // Stack overflow says that this next line is *the* way to open a URL in the
                                // default browser.  I don't trust it.  Seems like a potential security
                                // flaw to read a string from the network then run it from the shell.  This
                                // way I'm at least verifying that it is an http request and will start a
                                // browser.  The Uri object will also verify and sanitize the URL.
                                System.Diagnostics.Process.Start(uri.ToString());
                                break;
                            }
                        case "showdevtools":
                            {
                                WebBrowser.ShowDevTools();
                                break;
                            }
                    }
                }
                catch { }
                // Tell the browser to cancel the navigation.
                return true;
            }
        }

这段代码是为CefSharp设计的,但应该很容易进行调整。


5

请看GeckoFX控件

GeckoFX是一个开源组件,可以轻松地将Mozilla Gecko(Firefox)嵌入到任何.NET Windows Forms应用程序中。GeckoFX使用清晰、充分注释的C#编写,是默认的基于Internet Explorer的WebBrowser控件的完美替代品。


1
我的问题是,我在应用程序中有一个Web浏览器,所以假设你去谷歌并输入“堆栈溢出”,然后右键单击第一个链接并单击“在新窗口中打开”,它会在IE中而不是Chrome中打开。这是我编码不当的问题,还是我的计算机设置不正确? - Sean
@SLaks: 你为什么这么说?我不相信创建一个字符串并将其设置为GetDefaultBrowserPath()会有任何难度。 - THE DOCTOR
@Sean:如果你的应用程序中有一个Web浏览器,那么它默认会使用IE。Navigating事件可以帮助你解决这个问题。 - THE DOCTOR
我修改了我的答案,因为意识到 OP 不希望更改由单独进程启动的默认浏览器。 - THE DOCTOR

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接