如何在启动我的 ASP.NET 核心应用程序后启动 Web 浏览器?
How do I launch the web browser after starting my ASP.NET Core application?
我有一个 ASP.NET 核心应用程序,将被多个用户用作客户端。换句话说,它不会托管在中央服务器上,他们会在需要使用该应用程序的任何时候 运行 发布的可执行文件。
在 Program.cs
文件中有以下内容:
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
host.Run();
我希望默认网络浏览器自动打开,以避免用户不得不打开浏览器并手动输入 http://localhost:5000
地址的多余步骤。
实现此目标的最佳方法是什么?在调用 Run()
之后调用 Program.Start
将不起作用,因为 Run
阻塞了线程。
您可以在 host.Run()
之前生成 Web 浏览器进程。这适用于 Chrome,可能还有其他浏览器:
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
var browserExecutable = "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe";
Process.Start(browserExecutable, "http://localhost:5000");
host.Run();
}
在 Chrome 的情况下,新的 window 将等待服务器启动,然后连接并显示应用程序。
根据您的系统配置方式,您可以 Process.Start("http://localhost:5000")
启动默认浏览器,而不是对可执行文件的路径进行硬编码。由于某种原因,这对我不起作用。您还可以从注册表或配置文件中提取浏览器路径。
这里有两个不同的问题:
线程阻塞
host.Run()
确实阻塞了主线程。因此,使用 host.Start()
(或 2.x 上的 await StartAsync
)而不是 host.Run()
。
如何启动网络浏览器
如果您使用 ASP.NET Core 而不是 .NET Framework 4.x,Microsoft says 您可以只使用:
Process.Start("http://localhost:5000");
但如果您的目标是多平台 .NET Core,则上述行将失败。没有使用 .NET Standard
的单一解决方案适用于所有平台。仅 Windows 的解决方案是:
System.Diagnostics.Process.Start("cmd", "/C start http://google.com");
编辑:我创建了一个 ticket 并且一位 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
{
...
}
}
大家在一起:
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
}
}
}
这里的另一个选择是解析 Startup.Configure
中的 IApplicationLifetime
对象并在 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
});
}
接受的答案很好,但是因为没有阻塞程序会立即结束,停止服务器。这是改编自 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);
});
}
}
我有一个 ASP.NET 核心应用程序,将被多个用户用作客户端。换句话说,它不会托管在中央服务器上,他们会在需要使用该应用程序的任何时候 运行 发布的可执行文件。
在 Program.cs
文件中有以下内容:
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
host.Run();
我希望默认网络浏览器自动打开,以避免用户不得不打开浏览器并手动输入 http://localhost:5000
地址的多余步骤。
实现此目标的最佳方法是什么?在调用 Run()
之后调用 Program.Start
将不起作用,因为 Run
阻塞了线程。
您可以在 host.Run()
之前生成 Web 浏览器进程。这适用于 Chrome,可能还有其他浏览器:
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
var browserExecutable = "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe";
Process.Start(browserExecutable, "http://localhost:5000");
host.Run();
}
在 Chrome 的情况下,新的 window 将等待服务器启动,然后连接并显示应用程序。
根据您的系统配置方式,您可以 Process.Start("http://localhost:5000")
启动默认浏览器,而不是对可执行文件的路径进行硬编码。由于某种原因,这对我不起作用。您还可以从注册表或配置文件中提取浏览器路径。
这里有两个不同的问题:
线程阻塞
host.Run()
确实阻塞了主线程。因此,使用 host.Start()
(或 2.x 上的 await StartAsync
)而不是 host.Run()
。
如何启动网络浏览器
如果您使用 ASP.NET Core 而不是 .NET Framework 4.x,Microsoft says 您可以只使用:
Process.Start("http://localhost:5000");
但如果您的目标是多平台 .NET Core,则上述行将失败。没有使用 .NET Standard
的单一解决方案适用于所有平台。仅 Windows 的解决方案是:
System.Diagnostics.Process.Start("cmd", "/C start http://google.com");
编辑:我创建了一个 ticket 并且一位 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
{
...
}
}
大家在一起:
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
}
}
}
这里的另一个选择是解析 Startup.Configure
中的 IApplicationLifetime
对象并在 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
});
}
接受的答案很好,但是因为没有阻塞程序会立即结束,停止服务器。这是改编自 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);
});
}
}