It seems like the PID is 4 (System) because the actual listening socket is under a service called http.
I looked at what iisexpresstray.exe was using to provide a list of all running IISExpress applications. Thankfully it's managed .NET code (all in iisexpresstray.dll) that's easily decompiled.
It appears to have at least three different ways of getting the port number for a process:
- Reading
/port
from the command-line arguments (unreliable as we know)
- Running
netsh http show servicestate view=requestq
and parsing the output
- Calling
Microsoft.Web.RuntimeStatusClient.GetWorkerProcess(pid)
and parsing the site URL
Unfortunately, most of the useful stuff in iisexpresstray.dll like the IisExpressHelper
class is declared internal
(although I imagine there're tools to generate wrappers or copy the assembly and publicize everything).
I opted to use Microsoft.Web.dll. It was in my GAC, though for some reason wasn't appearing in the list of assemblies available to add as a reference in Visual Studio, so I just copied the file out from my GAC. Once I had Microsoft.Web.dll it was just a matter of using this code:
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;
}
You can also call RuntimeClient.GetAllWorkerProcesses
to retrieve only actual worker processes.
I looked into RegisteredUrlsInfo
(in Microsoft.Web.dll) as well and found that it's using two COM interfaces,
IRsca2_Core
(F90F62AB-EE00-4E4F-8EA6-3805B6B25CDD
)
IRsca2_WorkerProcess
(B1341209-7F09-4ECD-AE5F-3EE40D921870
)
Lastly, I read about a version of Microsoft.Web.Administration apparently being able to read IISExpress application info, but information was very scarce, and the one I found on my system wouldn't even let me instantiate ServerManager
without admin privileges.