【问题标题】:What is the proper way to stop/kill a .net core web app process after launching a process to display the browser启动进程以显示浏览器后停止/终止 .net 核心 Web 应用程序进程的正确方法是什么
【发布时间】:2021-03-17 21:31:32
【问题描述】:

在创建 .NET Core Web 应用 C# 和调试时,您可以选择在运行应用时启动浏览器。控制台启动,然后 url 在您首选的浏览器中启动。关闭调试会话打开的浏览器选项卡后,应用进程将停止并且不再在计算机上运行。

当我发布应用程序时,页面不会自动启动,因此我正在启动一个新流程来执行此操作。我在启动它之前向进程添加了一个事件处理程序,但是由于应用程序没有启动该进程,因此在关闭选项卡时它不会收到任何通知。

启动 .NET Core Web 应用和/或处理两者之间的通信的正确方法是什么?

我什至尝试添加一个关闭按钮,但 JS 不允许我关闭窗口,因为我还没有打开它。

我正在按如下方式创建我的流程:

var p = Process.Start("cmd", "/C start http://localhost:5000");

我试过了

p.WaitForExit();
p.EventHandler += newHandler;

我也尝试过使用 ProcessStartInfo,但现在唯一有效的是,如果我设置了一个计时器,然后在计时器激活时终止进程,但这似乎不太干净。

感谢任何建议!

【问题讨论】:

  • 没有“正确”的方法,因为这甚至都不常见。您的 Web 应用在 Web 服务器上正常运行,所有客户端浏览器远程独立运行
  • 感谢您的意见@KeithNicholas。我已经使用 NancyFX 完成了我的要求,您可以在其中自我托管,我希望我能够使用 Kestrel 使用 .net 核心自我托管并使其“像 NancyFX”一样工作,但我想不会。

标签: c# asp.net-core-3.1


【解决方案1】:

我想跟进我认为是我最满意的最优雅方式的过程。

一些可能有助于创建您自己的流程的信息。我的目标是使用 .net 核心来自托管客户端 Web 应用程序,该应用程序与服务器托管的 Web api 进行通信。

  • 我正在使用 Razor 视图和 .net core 3.1
  • 我正在使用 Startup 并利用 applicationLifeTime 来处理 OnStartup,在此我开始我在原始帖子中描述的过程。

此时 Web 应用程序打开,如果用户决定关闭浏览器,则进程不知道并继续在后台运行。

为了防止它继续运行并允许用户启动它关闭,我做了以下一些补充。

首先,我添加了一个计时器,该计时器通过 appsettings 使用可配置的时间长度。当启动打开浏览器的进程时,我调用并设置计时器,如果进程在我默认为 1 小时的可配置时间长度后仍在运行,则该计时器将执行“自动关机”。我在处理关闭正在运行的进程的事件中使用 Enviroment.Exit(0)。

我的视图使用的模型包含一个属性,该属性的值将通过隐藏字段从页面设置。 我在启动时向用户显示的视图中添加了一个关闭按钮。当用户点击关闭时,我使用 jquery 在视图中设置一个隐藏字段,然后我使用 jquery 提交表单。

收到模型后,客户端关闭请求设置的值为真,如果您使用计时器并在将视图重定向到带有消息的视图后几乎立即启动它,您可以处理关闭而不会显示错误客户端。无论他们将其打开还是关闭,该过程都将关闭。下面是我如何做到的示例。

最后,在 Main.cs 中,我检查了是否存在正在运行的现有进程并在启动新进程之前将其关闭。我添加这个是因为客户端可能不会总是关闭浏览器和/或他们可能会尝试在“AutoShutdown”计时器启动之前启动它。

这比我想要的更“hacky”,但是当客户端仍然打开视图并且尝试使用 Envirnoment.Exit(0) 时,我找不到任何其他没有抛出并显示 Bad Request 的东西我未能成功允许控制台输入以便我可以在控制台附近发送。

这就是我在控制器中处理来自客户端的关闭请求的方式

if (ui.HandleCloseApp)
            {
                
                var app = Process.GetProcessesByName("NameOfYourWebApp");
        
                if (app.Length >= 1)
                {
                    foreach (var p in app)
                    {
                        if (p.ProcessName == "NameOfYourWebApp")
                        {
                             
                            p.Close();
                            p.Dispose();                           
                     
                        }
                    }
                }
                var t = new System.Timers.Timer(10);
                t.Elapsed += OnClose;
                t.Start();
                return View("Close");
   
            }

我希望这有助于其他人创建他们自己的“优雅”流程,而这不应该是 :)

如果有人有意见要分享,我仍然愿意。谢谢!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多