看起来 PID 是 4(系统),因为实际监听套接字位于一个名为http https://msdn.microsoft.com/en-us/library/windows/desktop/aa364510(v=vs.85).aspx.
我查看了 iisexpresstray.exe 使用什么来提供所有正在运行的 IISExpress 应用程序的列表。值得庆幸的是,它是易于反编译的托管 .NET 代码(全部位于 iisexpresstray.dll 中)。
似乎至少有三种不同的方法来获取进程的端口号:
- Reading
/port
来自命令行参数(据我们所知不可靠)
- Running
netsh http show servicestate view=requestq
并解析输出
- Calling
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 接口,
-
IRsca2_Core
(F90F62AB-EE00-4E4F-8EA6-3805B6B25CDD
)
-
IRsca2_WorkerProcess
(B1341209-7F09-4ECD-AE5F-3EE40D921870
)
最后,我读到 Microsoft.Web.Administration 的一个版本显然能够读取 IISExpress 应用程序信息,但信息非常稀缺,我在系统上找到的那个版本甚至不允许我实例化ServerManager
没有管理员权限。