【问题标题】:How to determine which Windows Communication Foundation Service is using a given port?如何确定哪个 Windows Communication Foundation 服务正在使用给定端口?
【发布时间】:2013-02-11 09:33:53
【问题描述】:

理想情况下,我想在 C# 中执行此操作,因此我包含 C# 标记。

我有几个 Window Communication Foundation 服务正在运行并使用 System.ServiceModel.ServiceHost 打开 TCP 端口(每个端口一个)。我有一个正在使用的端口号列表,但我想使用正在运行的服务从端口号映射到可执行文件。

我曾尝试使用 netstat、TCPView 和其他一些我发现的类似工具来尝试搜索此解决方案,但没有显示我的进程,我能得到的最接近的是系统 (PID 4)。

所有这些都是 Windows WCF 服务,按预期运行,并显示在 netstat 和 TCPView 中(按端口号),但只能提供“系统”作为进程。

代码由几个不同的部门管理,所以我不认为通用接口方法是有效的解决方案。我确实拥有这台机器的完全管理员权限。

【问题讨论】:

  • 通常,netstat 确实可以正确识别服务进程。您确定这些是用户模式服务而不是设备驱动程序吗?端口是如何打开的?
  • 我使用了一个 hack,您可以在其中获取带有进程 ID 的 netstat 的输出,然后将进程 ID 与给出进程名称和 ID 的“任务列表”的输出相匹配。
  • @HarryJohnston 我正在运行 C# Windows 服务。我有从 System.ServiceProcess.ServiceBase 继承的服务,并且覆盖 OnStart 正在实例化我的库/代码库类型的 System.ServiceModel.ServiceHost 并打开它。有些项目在其 app.config 中定义了端点,有些在 .cs 文件中更多/更少文字的代码中,出于所有意图和目的,无法从编译版本中解析出来。
  • @NareshJois 在发布之前,我曾明确考虑过这两个步骤,但就像我提到的 netstat 返回一个 PID 为 4 的系统。您可以使用 -b 标志返回进程;但是,我被卡住了,因为所有 Windows 服务都返回系统或“无法获取所有权信息”,具体取决于主机操作系统。我已经阅读并发现 Microsoft 改变了它的显示方式,但都是一样的。

标签: c# windows wcf tcplistener netstat


【解决方案1】:

WCF 提供了一个WMI interface for diagnostics,您应该能够使用它来将 WCF 服务端口与特定进程相关联。特别是 Service 类看起来很有希望。

(请随意在此处附上您所讨论的示例代码,或将其作为另一个答案发布。)

【讨论】:

    【解决方案2】:

    将我的示例代码添加到@HarryJohnston 的答案中:

    String wcfNamespace = String.Format(@"\\{0}\Root\ServiceModel", "MachineName");
    
    ConnectionOptions connection = new ConnectionOptions();
    connection.Authentication = AuthenticationLevel.PacketPrivacy;
    ManagementScope scope = new ManagementScope(wcfNamespace, connection);
    scope.Connect();
    
    ObjectQuery query = new ObjectQuery("Select * From Service");
    ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
    
    ManagementObjectCollection queryCollection = searcher.Get();
    ManagementObject[] listing = queryCollection.OfType<ManagementObject>().ToArray();
    
    Dictionary<int, int> portToPID = new Dictionary<int, int>();
    
    foreach (ManagementObject mo in queryCollection)
    {
        //each of services only have one base address in my example
        Uri baseAddress = new Uri(((Array)mo.Properties["BaseAddresses"].Value).GetValue(0).ToString());
        int pid = Int32.Parse(mo.Properties["ProcessId"].Value.ToString());
        portToPID.Add(baseAddress.Port, pid);
    }
    

    还需要将此添加到每个服务 .config,而不是 WMI 客户端

    <system.serviceModel>
        …
        <diagnostics wmiProviderEnabled="true" />
        …
    </system.serviceModel>
    

    【讨论】:

      猜你喜欢
      • 2021-12-16
      • 1970-01-01
      • 2011-02-19
      • 2011-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多