【问题标题】:Enumerating Network Sessions枚举网络会话
【发布时间】:2010-03-10 15:14:13
【问题描述】:

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

问候

【问题讨论】:

    标签: c# .net networking pinvoke


    【解决方案1】:

    你想要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
        }
    }
    

    【讨论】:

    • 只是想知道是否有人让这个样本工作....
    【解决方案2】:

    您不想与计算机管理交互,您想调用与它相同的函数并将中间人排除在循环之外。

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

    我认为 BCL 中没有 .NET 函数,您必须使用 p/invoke 或寻找第三方库(或者我个人最喜欢的,使用 C++/CLI 编写包装器)

    【讨论】:

    • 嗨,本,WNetOpenEnum 也在枚举所有连接的资源。我只想要通过 Active Directory 连接的用户的过滤列表。在服务器上,许多网络资源被连接和断开。所以它们对我没有用。我以前从未做过这种编程。任何实现这一点的资源都会非常有帮助。
    • 也许只列举连接到 NETLOGON$ 的用户就足够了,IIRC 任何用户都必须在使用任何其他资源之前连接到该用户。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-17
    • 1970-01-01
    • 2021-10-29
    • 2014-01-20
    相关资源
    最近更新 更多