1

現在のすべての LAN マシンを一覧表示する必要があるアプリケーションを開発しています。

LAN 上のすべてのワークステーションを一覧表示するために、インポート後に NetServerEnum() を使用しました。

プログラムを実行すると、問題なく動作するように見えました。2 台の既存のマシンが正しく検出されました。ただし、必要に応じてリストを更新したい (更新ボタン)。そこで、他のコンピューターの配線をスイッチから切り離し、LAN 上に 1 台のコンピューターのみをレンダリングしました。今、プログラムを実行すると、切断されたマシンがまだリストされています。

これを解決する方法は?

コードは次のとおりです。

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 ( );
        }
    }
}
4

2 に答える 2

1

NetServerEnum を使用する場合、Windows Browser Service を使用しています。マスタ ブラウザは、ネットワーク内のコンピュータのリストを維持します。コンピュータがネットワーク上で自身を通知した後、電源をオフにすると、マスタ ブラウザはそのコンピュータをリストに保持します。

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

代わりに、ネットワーク内のコンピューターについて Active Directory に問い合わせると、登録済みコンピューターのリストも取得されますが、これはリスト内のすべてのコンピューターがオンラインであることを意味するわけではありません。

于 2009-12-17T22:36:54.720 に答える
0

この問題を解決できませんでした。しかし、私は別の方法を選びました - 可能な IP 範囲全体に ping を実行し、マシンに接続することです。

ただし、このまだ長引く質問に対する回答を歓迎します:)

于 2009-06-19T06:19:45.463 に答える