使用NetServerEnum()查找网络上的所有计算机

时间:2013-12-11 06:39:53

标签: c# .net network-programming

我试图找到网络上的所有计算机。以下代码适用于Win7-32​​bit,但为Win7-64bit提供以下错误。

NetServerEnum()正在返回代码-6118。

public sealed class NetworkBrowser
{
    [DllImport("Netapi32", CharSet = CharSet.Auto, SetLastError = true), SuppressUnmanagedCodeSecurityAttribute]
    public static extern int NetServerEnum(
        string serverName,
        int dwLevel,
        ref IntPtr pBuf,
        int dwPrefMaxLen,
        out int dwEntriesRead,
        out int dwTotalEntries,
        int dwServerType,
        string domain,
        out int dwResumeHandle
        );

    [DllImport("Netapi32", SetLastError = true), SuppressUnmanagedCodeSecurity]
    public static extern int NetApiBufferFree(IntPtr pBuf);

    [StructLayout(LayoutKind.Sequential)]
    public struct ServerInfo100
    {
        internal int sv100_platform_id;
        [MarshalAs(UnmanagedType.LPWStr)]
        internal string sv100_name;
    }

    public static ArrayList GetNetworkComputers()
    {
        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;
        int totalEntries;
        int resHandle;
        int sizeofInfo = Marshal.SizeOf(typeof(ServerInfo100));


        try
        {
            int ret = NetServerEnum(null, 100, ref buffer,
                                    MAX_PREFERRED_LENGTH, out entriesRead, out totalEntries,
                                    SV_TYPE_WORKSTATION | SV_TYPE_SERVER, null, out resHandle);

            if (ret == 0)
            {
                for (int i = 0; i < totalEntries; i++)
                {
                    tmpBuffer = new IntPtr((int)buffer +(i * sizeofInfo));

                    ServerInfo100 svrInfo = (ServerInfo100)
                                               Marshal.PtrToStructure(tmpBuffer,
                                                                      typeof(ServerInfo100));
                    networkComputers.Add(svrInfo.sv100_name);
                }
            }
        }
        catch (Exception ex)
        {
            return null;
        }
        finally
        {
            NetApiBufferFree(buffer);
        }
        return networkComputers;
    }
}

我已经搜索了很多内容,但是没有找到任何解决方案。

4 个答案:

答案 0 :(得分:1)

我认为,这完全回答了你的问题。

Retrieving a list of network computer names using C# - Code project article comment

  

错误和解决方案 - designmaistro - 25-Feb-14 23:46

     

我已经读过,有些人在基于x64的系统上使用这段代码时遇到了问题。它可能与指针操作有关,更准确地说,这一行是代码中断的地方:

     

tmpBuffer = new IntPtr((int)buffer + (i * sizeofINFO));

     

因为在x64系统上,地址空间的宽度为64位,所以代码应更改为:

     

tmpBuffer = new IntPtr((long)buffer + (i * sizeofINFO));

     

在此更改后,一切都应该正常工作。   最好的问候!

答案 1 :(得分:0)

可能会有所帮助

http://social.msdn.microsoft.com/Forums/windows/en-US/1107608f-ef56-4719-a5e5-f6966d111043/win32-api-compatibility-on-windows-7-64-bit?forum=winforms

它说 “当您将应用程序的目标平台设置为'AnyCPU'时,默认情况下它将在64位计算机上以64位模式运行,并在32位计算机上以32位模式运行。现在,假设您的应用程序以64位模式运行这个时间点,它必须调用一些特定于32位机器的API或代码(比如你的PrintDlg API)。但是,由于你的进程已经在64位模式下运行,你的32位代码无法加载,因此它将会失败。

将Target平台设置为x86 - 您的应用程序将始终以32位和32位模式运行。 64位机器。由于应用程序始终以32位模式运行,因此也可以毫无问题地调用32位组件或API。现在,唯一的问题是 - 如果您有任何64位特定组件,则无法调用它(因为64位代码无法在32位进程中运行)。但我认为这不是一个问题,因为你专门为64位机器设计应用程序。“

答案 2 :(得分:0)

使用此注释完成了您的功能:

[DllImport("Netapi32", CharSet = CharSet.Unicode, SetLastError = true)]

代替:

[DllImport("Netapi32", CharSet = CharSet.Auto, SetLastError = true), SuppressUnmanagedCodeSecurityAttribute]

问候。

答案 3 :(得分:-1)

int ret = NetServerEnum(null,100,ref buffer,                                     MAX_PREFERRED_LENGTH,out entriesRead,out totalEntries,                                     SV_TYPE_WORKSTATION | SV_TYPE_SERVER,null,out resHandle);

您需要将域名传递给初始化
int ret = NetServerEnum(null,100,ref buffer,                                     MAX_PREFERRED_LENGTH,out entriesRead,out totalEntries,                                     SV_TYPE_WORKSTATION | SV_TYPE_SERVER, domainName ,out resHandle);

它完美无缺

由于