2009-02-23 80 views
4

獲取在C#中給定端口偵聽的PID的最簡單方法是什麼? 基本上,我想確保我的服務正在運行,並在我提供的端口上進行偵聽。 如果有比解析netstat輸出更簡單的方法,它將會很棒。哪個PID在給定的端口上偵聽c#

回答

6

從Win XP SP2的起你可以P/Invoke到GetExtendedTcpTable

使用This person's樣的工作來充實簽名(該PInvoke.net規範是不完整的)這裏a(粗略且差錯檢查)示例

using System; 
using System.Runtime.InteropServices; 

public enum TCP_TABLE_CLASS : int 
{ 
    TCP_TABLE_BASIC_LISTENER, 
    TCP_TABLE_BASIC_CONNECTIONS, 
    TCP_TABLE_BASIC_ALL, 
    TCP_TABLE_OWNER_PID_LISTENER, 
    TCP_TABLE_OWNER_PID_CONNECTIONS, 
    TCP_TABLE_OWNER_PID_ALL, 
    TCP_TABLE_OWNER_MODULE_LISTENER, 
    TCP_TABLE_OWNER_MODULE_CONNECTIONS, 
    TCP_TABLE_OWNER_MODULE_ALL 
} 

[StructLayout(LayoutKind.Sequential)] 
public struct MIB_TCPROW_OWNER_PID 
{ 
    public uint state; 
    public uint localAddr; 
    public byte localPort1; 
    public byte localPort2; 
    public byte localPort3; 
    public byte localPort4; 
    public uint remoteAddr; 
    public byte remotePort1; 
    public byte remotePort2; 
    public byte remotePort3; 
    public byte remotePort4; 
    public int owningPid; 

    public ushort LocalPort 
{ 
     get 
     { 
      return BitConverter.ToUInt16(
       new byte[2] { localPort2, localPort1}, 0); 
     } 
    } 

    public ushort RemotePort 
    { 
     get 
     { 
      return BitConverter.ToUInt16(
       new byte[2] { remotePort2, remotePort1}, 0); 
     } 
    } 
} 

[StructLayout(LayoutKind.Sequential)] 
public struct MIB_TCPTABLE_OWNER_PID 
{ 
    public uint dwNumEntries; 
    MIB_TCPROW_OWNER_PID table; 
} 

[DllImport("iphlpapi.dll", SetLastError=true)] 
static extern uint GetExtendedTcpTable(IntPtr pTcpTable, 
    ref int dwOutBufLen, 
    bool sort, 
    int ipVersion, 
    TCP_TABLE_CLASS tblClass, 
    int reserved); 

public static MIB_TCPROW_OWNER_PID[] GetAllTcpConnections() 
{ 
    MIB_TCPROW_OWNER_PID[] tTable; 
    int AF_INET = 2; // IP_v4 
    int buffSize = 0; 

    // how much memory do we need? 
    uint ret = GetExtendedTcpTable(IntPtr.Zero, 
     ref buffSize, 
     true, 
     AF_INET, 
     TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_ALL, 
     0);   
    if (ret != 0 && ret != 122) // 122 insufficient buffer size 
     throw new Exception("bad ret on check " + ret); 
    IntPtr buffTable = Marshal.AllocHGlobal(buffSize); 

    try 
    { 
     ret = GetExtendedTcpTable(buffTable, 
      ref buffSize, 
      true, 
      AF_INET, 
      TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_ALL, 
      0); 
     if (ret != 0) 
      throw new Exception("bad ret "+ ret);   

     // get the number of entries in the table 
     MIB_TCPTABLE_OWNER_PID tab = 
      (MIB_TCPTABLE_OWNER_PID)Marshal.PtrToStructure(
       buffTable, 
       typeof(MIB_TCPTABLE_OWNER_PID)); 
     IntPtr rowPtr = (IntPtr)((long)buffTable + 
      Marshal.SizeOf(tab.dwNumEntries)); 
     tTable = new MIB_TCPROW_OWNER_PID[tab.dwNumEntries]; 

     for (int i = 0; i < tab.dwNumEntries; i++) 
     { 
      MIB_TCPROW_OWNER_PID tcpRow = (MIB_TCPROW_OWNER_PID)Marshal 
       .PtrToStructure(rowPtr, typeof(MIB_TCPROW_OWNER_PID)); 
      tTable[i] = tcpRow; 
      // next entry 
      rowPtr = (IntPtr)((long)rowPtr + Marshal.SizeOf(tcpRow)); 
     } 
    } 
    finally 
    { 
     // Free the Memory 
     Marshal.FreeHGlobal(buffTable); 
    } 
    return tTable; 
} 
3

退房這個項目: ​​

它使用的Interop在C#中去的根本GetTcpTable贏API函數。因此可以給你你正在尋找的進程ID。

希望幫助, 亞歷

相關問題