启动ASP.NET Core应用程序后如何启动Web浏览器?

Jus*_*son 18 c# .net-core asp.net-core

我有一个ASP.NET Core应用程序,将被多个用户用作客户端.换句话说,它不会托管在中央服务器上,只要需要使用应用程序,它们就会运行已发布的可执行文件.

Program.cs文件中有以下内容:

var host = new WebHostBuilder()
    .UseKestrel()
    .UseContentRoot(Directory.GetCurrentDirectory())
    .UseIISIntegration()
    .UseStartup<Startup>()
    .Build();

host.Run();
Run Code Online (Sandbox Code Playgroud)

我希望默认的Web浏览器能够自动打开,以避免用户必须打开浏览器并手动输入http://localhost:5000地址的冗余步骤.

实现这一目标的最佳方法是什么?调用Program.Start后调用Run()将无效,因为Run阻塞了线程.

Ger*_*oli 26

你有两个不同的问题:

线程阻塞

host.Run()确实阻止了主线程.所以,使用host.Start()(或await StartAsync2.x)代替host.Run().

如何启动Web浏览器

如果您在.NET Framework 4.x上使用ASP.NET Core,Microsoft 表示您可以使用:

Process.Start("http://localhost:5000");
Run Code Online (Sandbox Code Playgroud)

但是,如果您的目标是多平台.NET Core,则上述行将失败.没有一种解决方案.NET Standard可以在每个平台上使用.仅限Windows的解决方案是:

System.Diagnostics.Process.Start("cmd", "/C start http://google.com");
Run Code Online (Sandbox Code Playgroud)

编辑:我创建了一个故障并且MS开发人员回答了今天的情况,如果你想要一个多平台版本,你应该手动完成,例如:

public static void OpenBrowser(string url)
{
    if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
    {
        Process.Start(new ProcessStartInfo(url) { UseShellExecute = true }); // Works ok on windows
    }
    else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
    {
        Process.Start("xdg-open", url);  // Works ok on linux
    }
    else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
    {
        Process.Start("open", url); // Not tested
    }
    else
    {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

现在一起:

using System.Threading;

public class Program
{
    public static void Main(string[] args)
    {
        var host = new WebHostBuilder()
            .UseKestrel()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseIISIntegration()
            .UseStartup<Startup>()
            .Build();

        host.Start();
        OpenBrowser("http://localhost:5000/");
    }

    public static void OpenBrowser(string url)
    {
        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
        {
        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 
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 根据您链接的票证,现在可以通过`new ProcessStartInfo(url){UseShellExecute = true}`实现。 (2认同)

Wil*_*ill 6

接受的答案很好,但是因为没有阻塞,程序将立即结束,停止服务器。这是根据 Gerardo 和 Ivan 的答案改编的版本。

它将创建服务器,在服务器开始侦听时启动浏览器,并阻塞直到服务器结束:

using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using System.Diagnostics;
using Microsoft.AspNetCore.Builder;
using static System.Runtime.InteropServices.RuntimeInformation;
using static System.Runtime.InteropServices.OSPlatform;

class Program
{
    static void Main(string[] args)
    {
        string url = "http://localhost:54321/";

        using (var server = CreateServer(args, url))
        {
            StartBrowserWhenServerStarts(server, url);
            server.Run(); //blocks
        }
    }

    /// <summary>
    /// Create the kestrel server, but don't start it
    /// </summary>
    private static IWebHost CreateServer(string[] args, string url) => WebHost
        .CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .UseUrls(url)
        .Build();

    /// <summary>
    /// Register a browser to launch when the server is listening
    /// </summary>
    private static void StartBrowserWhenServerStarts(IWebHost server, string url)
    {
        var serverLifetime = server.Services.GetService(typeof(IApplicationLifetime)) as IApplicationLifetime;
        serverLifetime.ApplicationStarted.Register(() =>
        {
            var browser =
                IsOSPlatform(Windows) ? new ProcessStartInfo("cmd", $"/c start {url}") :
                IsOSPlatform(OSX) ? new ProcessStartInfo("open", url) :
                new ProcessStartInfo("xdg-open", url); //linux, unix-like

            Process.Start(browser);
        });
    }
}
Run Code Online (Sandbox Code Playgroud)


Iva*_*uba 5

这里的另一个选择是解析一个IApplicationLifetime对象Startup.Configure并在 上注册一个回调ApplicationStarted。当主机启动并正在侦听时触发该事件。

public void Configure(IApplicationBuilder app, IApplicationLifetime appLifetime)
{
    appLifetime.ApplicationStarted.Register(() => OpenBrowser(
        app.ServerFeatures.Get<IServerAddressesFeature>().Addresses.First()));
}

private static void OpenBrowser(string url)
{
    Process.Start(
        new ProcessStartInfo("cmd", $"/c start {url}") 
        {
            CreateNoWindow = true 
        });
}
Run Code Online (Sandbox Code Playgroud)