C# 中的 NetServerEnum() 问题

发布于 2024-07-22 15:07:52 字数 3444 浏览 6 评论 0原文

我正在开发一个应用程序,需要列出所有当前的 LAN 机器。

为了列出 LAN 上的所有工作站,我在导入后使用了 NetServerEnum() 。

运行该程序时,它似乎运行良好。 两台现有机器均已正确检测。 但是,我希望在需要时刷新列表(某些刷新按钮)。 因此,我将另一台计算机的电线与交换机分开,只呈现局域网上的一台计算机。 现在,当我运行该程序时,它仍然列出已断开连接的机器。

怎么解决这个问题呢?

代码如下:

namespace LanIpAddresses
{
    class NetApi
    {
        [DllImport ( "Netapi32.dll", EntryPoint = "NetServerEnum" )]
        public static extern Int32 NetServerEnum (
            [MarshalAs (UnmanagedType.LPWStr)] String serverName,
            Int32 level,
            out IntPtr bufferPtr,
            UInt32 prefMaxLen,
            ref Int32 entriesRead,
            ref Int32 totalEntries,
            UInt32 serverType,
            [MarshalAs (UnmanagedType.LPWStr)] String domain,
            IntPtr handle );

        [DllImport ( "Netapi32.dll", EntryPoint = "NetApiBufferFree" )]
        public static extern UInt32 NetApiBufferFree ( IntPtr buffer );
    }


    class EnumerateLanMachines
    {
        public const UInt32 SUCCESS = 0;
        public const UInt32 FAIL = 234;
        public const UInt32 MAX_PREFERRED_LENGTH = 0xFFFFFFFF;
        //public ArrayList machines = new ArrayList ( );

        enum ServerTypes : uint
        {
            WorkStation = 0x00000001,
            Server = 0x00000002
        }

        [StructLayout ( LayoutKind.Sequential, CharSet = CharSet.Auto )]
        public struct MachineInfo
        {
            [MarshalAs ( UnmanagedType.U4 )]
            public UInt32 platformId;

            [MarshalAs ( UnmanagedType.LPWStr )]
            public String serverName;
        }

        public enum Platform
        { 
            PLATFORM_ID_DOS = 300,
            PLATFORM_ID_OS2 = 400,
            PLATFORM_ID_NT = 500,
            PLATFORM_ID_OSF = 600,
            PLATFORM_ID_VMS = 700
        }

        public void enumerateMachines ( )
        { 
            IntPtr buffer = new IntPtr();
            int totalEntries = 0;
            int entriesRead = 0;
            int result;

            result = NetApi.NetServerEnum ( null, 100, out buffer, MAX_PREFERRED_LENGTH, ref entriesRead, ref totalEntries, (uint) ServerTypes.WorkStation, null, IntPtr.Zero );

            MachineInfo machineInfo;

            if (result != FAIL)
            {
                Console.WriteLine ( "Succeeded!" );
                Console.WriteLine ( entriesRead );
                for (int i = 0; i < entriesRead; ++i)
                {
                    machineInfo = (MachineInfo) Marshal.PtrToStructure ( buffer, typeof ( MachineInfo ) );

                    //machines.Add ( machineInfo );
                    Console.WriteLine ( machineInfo.serverName );

                    buffer = (IntPtr) ( (ulong) buffer + (ulong) Marshal.SizeOf ( machineInfo ) );
                }

                NetApi.NetApiBufferFree ( buffer );
            }
        }
    }
}
namespace LanIpAddresses
{
    class Program
    {
        private static IPHostEntry ipHost;
        static ArrayList ipList;

        static void Main ( string[ ] args )
        {
            EnumerateLanMachines enumerate = new EnumerateLanMachines ( );

            enumerate.enumerateMachines ( );

            /*foreach (EnumerateLanMachines.MachineInfo o in enumerate.machines)
            {
                Console.WriteLine ( o.platformId + " " + o.serverName );
            }*/

            Console.ReadLine ( );
        }
    }
}

I am developing an application which requires to list all the current LAN machines.

Inorder to list all the workstations on a LAN, i have used NetServerEnum() after importing it.

On running the program, it seemed to work fine. The two existing machines were detected correctly.
However, i want the list to be refreshed whenever required (some refresh button). So i detached the wire of the other computer from the switch, rendering only a single computer on the LAN.
Now, when i ran the program, it still lists out the disconnected machine.

How to solve this out?

The code is as follows :

namespace LanIpAddresses
{
    class NetApi
    {
        [DllImport ( "Netapi32.dll", EntryPoint = "NetServerEnum" )]
        public static extern Int32 NetServerEnum (
            [MarshalAs (UnmanagedType.LPWStr)] String serverName,
            Int32 level,
            out IntPtr bufferPtr,
            UInt32 prefMaxLen,
            ref Int32 entriesRead,
            ref Int32 totalEntries,
            UInt32 serverType,
            [MarshalAs (UnmanagedType.LPWStr)] String domain,
            IntPtr handle );

        [DllImport ( "Netapi32.dll", EntryPoint = "NetApiBufferFree" )]
        public static extern UInt32 NetApiBufferFree ( IntPtr buffer );
    }


    class EnumerateLanMachines
    {
        public const UInt32 SUCCESS = 0;
        public const UInt32 FAIL = 234;
        public const UInt32 MAX_PREFERRED_LENGTH = 0xFFFFFFFF;
        //public ArrayList machines = new ArrayList ( );

        enum ServerTypes : uint
        {
            WorkStation = 0x00000001,
            Server = 0x00000002
        }

        [StructLayout ( LayoutKind.Sequential, CharSet = CharSet.Auto )]
        public struct MachineInfo
        {
            [MarshalAs ( UnmanagedType.U4 )]
            public UInt32 platformId;

            [MarshalAs ( UnmanagedType.LPWStr )]
            public String serverName;
        }

        public enum Platform
        { 
            PLATFORM_ID_DOS = 300,
            PLATFORM_ID_OS2 = 400,
            PLATFORM_ID_NT = 500,
            PLATFORM_ID_OSF = 600,
            PLATFORM_ID_VMS = 700
        }

        public void enumerateMachines ( )
        { 
            IntPtr buffer = new IntPtr();
            int totalEntries = 0;
            int entriesRead = 0;
            int result;

            result = NetApi.NetServerEnum ( null, 100, out buffer, MAX_PREFERRED_LENGTH, ref entriesRead, ref totalEntries, (uint) ServerTypes.WorkStation, null, IntPtr.Zero );

            MachineInfo machineInfo;

            if (result != FAIL)
            {
                Console.WriteLine ( "Succeeded!" );
                Console.WriteLine ( entriesRead );
                for (int i = 0; i < entriesRead; ++i)
                {
                    machineInfo = (MachineInfo) Marshal.PtrToStructure ( buffer, typeof ( MachineInfo ) );

                    //machines.Add ( machineInfo );
                    Console.WriteLine ( machineInfo.serverName );

                    buffer = (IntPtr) ( (ulong) buffer + (ulong) Marshal.SizeOf ( machineInfo ) );
                }

                NetApi.NetApiBufferFree ( buffer );
            }
        }
    }
}
namespace LanIpAddresses
{
    class Program
    {
        private static IPHostEntry ipHost;
        static ArrayList ipList;

        static void Main ( string[ ] args )
        {
            EnumerateLanMachines enumerate = new EnumerateLanMachines ( );

            enumerate.enumerateMachines ( );

            /*foreach (EnumerateLanMachines.MachineInfo o in enumerate.machines)
            {
                Console.WriteLine ( o.platformId + " " + o.serverName );
            }*/

            Console.ReadLine ( );
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

落墨 2024-07-29 15:07:52

当使用 NetServerEnum 时,就是使用 Windows 浏览器服务。 主浏览器维护网络中的计算机列表。 如果一台计算机在网络上宣布自己,然后关闭,则主浏览器会将该计算机保留在其列表中。

http://support.microsoft.com/kb/188001

如果您改为询问 Active Directory关于网络中的计算机,那么您还会获得已注册计算机的列表,但这并不意味着列表中的所有计算机都在线。

When using NetServerEnum then one is using the Windows Browser Service. The master browser maintains a list of computers in the network. If a computer announces it self on the network and then is turned off, then the Master Browser will keep that computer in its list.

http://support.microsoft.com/kb/188001

If you instead asked the Active Directory about the computers in the network, then you would also get a list of registered computers, but this doesn't mean all the computers in the list are online.

一生独一 2024-07-29 15:07:52

我无法解决这个问题。 然而,我选择了另一种方法 - ping 整个可能的 IP 范围并连接到机器。

然而,我欢迎任何关于这个仍然挥之不去的问题的答案:)

I could not solve this problem. However, i chose another way - to ping the whole possible IP range and connect to the machines.

However, i would welcome any answers on this still lingering question :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文