我想以编程方式终止占用特定端口的正在运行的 IIS 实例,但似乎无法确定哪个 IIS 实例正在使用特定端口。
netstat.exe 仅显示该进程的 PID 为 4,但这是系统进程。 “netsh http show urlacl”根本不显示占用的端口。
IIS Express Tray 程序以某种方式知道这一点。当我尝试在端口被占用时启动另一个 IIS Express 实例时,出现以下错误:
“端口‘40000’已被进程‘IIS Express’(进程 ID ‘10632’)使用。
有人知道我如何获得这些信息吗?
最佳答案
PID 似乎是 4(系统),因为实际的监听套接字在名为 http 的服务下.
我查看了 iisexpresstray.exe 使用什么来提供所有正在运行的 IISExpress 应用程序的列表。值得庆幸的是,它是易于反编译的托管 .NET 代码(全部在 iisexpresstray.dll 中)。
它似乎至少有三种不同的方法来获取进程的端口号:
- 从命令行参数读取
/port
(我们知道这是不可靠的) - 运行
netsh http show servicestate view=requestq
并解析输出 - 调用
Microsoft.Web.RuntimeStatusClient.GetWorkerProcess(pid)
并解析站点 URL
不幸的是,iisexpresstray.dll 中大部分有用的东西,如 IisExpressHelper
类都被声明为 internal
(尽管我想有生成包装器或复制程序集的工具并宣传一切)。
我选择使用 Microsoft.Web.dll。它在我的 GAC 中,但由于某种原因没有出现在可作为 Visual Studio 中的引用添加的程序集列表中,所以我只是从我的 GAC 中复制了该文件。一旦我有了 Microsoft.Web.dll,只需使用以下代码即可:
using (var runtimeStatusClient = new RuntimeStatusClient())
{
var workerProcess = runtimeStatusClient.GetWorkerProcess(process.Id);
// Apparently an IISExpress process can run multiple sites/applications?
var apps = workerProcess.RegisteredUrlsInfo.Select(r => r.Split('|')).Select(u => new { SiteName = u[0], PhysicalPath = u[1], Url = u[2] });
// If we just assume one app
return new Uri(apps.FirstOrDefault().Url).Port;
}
您还可以调用 RuntimeClient.GetAllWorkerProcesses
以仅检索实际工作进程。
我也查看了 RegisteredUrlsInfo
(在 Microsoft.Web.dll 中),发现它使用了两个 COM 接口(interface),
IRsca2_Core
(F90F62AB-EE00-4E4F-8EA6-3805B6B25CDD
)IRsca2_WorkerProcess
(B1341209-7F09-4ECD-AE5F-3EE40D921870
)
最后,我读到 Microsoft.Web.Administration 的一个版本显然能够读取 IISExpress 应用程序信息,但信息非常稀少,我在系统上找到的版本甚至不允许我实例化 ServerManager
没有管理员权限。
关于c# - 如何找出哪个 IIS Express 实例正在使用端口?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32196188/