【问题标题】:c# network discovery [duplicate]c#网络发现[重复]
【发布时间】:2013-03-28 16:49:05
【问题描述】:

我正在开发一个 C# 应用程序,我需要发现 LAN 中的计算机和打印机。如何从 .NET 执行此操作? .NET 框架中是否有我可以使用的类。感谢您的回答。

【问题讨论】:

    标签: c# .net networking discovery


    【解决方案1】:

    您可以使用 DirectoryServices 获取计算机。

        System.DirectoryServices.DirectoryEntry winNtDirectoryEntries = new System.DirectoryServices.DirectoryEntry("WinNT:");
        List<String> computerNames = (from DirectoryEntry availDomains in winNtDirectoryEntries.Children 
                                      from DirectoryEntry pcNameEntry in availDomains.Children 
                                      where pcNameEntry.SchemaClassName.ToLower().Contains("computer") 
                                      select pcNameEntry.Name).ToList();
    

    【讨论】:

    • 非常有帮助,谢谢。
    【解决方案2】:

    这可能会对您有所帮助:http://www.codeproject.com/Articles/16113/Retreiving-a-list-of-network-computer-names-using

    using System;
    using System.Runtime.InteropServices;
    using System.Security;
    using System.Collections;
    
    namespace ListNetworkComputers
    {
        #region NetworkBrowser CLASS
        /// <summary>
        /// Provides a mechanism for supplying
        // a list of all PC names in the local network.
        /// This collection of PC names is used in the form 
        /// 
    
    
        /// This class makes use of a DllImport instruction.
        /// The purpose of which is as follows:
        /// When a DllImport declaration is made
        /// in managed code (C#) it is a call to a legacy
        /// unmanaged code module, normally
        /// a C++ Dynamic Link Library. These C++ Dll's are
        /// usually part of the operating system API,
        /// or some other vendors API, and must be 
        /// used to carry out operations that are not
        /// native within the managed code C# framework. 
        /// This is fairly normal within the windows world.
        /// The only thing that needs careful consideration
        /// is the construction of the correct type of STRUCTS,
        /// object pointers, and attribute markers,
        /// which all contribute to making the link
        /// between managed (C#) and unmanaged code (C++)
        /// more seamless
        /// 
    
        /// This class makes use of the following Dll calls
        /// <list type="bullet">
        /// <item>
        /// <description> Netapi32.dll : NetServerEnum,
        /// The NetServerEnum function lists all servers
        /// of the specified type that are visible in
        /// a domain. For example, an application can call 
        /// NetServerEnum to list all domain controllers
        /// only or all SQL servers only.
        /// You can combine bit masks to list several
        /// types. For example, a value of 0x00000003 
        /// combines the bit masks for SV_TYPE_WORKSTATION
        /// (0x00000001) and SV_TYPE_SERVER (0x00000002).
        /// </description>
        /// </item>
        /// <item>
        /// <description> Netapi32.dll : NetApiBufferFree,
        /// The NetApiBufferFree function frees 
        /// the memory that the NetApiBufferAllocate
        /// function allocates. Call NetApiBufferFree 
        /// to free the memory that other network
        /// management functions return.</description>
        /// </item>
        /// </list>
        /// </summary>
        public sealed class NetworkBrowser
        {
            #region Dll Imports
    
            //declare the Netapi32 : NetServerEnum method import
            [DllImport("Netapi32", CharSet = CharSet.Auto,
            SetLastError = true),
            SuppressUnmanagedCodeSecurityAttribute]
    
            /// <summary>
            /// Netapi32.dll : The NetServerEnum function lists all servers
            /// of the specified type that are
            /// visible in a domain. For example, an 
            /// application can call NetServerEnum
            /// to list all domain controllers only
            /// or all SQL servers only.
            /// You can combine bit masks to list
            /// several types. For example, a value 
            /// of 0x00000003  combines the bit
            /// masks for SV_TYPE_WORKSTATION 
            /// (0x00000001) and SV_TYPE_SERVER (0x00000002)
            /// </summary>
            public static extern int NetServerEnum(
                string ServerNane, // must be null
                int dwLevel,
                ref IntPtr pBuf,
                int dwPrefMaxLen,
                out int dwEntriesRead,
                out int dwTotalEntries,
                int dwServerType,
                string domain, // null for login domain
                out int dwResumeHandle
                );
    
            //declare the Netapi32 : NetApiBufferFree method import
            [DllImport("Netapi32", SetLastError = true),
            SuppressUnmanagedCodeSecurityAttribute]
    
            /// <summary>
            /// Netapi32.dll : The NetApiBufferFree function frees 
            /// the memory that the NetApiBufferAllocate function allocates. 
            /// Call NetApiBufferFree to free
            /// the memory that other network 
            /// management functions return.
            /// </summary>
            public static extern int NetApiBufferFree(
                IntPtr pBuf);
    
            //create a _SERVER_INFO_100 STRUCTURE
            [StructLayout(LayoutKind.Sequential)]
            public struct _SERVER_INFO_100
            {
                internal int sv100_platform_id;
                [MarshalAs(UnmanagedType.LPWStr)]
                internal string sv100_name;
            }
            #endregion
            #region Public Constructor
            /// <SUMMARY>
            /// Constructor, simply creates a new NetworkBrowser object
            /// </SUMMARY>
            public NetworkBrowser()
            {
    
            }
            #endregion
            #region Public Methods
            /// <summary>
            /// Uses the DllImport : NetServerEnum
            /// with all its required parameters
            /// (see http://msdn.microsoft.com/library/default.asp?
            ///      url=/library/en-us/netmgmt/netmgmt/netserverenum.asp
            /// for full details or method signature) to
            /// retrieve a list of domain SV_TYPE_WORKSTATION
            /// and SV_TYPE_SERVER PC's
            /// </summary>
            /// <returns>Arraylist that represents
            /// all the SV_TYPE_WORKSTATION and SV_TYPE_SERVER
            /// PC's in the Domain</returns>
            public ArrayList getNetworkComputers()
            {
                //local fields
                ArrayList networkComputers = new ArrayList();
                const int MAX_PREFERRED_LENGTH = -1;
                int SV_TYPE_WORKSTATION = 1;
                int SV_TYPE_SERVER = 2;
                IntPtr buffer = IntPtr.Zero;
                IntPtr tmpBuffer = IntPtr.Zero;
                int entriesRead = 0;
                int totalEntries = 0;
                int resHandle = 0;
                int sizeofINFO = Marshal.SizeOf(typeof(_SERVER_INFO_100));
    
    
                try
                {
                    //call the DllImport : NetServerEnum 
                    //with all its required parameters
                    //see http://msdn.microsoft.com/library/
                    //default.asp?url=/library/en-us/netmgmt/netmgmt/netserverenum.asp
                    //for full details of method signature
                    int ret = NetServerEnum(null, 100, ref buffer,
                        MAX_PREFERRED_LENGTH,
                        out entriesRead,
                        out totalEntries, SV_TYPE_WORKSTATION |
                        SV_TYPE_SERVER, null, out 
                        resHandle);
                    //if the returned with a NERR_Success 
                    //(C++ term), =0 for C#
                    if (ret == 0)
                    {
                        //loop through all SV_TYPE_WORKSTATION 
                        //and SV_TYPE_SERVER PC's
                        for (int i = 0; i < totalEntries; i++)
                        {
                            //get pointer to, Pointer to the 
                            //buffer that received the data from
                            //the call to NetServerEnum. 
                            //Must ensure to use correct size of 
                            //STRUCTURE to ensure correct 
                            //location in memory is pointed to
                            tmpBuffer = new IntPtr((int)buffer +
                                       (i * sizeofINFO));
                            //Have now got a pointer to the list 
                            //of SV_TYPE_WORKSTATION and 
                            //SV_TYPE_SERVER PC's, which is unmanaged memory
                            //Needs to Marshal data from an 
                            //unmanaged block of memory to a 
                            //managed object, again using 
                            //STRUCTURE to ensure the correct data
                            //is marshalled 
                            _SERVER_INFO_100 svrInfo = (_SERVER_INFO_100)
                                Marshal.PtrToStructure(tmpBuffer,
                                        typeof(_SERVER_INFO_100));
    
                            //add the PC names to the ArrayList
                            networkComputers.Add(svrInfo.sv100_name);
                        }
                    }
                }
                catch (Exception ex)
                {
                    return null;
                }
                finally
                {
                    //The NetApiBufferFree function frees 
                    //the memory that the 
                    //NetApiBufferAllocate function allocates
                    NetApiBufferFree(buffer);
                }
                //return entries found
                return networkComputers;
    
            }
            #endregion
        }
        #endregion
    }
    

    用法:

    static void Main(string[] args)
    {
        ListNetworkComputers.NetworkBrowser browser = new ListNetworkComputers.NetworkBrowser();
        ArrayList networks = browser.getNetworkComputers();
        foreach(object item in networks)
        {
            Console.WriteLine(item.ToString());
        }
        Console.Read();
    }
    

    【讨论】:

    • 这可能会有所帮助,但我期待一个更清洁的解决方案,即 .NET 内部的东西。 .NET 框架内真的没有解决方案吗?
    【解决方案3】:

    我不确定你尝试了什么;也不知道你的目标是什么。您可以通过以下方式完成:

    • 启动 Process,它将调用批处理文件或 powershell 脚本。
    • 实现DirectoryServices.dll。

    如果你实现了上述,针对Workgroup

    using (DirectoryEntry workgroup = new DirectoryEntry("WinNT://Workgroup"))
    {
        foreach (DirectoryEntry childEntry in workgroup.Children)
        {
             Console.WriteLine(child.Name);
        }
    }
    

    这将允许您针对特定的Workgroup 进行测试。对整个 Domain 进行测试的示例如下:

    using (DirectoryEntry domain = new DirectoryENtry("LDAP://" + domainName))
    {
         domain.Children.SchemaFilter.Add("computer");
         foreach (DirectoryEntry d in domain.Childern)
         {
              Console.WriteLine(d.Name);
         }
    }
    

    如您所见,您在此处具有相当大的灵活性。显然,您可以为执行Netview 的批处理文件实现Process。这是非常基本的。

    另一个选择是 Powershell。它可以访问WMI,因此您将能够提取大量信息。加上大量的 IT 社区依赖它,有很多脚本可以完成这项任务。

    希望对您有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-27
      • 2016-10-12
      • 1970-01-01
      • 1970-01-01
      • 2011-10-11
      • 2014-08-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多