无法访问HttpContext时如何获取IIS托管网站的IP地址与端口号
问题原因说明
IIS的HTTP.sys作为内核态HTTP服务负责所有IIS站点的端口监听逻辑,运行在PID为4的System进程下,你代码运行的w3wp工作进程仅负责处理HTTP.sys转发的请求,本身不会直接监听端口,所以用w3wp进程ID查询netstat无法得到对应端口。
可行解决方案
方案1:通过IIS管理API读取站点配置
该方案通过读取IIS本地配置匹配当前进程所属站点,直接获取绑定的IP端口:
- 第一步:先安装NuGet包
Microsoft.Web.Administration - 第二步:解析当前w3wp进程的启动参数,提取对应的应用池名称,再匹配IIS站点配置获取对应绑定信息
代码示例:
using System.Diagnostics; using Microsoft.Web.Administration; // 提取当前进程对应的IIS应用池名称 var currentProcess = Process.GetCurrentProcess(); string cmdArgs = currentProcess.StartInfo.Arguments; int apParamIndex = cmdArgs.IndexOf("-ap ", StringComparison.OrdinalIgnoreCase); string appPoolName = cmdArgs.Substring(apParamIndex + 4).Split('"')[1]; // 遍历IIS站点匹配应用池,读取绑定信息 using var serverManager = new ServerManager(); foreach (var site in serverManager.Sites) { var rootApp = site.Applications.FirstOrDefault(a => a.Path == "/"); if (rootApp == null) continue; if (rootApp.ApplicationPoolName.Equals(appPoolName, StringComparison.OrdinalIgnoreCase)) { foreach (var binding in site.Bindings) { string ip = binding.EndPoint.Address.ToString(); int port = binding.EndPoint.Port; // 此处可获取到绑定的IP和端口 } break; } }
*注意:该方案需要应用池运行身份拥有IIS配置读取权限,可将应用池身份设置为LocalSystem,或为对应身份配置C:\Windows\System32\inetsrv\config\applicationHost.config文件的读取权限。
方案2:解析netsh命令输出
该方案不需要引入额外依赖,直接通过Windows自带的netsh命令查询HTTP.sys的请求队列配置,关联当前进程PID得到绑定的URL,再解析出IP端口:
代码示例:
using System.Diagnostics; using System.Text.RegularExpressions; int currentPid = Process.GetCurrentProcess().Id; // 执行netsh命令查询HTTP.sys服务状态 var process = new Process { StartInfo = new ProcessStartInfo { FileName = "netsh", Arguments = "http show servicestate view=requestq", RedirectStandardOutput = true, UseShellExecute = false, CreateNoWindow = true } }; process.Start(); string output = process.StandardOutput.ReadToEnd(); process.WaitForExit(); // 正则匹配当前PID对应的注册URL var regex = new Regex($@"Process ID:\s*{currentPid}.*?Registered URLs:\s*(.*?)\r\n\r\n", RegexOptions.Singleline | RegexOptions.IgnoreCase); var match = regex.Match(output); if (match.Success) { var urlList = match.Groups[1].Value.Split(new[] {'\r','\n'}, StringSplitOptions.RemoveEmptyEntries); foreach (var rawUrl in urlList) { var uri = new Uri(rawUrl.Trim()); string ip = uri.Host; int port = uri.Port; // 此处可获取IP和端口,若Host为*或+代表绑定所有网卡IP } }
方案3:直接解析IIS配置文件
如果不希望调用外部API或执行系统命令,可以直接读取IIS的核心配置文件C:\Windows\System32\inetsrv\config\applicationHost.config,解析XML结构提取站点绑定信息,匹配逻辑和方案1一致。
内容的提问来源于stack exchange,提问作者Kingfish
相关产品推荐
相关产品推荐

