c# - 在 IIS Express 停止后停止 npm 任务/脚本
问题描述
所以这是一个有趣的问题。我有一个使用 EntityFrameworkCore 和 VueJS 的 dotnetcore 3 项目。正确的。我Startup.cs:Configure(app,env)
的声明如下:
app.UseSpa(spa =>
{
if (env.IsDevelopment())
spa.Options.SourcePath = "ClientApp";
else
spa.Options.SourcePath = "dist";
if (env.IsDevelopment())
{
spa.UseVueCli(npmScript: "serve", port: 4444, forceKill: true);
}
});
如您所见,我已手动指定端口,4444
如果我不这样做,应用程序将尝试在端口上运行,8080
或者8080++
直到应用程序到达机器上的空闲端口。这适用于您只运行一次应用程序然后它从未崩溃或 Visual Studio 从未崩溃或您必须停止调试代码以管理项目文件结构的情况。你明白我的意思。在开发中你永远不会只只需触发一次命令并完成它。至少在我的经验中不是。
但尽管如此,这是此设置假设您所做的,因为当 IIS Express 服务关闭时它永远不会停止 npm-script,但它会尝试在同一 localhost 端口上重新启动 VueJS 应用程序,这确保与重新启动的应用程序的连接没有正确建立,因此会发生混乱。除非你通过 windows 终端杀死之前的 npm-script 任务。
所以我的问题是 - 当我停止我的 IIS Express 服务器时,有谁知道如何阻止脚本运行并杀死让它保持活动状态的任务?老实说,这对我来说有点莫名其妙:)
如果有人感兴趣的话,中间件类:)
#region Assembly VueCliMiddleware, Version=3.1.0.0, Culture=neutral, PublicKeyToken=null
// C:\Users\<USER>\.nuget\packages\vueclimiddleware\3.1.1\lib\netcoreapp3.1\VueCliMiddleware.dll
#endregion
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.SpaServices;
using VueCliMiddleware;
namespace VueCliMiddleware
{
public static class VueCliMiddlewareExtensions
{
public static IEndpointConventionBuilder MapToVueCliProxy(this IEndpointRouteBuilder endpoints, string pattern, SpaOptions options, string npmScript = "serve", int port = 8080, ScriptRunnerType runner = ScriptRunnerType.Npm, string regex = "running at", bool forceKill = false);
public static IEndpointConventionBuilder MapToVueCliProxy(this IEndpointRouteBuilder endpoints, string pattern, string sourcePath, string npmScript = "serve", int port = 8080, ScriptRunnerType runner = ScriptRunnerType.Npm, string regex = "running at", bool forceKill = false);
public static IEndpointConventionBuilder MapToVueCliProxy(this IEndpointRouteBuilder endpoints, SpaOptions options, string npmScript = "serve", int port = 8080, ScriptRunnerType runner = ScriptRunnerType.Npm, string regex = "running at", bool forceKill = false);
public static IEndpointConventionBuilder MapToVueCliProxy(this IEndpointRouteBuilder endpoints, string sourcePath, string npmScript = "serve", int port = 8080, ScriptRunnerType runner = ScriptRunnerType.Npm, string regex = "running at", bool forceKill = false);
public static void UseVueCli(this ISpaBuilder spaBuilder, string npmScript = "serve", int port = 8080, ScriptRunnerType runner = ScriptRunnerType.Npm, string regex = "running at", bool forceKill = false);
}
}
解决方案
好的,免责声明:这完全是 hack,只有在您事先知道您的端口时才有效(至少,它适用于我的机器;)),需要大量重构,我不提供任何保证。
很少有人知道您可以在 Startup 类中轻松附加到应用程序生命周期:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime lifetime)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
lifetime.ApplicationStopping.Register(OnStopping); // <== Magic is here!
}
// [Blah blah, yada yada, your super cool code here]
}
private void OnStopping()
{
// Things to do before application is stopped
}
我的想法是让你的known tcp port
(比方说4444
)和kill it
(戏剧音乐)听的过程。
我知道从端口检索 PID 的更快方法是使用netstat -nao
. OnStopping 代码将如下所示:
private void OnStopping()
{
// Following code runs on Windows platform only,
// if current platform is something else, we just exit
if(!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) return;
Process netstat = new Process();
netstat.StartInfo = new ProcessStartInfo
{
FileName = "netstat",
Arguments = "-nao",
RedirectStandardOutput = true
};
netstat.Start();
var output = netstat.StandardOutput.ReadToEnd();
var ports = output.Split('\n');
var f = ports.FirstOrDefault(p => p.Contains("LISTENING") && p.Contains("127.0.0.1:4444"));
var pid = int.Parse(f.Split(' ').Last());
var clientServer = Process.GetProcessById(pid);
clientServer.Kill();
clientServer.WaitForExit();
}
请让我知道您的想法,以及它是否适合您。
推荐阅读
- css - 如何让堆叠的 div 垂直向上增长?
- sql - 允许数组中的空值
- java - Android / Java:如何在 Android 中以编程方式打开具有密码 (SQLCipher) 的 SQLite DB?
- c# - 如何为 2 个字段创建索引以使其在集合中独一无二
- jenkins - 重新启动构建时如何获取父构建的构建号
- javascript - 使用 Vuetify 删除 v-stepper-header 编号
- java - 创建休眠查询以执行两个选择查询列的总和
- javascript - 使用 Apps 脚本将图像上传到 Google Drive
- android - 带有缅甸语言环境的 Android Adform 横幅。“键“height”的值“၅၀”无效,已被忽略
- python - 为多个单元格赋值