Enumerating Network Sessions

2019-01-27 01:59发布

I wanted to pull data about the connected network users from the Computer Management -> Shared Folders -> Sessions tab into my c# application. Can anybody guide me on what namespaces have to be used along with some sample code to import username and ip address from Computer Management -> Shared Folders -> Sessions tab?

Regards

2条回答
祖国的老花朵
2楼-- · 2019-01-27 02:11

You don't want to interact with Computer Management, you want to call the same functions it does and cut the middle man out of the loop.

For finding out about current network connection, you might be looking for WNetOpenEnum or NetConnectionEnum

I don't think there's a .NET function for this in the BCL, you'd have to use p/invoke or look for a third-party library (or my personal favorite, use C++/CLI to write a wrapper)

查看更多
老娘就宠你
3楼-- · 2019-01-27 02:12

You want NetSessionEnum, which:

Provides information about sessions established on a server.

When passed a level of 502, it'll return an array of:

...the name of the computer; name of the user; open files, pipes, and devices on the computer; and the name of the transport the client is using.

Luckily for you, pinvoke.net has the necessary signatures and even some sample code. Here's a full featured sample:

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
    }
}
查看更多
登录 后发表回答