枚举网络会话

时间:2010-03-10 15:14:13

标签: c# .net networking pinvoke

我想从计算机管理中提取有关已连接网络用户的数据 - >共享文件夹 - > Sessions选项卡进入我的c#应用程序。任何人都可以指导我必须使用哪些名称空间以及一些示例代码来从计算机管理导入用户名和IP地址 - >共享文件夹 - >会话标签?

此致

2 个答案:

答案 0 :(得分:6)

您需要NetSessionEnum,其中:

  

提供有关在服务器上建立的会话的信息。

当传递502级别时,它将返回一个数组:

  

......电脑的名称;用户名;打开计算机上的文件,管道和设备;以及客户端正在使用的传输的名称。

幸运的是,pinvoke.net有necessary signatures甚至一些示例代码。这是一个功能齐全的样本:

public class Program {
    public void Main(string[] args) {
        IntPtr pSessionInfo;
        IntPtr pResumeHandle = IntPtr.Zero;
        UInt32 entriesRead, totalEntries;

        var netStatus = NativeMethods.NetSessionEnum(
            null, // local computer
            null, // client name
            null, // username
            502, // include all info
            out pSessionInfo, // pointer to SESSION_INFO_502[]
            NativeMethods.MAX_PREFERRED_LENGTH,
            out entriesRead,
            out totalEntries,
            ref pResumeHandle
        );

        try {
            if (netStatus != NativeMethods.NET_API_STATUS.NERR_Success) {
                throw new InvalidOperationException(netStatus.ToString());
            }
            Console.WriteLine("Read {0} of {1} entries", entriesRead, totalEntries);
            for (int i = 0; i < entriesRead; i++) {
                var pCurrentSessionInfo = new IntPtr(pSessionInfo.ToInt32() + (NativeMethods.SESSION_INFO_502.SIZE_OF * i));
                var s = (NativeMethods.SESSION_INFO_502)Marshal.PtrToStructure(pCurrentSessionInfo, typeof(NativeMethods.SESSION_INFO_502));
                Console.WriteLine(
                    "User: {0}, Computer: {1}, Type: {2}, # Open Files: {3}, Connected Time: {4}s, Idle Time: {5}s, Guest: {6}",
                    s.sesi502_username,
                    s.sesi502_cname,
                    s.sesi502_cltype_name,
                    s.sesi502_num_opens,
                    s.sesi502_time,
                    s.sesi502_idle_time,
                    s.sesi502_user_flags == NativeMethods.SESSION_INFO_502_USER_FLAGS.SESS_GUEST
                );
            }
        } finally {
            NativeMethods.NetApiBufferFree(pSessionInfo);
        }
    }
}

public sealed class NativeMethods {
    [DllImport("netapi32.dll", SetLastError=true)]
    public static extern NET_API_STATUS NetSessionEnum(
            string serverName,
            string uncClientName,
            string userName,
            UInt32 level,
            out IntPtr bufPtr,
            int prefMaxLen,
            out UInt32 entriesRead,
            out UInt32 totalEntries,
            ref IntPtr resume_handle
    );

    [DllImport("netapi32.dll")]
    public static extern uint NetApiBufferFree(IntPtr Buffer);

    public const int MAX_PREFERRED_LENGTH = -1;

    public enum NET_API_STATUS : uint {
        NERR_Success = 0,
        NERR_InvalidComputer = 2351,
        NERR_NotPrimary = 2226,
        NERR_SpeGroupOp = 2234,
        NERR_LastAdmin = 2452,
        NERR_BadPassword = 2203,
        NERR_PasswordTooShort = 2245,
        NERR_UserNotFound = 2221,
        ERROR_ACCESS_DENIED = 5,
        ERROR_NOT_ENOUGH_MEMORY = 8,
        ERROR_INVALID_PARAMETER = 87,
        ERROR_INVALID_NAME = 123,
        ERROR_INVALID_LEVEL = 124,
        ERROR_MORE_DATA = 234 ,
        ERROR_SESSION_CREDENTIAL_CONFLICT = 1219
    }

    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
    public struct SESSION_INFO_502 {
        public static readonly int SIZE_OF = Marshal.SizeOf(typeof(SESSION_INFO_502));
        public string sesi502_cname;
        public string sesi502_username;
        public uint sesi502_num_opens;
        public uint sesi502_time;
        public uint sesi502_idle_time;
        public SESSION_INFO_502_USER_FLAGS sesi502_user_flags;
        public string sesi502_cltype_name;
        public string sesi502_transport;
    }

    public enum SESSION_INFO_502_USER_FLAGS : uint {
        SESS_GUEST = 1,
        SESS_NOENCRYPTION = 2
    }
}

答案 1 :(得分:0)

您不想与计算机管理进行交互,您希望调用它所执行的相同功能,并将中间人从循环中删除。

要了解当前的网络连接,您可能正在寻找WNetOpenEnumNetConnectionEnum

我不认为在BCL中有这样的.NET功能,你必须使用p / invoke或寻找第三方库(或我个人喜欢的,使用C ++ / CLI编写包装器) )