|











|
 | PDC, BDC, SQL サーバなどのサーバをリストする |
|
|
|
|
ネットに接続しているサーバをリストします。 このぐらい、Platform SDK じゃなくって、System.Net あたりに用意しておけよ!って感じ。 |
|
(1) MSDN
NetApi32 (2) MSDN
WNet (2) C# プログラミング: InterOp
|
|
Platform SDK: NetApi32と、Windows Networking
(WNet)が考えられます。
| 方法 |
メリット |
デメリット |
Platform SDK NetApi32 | PDC, BDC, SQL サーバなどのサーバの種類を指定してリストできる。 |
NetBIOS のない環境ではサポートされません。 Windows NT/2000:Windows NT 3.1 以降のみ Windows 95/98:対応していません |
Platform SDK WNet | Windows NT/2000:Windows NT 3.1 以降 Windows 95/98:Windows 95 以降 | PDC, BDC, SQL サーバなどのサーバの種類を指定できない。 |
|
|
|
Kernel32.dll の SetEnvironmentVariable(),
GetEnvironmentVariable() のプラットフォームSDK 呼び出しを行います。 呼び出しは次の2つのステップになります。
| (1) NetServerEnum |
[DllImport("netapi32")]
public static extern int NetServerEnum (
[In] string servername, // 予約済み
[In] uint level, // 情報レベル
[Out] out IntPtr bufptr, // 情報が格納されるバッファ
[In] uint prefmaxlen, // バッファの最大サイズ
[Out] out uint entriesread, // 格納されたエントリの数
[Out] out uint totalentries, // 利用可能なエントリの総数
[In] uint servertype, // サーバーのタイプ
[In] string domain, // 列挙対象のドメイン
[In, Out] ref uint resume_handle // レジュームハンドル
);
|
| (2) NetApiBufferFree |
[DllImport("netapi32")]
public static extern int NetApiBufferFree(
[In] IntPtr lpBuffer);
|
| 実行例 |
ServerName:UCHUKAMEN Platform:PLATFORM_ID_NT MajorVersion:5 MinorVersion:1 Type:201219 Comment:コメントです
|
|
|
Kernel32.dll の SetEnvironmentVariable(),
GetEnvironmentVariable() のプラットフォームSDK 呼び出しを行います。 呼び出しは次の3つのステップになります。
| (1) WNetOpenEnum |
[DllImport("Mpr.dll")]
public static extern uint WNetOpenEnum(
[In] WNet.Scope dwScope,
[In] WNet.Type dwType,
[In] WNet.Usage dwUsage,
[In] IntPtr lpNetResource,
[Out] out IntPtr lphEnum);
|
| (2) WNetEnumResource |
[DllImport("Mpr.dll")]
public static extern uint WNetEnumResource(
[In] IntPtr hEnum,
[In, Out] ref uint lpcCount,
[Out] IntPtr lpBuffer,
[In, Out] ref uint lpBufferSize);
|
| (3) WNetCloseEnum |
[DllImport("Mpr.dll")]
public static extern uint WNetCloseEnum(
[In] IntPtr hEnum);
|
| 実行例 |
lpProvider:Microsoft Windows Network lpRemoteName:\\UCHUKAMEN lpComment:コメントです lpProvider:Microsoft Windows Network |
|
|
|
| 2003/6/8 初版作成。 |
|
|
| NetApi32 用ライブラリ |
using System;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;
namespace Uchukamen
{
/// <summary>
/// NetApi32 の概要の説明です。
/// </summary>
public class NetApi32
{
public NetApi32()
{
}
#region 高レベル・メソッド
public string [] GetServerName()
{
return GetServerName(null);
}
public string [] GetServerName(string domain)
{
return GetServerName(domain, NetApi32.ServerType.SV_TYPE_SQLSERVER);
}
public string [] GetSQLServerName()
{
return GetServerName(null, NetApi32.ServerType.SV_TYPE_SQLSERVER);
}
public string [] GetSQLServerName(string domain)
{
return GetServerName(domain, NetApi32.ServerType.SV_TYPE_SQLSERVER);
}
public string [] GetServerName(NetApi32.ServerType servtype)
{
return GetServerName(null, servtype);
}
/// <summary>
/// GetServerName(string domain)
/// </summary>
/// <param name="domain"></param>
/// <returns>ServerInfo []</returns>
public string [] GetServerName(string domain, NetApi32.ServerType stype)
{
string servername = null; // 予約されています。NULL を指定します。
uint level = 100;
IntPtr bufptr;
uint prefmaxlen = NetApi32.MAX_PREFERRED_LENGTH;
uint entriesread;
uint totalentries;
uint servertype = (uint)(stype);
uint resume_handle = 0;
int result;
result = NetApi32.NetServerEnum (servername, level,
out bufptr, prefmaxlen, out entriesread,
out totalentries, servertype,
domain, ref resume_handle);
Type t = typeof(NetApi32.SERVER_INFO_100);
int offset = Marshal.SizeOf( t );
string [] server = new string[totalentries];
for (int index = 0; index < (int)totalentries; index++)
{
IntPtr ptr = new IntPtr(bufptr.ToInt32() + index * offset);
NetApi32.SERVER_INFO_100 info = (NetApi32.SERVER_INFO_100)(Marshal.PtrToStructure(ptr, t));
server[index] = Marshal.PtrToStringUni(info.sv100_name);
Debug.WriteLine("sv100_name:" + Marshal.PtrToStringUni(info.sv100_name));
}
NetApi32.NetApiBufferFree(bufptr);
return server;
}
/// <summary>
/// サーバの情報を取得する。
/// </summary>
public struct ServerInfo
{
public PlatformID Platform;
public string ServerName;
public uint MajorVersion;
public uint MinorVersion;
public uint Type;
public string Comment;
}
public ServerInfo [] GetServerInfo()
{
return GetServerInfo(null, NetApi32.ServerType.SV_TYPE_ALL);
}
public ServerInfo [] GetSQLServerInfo()
{
return GetServerInfo(null, NetApi32.ServerType.SV_TYPE_SQLSERVER);
}
public ServerInfo [] GetServerInfo(string domain)
{
return GetServerInfo(domain, NetApi32.ServerType.SV_TYPE_ALL);
}
public ServerInfo [] GetSQLServerInfo(string domain)
{
return GetServerInfo(domain, NetApi32.ServerType.SV_TYPE_SQLSERVER);
}
public ServerInfo [] GetServerInfo(NetApi32.ServerType servtype)
{
return GetServerInfo(null, servtype);
}
public ServerInfo[] GetServerInfo(string domain, NetApi32.ServerType stype)
{
string servername = null; // 予約されています。NULL を指定します。
uint level = 101;
IntPtr bufptr;
uint prefmaxlen = NetApi32.MAX_PREFERRED_LENGTH;
uint entriesread;
uint totalentries;
uint servertype = (uint)(stype);
uint resume_handle = 0;
int result;
result = NetApi32.NetServerEnum (servername, level,
out bufptr, prefmaxlen, out entriesread,
out totalentries, servertype,
domain, ref resume_handle);
Type t = typeof(NetApi32.SERVER_INFO_101);
int offset = Marshal.SizeOf(t);
ServerInfo[] sinfo = new ServerInfo[totalentries];
for (int index = 0; index < (int)totalentries; index++)
{
IntPtr ptr = new IntPtr(bufptr.ToInt32() + index * offset);
NetApi32.SERVER_INFO_101 info = (NetApi32.SERVER_INFO_101)(Marshal.PtrToStructure(ptr, t));
sinfo[index].ServerName = Marshal.PtrToStringUni(info.sv101_name);
sinfo[index].Platform = (PlatformID)info.sv101_platform_id;
sinfo[index].MajorVersion = info.sv101_version_major;
sinfo[index].MinorVersion = info.sv101_version_minor;
sinfo[index].Type = info.sv101_type;
sinfo[index].Comment = Marshal.PtrToStringUni(info.sv101_comment);
Debug.WriteLine("ServerName:" + sinfo[index].ServerName);
Debug.WriteLine("Platform:" + sinfo[index].Platform);
Debug.WriteLine("MajorVersion:" + sinfo[index].MajorVersion);
Debug.WriteLine("MinorVersion:" + sinfo[index].MinorVersion);
Debug.WriteLine("Type:" + sinfo[index].Type);
Debug.WriteLine("Comment:" + sinfo[index].Comment);
}
NetApi32.NetApiBufferFree(bufptr);
return sinfo;
}
#endregion
#region 低レベルメソッド用 定数
public const uint MAX_PREFERRED_LENGTH = unchecked((uint)-1);
public enum ServerType : uint
{
SV_TYPE_WORKSTATION = 0x00000001, // すべてのワークステーション
SV_TYPE_SERVER = 0x00000002, // すべてのサーバー
SV_TYPE_SQLSERVER = 0x00000004, // すべてのMS SQL Server
SV_TYPE_DOMAIN_CTRL = 0x00000008, // プライマリドメインコントローラ
SV_TYPE_DOMAIN_BAKCTRL = 0x00000010, // バックアップドメインコントローラ
SV_TYPE_TIME_SOURCE = 0x00000020, // Timesource サービスを実行しているサーバー
SV_TYPE_AFP = 0x00000040, // Apple File Protocol(AFP)サーバー
SV_TYPE_NOVELL = 0x00000080, // Novell サーバー
SV_TYPE_DOMAIN_MEMBER = 0x00000100, // LAN Manager 2.x のドメインメンバ
SV_TYPE_PRINTQ_SERVER = 0x00000200, // プリントキューを共有するサーバー
SV_TYPE_DIALIN_SERVER = 0x00000400, // ダイヤルインサービスを実行しているサーバー
SV_TYPE_XENIX_SERVER = 0x00000800, // Xenix サーバー
SV_TYPE_SERVER_UNIX = SV_TYPE_XENIX_SERVER, //
SV_TYPE_NT = 0x00001000, // Windows NT/2000 のワークステーションまたはサーバー
SV_TYPE_WFW = 0x00002000, // Windows for Workgroups を実行しているサーバー
SV_TYPE_SERVER_MFPN = 0x00004000, //
SV_TYPE_SERVER_NT = 0x00008000, // ドメインコントローラではない、Windows NT/2000 のサーバー
SV_TYPE_POTENTIAL_BROWSER = 0x00010000, // ブラウザサービスを実行できるサーバー
SV_TYPE_BACKUP_BROWSER = 0x00020000, // バックアップとしてブラウザサービスを実行しているサーバー
SV_TYPE_MASTER_BROWSER = 0x00040000, // マスタブラウザサービスを実行しているサーバー
SV_TYPE_DOMAIN_MASTER = 0x00080000, // ドメインマスタブラウザを実行しているサーバー
SV_TYPE_SERVER_OSF = 0x00100000, //
SV_TYPE_SERVER_VMS = 0x00200000, //
SV_TYPE_WINDOWS = 0x00400000, // Windows 95 以降
SV_TYPE_DFS = 0x00800000, //
SV_TYPE_CLUSTER_NT = 0x01000000, // ドメイン内で利用できるサーバークラスタ
SV_TYPE_TERMINALSERVER = 0x02000000, // Terminal Server
SV_TYPE_CLUSTER_VS_NT = 0x04000000, // NT Cluster Virtual Server Name
SV_TYPE_DCE = 0x10000000, // IBM DSS or equivalent
SV_TYPE_ALTERNATE_XPORT = 0x20000000, // return list for alternate transport
SV_TYPE_LOCAL_LIST_ONLY = 0x40000000, // Return local list only
SV_TYPE_DOMAIN_ENUM = 0x80000000,
SV_TYPE_ALL = 0xFFFFFFFF // すべてのサーバー
}
public enum PlatformID : uint
{
PLATFORM_ID_DOS = 300,
PLATFORM_ID_OS2 = 400,
PLATFORM_ID_NT = 500,
PLATFORM_ID_OSF = 600,
PLATFORM_ID_VMS = 700
}
/*
typedef struct _SERVER_INFO_100
{
DWORD sv100_platform_id;
LPWSTR sv100_name;
} SERVER_INFO_100, *PSERVER_INFO_100, *LPSERVER_INFO_100;
*/
[StructLayout(LayoutKind.Sequential)]
public struct SERVER_INFO_100
{
public uint sv100_platform_id;
public IntPtr sv100_name;
}
/*
typedef struct _SERVER_INFO_101
{
DWORD sv101_platform_id;
LPWSTR sv101_name;
DWORD sv101_version_major;
DWORD sv101_version_minor;
DWORD sv101_type;
LPWSTR sv101_comment;
} SERVER_INFO_101, *PSERVER_INFO_101, *LPSERVER_INFO_101;
*/
[StructLayout(LayoutKind.Sequential)]
public struct SERVER_INFO_101
{
public uint sv101_platform_id;
public IntPtr sv101_name;
public uint sv101_version_major;
public uint sv101_version_minor;
public uint sv101_type;
public IntPtr sv101_comment;
}
#endregion
#region 低レベルメソッド
/*
NET_API_STATUS NetServerEnum(
LPCWSTR servername, // 予約済み
DWORD level, // 情報レベル
LPBYTE *bufptr, // 情報が格納されるバッファ
DWORD prefmaxlen, // バッファの最大サイズ
LPDWORD entriesread, // 格納されたエントリの数
LPDWORD totalentries, // 利用可能なエントリの総数
DWORD servertype, // サーバーのタイプ
LPCWSTR domain, // 列挙対象のドメイン
LPDWORD resume_handle // レジュームハンドル
);
*/
[DllImport("netapi32")]
public static extern int NetServerEnum (
[In] string servername, // 予約済み
[In] uint level, // 情報レベル
[Out] out IntPtr bufptr, // 情報が格納されるバッファ
[In] uint prefmaxlen, // バッファの最大サイズ
[Out] out uint entriesread, // 格納されたエントリの数
[Out] out uint totalentries, // 利用可能なエントリの総数
[In] uint servertype, // サーバーのタイプ
[In] string domain, // 列挙対象のドメイン
[In, Out] ref uint resume_handle // レジュームハンドル
);
// bufptr は、NetApiBufferFree(bufptr)で開放する必要がある。
/*
NET_API_STATUS NetApiBufferFree(
LPVOID Buffer // バッファ
);
*/
[DllImport("netapi32")]
public static extern int NetApiBufferFree(
[In] IntPtr lpBuffer);
#endregion
}
}
|
|
|
|
| WNet 用ライブラリ |
using System;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;
namespace Uchukamen
{
/// <summary>
/// WNet の概要の説明です。
/// </summary>
public class WNet
{
public WNet()
{
//
// TODO: コンストラクタ ロジックをここに追加してください。
//
}
#region 定数、構造体
public struct HostInfo
{
public string lpLocalName;
public string lpRemoteName;
public string lpComment;
public string lpProvider;
}
public enum Scope : uint
{
RESOURCE_CONNECTED = 0x00000001, // 現在接続されているすべてのリソース
RESOURCE_CONTEXT = 0x00000005, // 呼び出し側のネットワークコンテキスト内のリソース
RESOURCE_GLOBALNET = 0x00000002, // ネットワーク上のすべてのリソース
RESOURCE_REMEMBERED = 0x00000003 // 記憶されている( 永続的な)すべての接続
}
public enum Type : uint
{
RESOURCETYPE_ANY = 0x00000000, // すべてのリソース
RESOURCETYPE_DISK = 0x00000001, // すべてのディスクリソース
RESOURCETYPE_PRINT = 0x00000002 // すべての印刷リソース
}
public enum Usage : uint
{
RESOURCEUSAGE_CONNECTABLE = 0x00000001, // 接続可能なすべてのリソース
RESOURCEUSAGE_CONTAINER = 0x00000002, // すべてのコンテナリソース
RESOURCEUSAGE_ATTACHED = 0x00000010, // ユーザーが認証されていない場合、失敗
RESOURCEUSAGE_ALL = (RESOURCEUSAGE_CONNECTABLE | RESOURCEUSAGE_CONTAINER | RESOURCEUSAGE_ATTACHED)
}
public enum DisplayType : uint
{
RESOURCEDISPLAYTYPE_GENERIC = 0x00000000,
RESOURCEDISPLAYTYPE_DOMAIN = 0x00000001,
RESOURCEDISPLAYTYPE_SERVER = 0x00000002,
RESOURCEDISPLAYTYPE_SHARE = 0x00000003,
RESOURCEDISPLAYTYPE_FILE = 0x00000004,
RESOURCEDISPLAYTYPE_GROUP = 0x00000005,
RESOURCEDISPLAYTYPE_NETWORK = 0x00000006,
RESOURCEDISPLAYTYPE_ROOT = 0x00000007,
RESOURCEDISPLAYTYPE_SHAREADMIN = 0x00000008,
RESOURCEDISPLAYTYPE_DIRECTORY = 0x00000009,
RESOURCEDISPLAYTYPE_TREE = 0x0000000A,
RESOURCEDISPLAYTYPE_NDSCONTAINER = 0x0000000B
}
// エラー
private const uint NO_ERROR = 0;
private const uint ERROR_NOT_CONTAINER = 1207;
private const uint ERROR_INVALID_PARAMETER = 87;
private const uint ERROR_NO_NETWORK = 1222;
private const uint ERROR_EXTENDED_ERROR = 1208;
private const uint ERROR_NO_MORE_ITEMS = 259;
// 構造体
[StructLayout(LayoutKind.Sequential)]
public struct NETRESOURCE
{
public uint dwScope;
public uint dwType;
public uint dwDisplayType;
public uint dwUsage;
public string lpLocalName;
public string lpRemoteName;
public string lpComment;
public string lpProvider;
}
#endregion
#region プロトタイプ宣言
//DWORD WNetConnectionDialog(
// HWND hwnd, // ダイアログボックスを所有するウィンドウのハンドル
// DWORD dwType // 資源の種類
// );
[DllImport("Mpr.dll")]
public static extern uint WNetConnectionDialog(IntPtr hwnd, uint dwType);
// DWORD WNetGetLastError(
// LPDWORD lpError, // [out] エラーコード
// LPTSTR lpErrorBuf, // [out] エラー記述バッファ
// DWORD nErrorBufSize, // [in] 記述バッファのサイズ
// LPTSTR lpNameBuf, // [out] プロバイダ名を保持するバッファ
// DWORD nNameBufSize // [in] プロバイダ名バッファのサイズ
// );
[DllImport("Mpr.dll")]
public static extern uint WNetGetLastError(
out uint lpError,
StringBuilder lpErrorBuf,
uint nErrorBufSize,
StringBuilder lpNameBuf,
uint nNameBufSize);
//DWORD WNetOpenEnum(
// DWORD dwScope, // [in] 列挙のスコープ
// DWORD dwType, // [in] 列挙したいリソースのタイプ
// DWORD dwUsage, // [in] 列挙したいリソースの用途
// LPNETRESOURCE lpNetResource, // [in] リソースの構造体
// LPHANDLE lphEnum // [out] 列挙ハンドルのバッファ
// );
[DllImport("Mpr.dll")]
public static extern uint WNetOpenEnum(
[In] WNet.Scope dwScope,
[In] WNet.Type dwType,
[In] WNet.Usage dwUsage,
[In] IntPtr lpNetResource,
[Out] out IntPtr lphEnum);
//DWORD WNetEnumResource(
// HANDLE hEnum, // [in] 列挙のハンドル
// LPDWORD lpcCount, // [In, Out] 列挙したいエントリ
// LPVOID lpBuffer, // [out] バッファ
// LPDWORD lpBufferSize // [In, Out] バッファサイズ
// );
[DllImport("Mpr.dll")]
public static extern uint WNetEnumResource(
[In] IntPtr hEnum,
[In, Out] ref uint lpcCount,
[Out] NETRESOURCE[] lpBuffer,
[In, Out] ref uint lpBufferSize);
//DWORD WNetEnumResource(
// HANDLE hEnum, // [in] 列挙のハンドル
// LPDWORD lpcCount, // [In, Out] 列挙したいエントリ
// LPVOID lpBuffer, // [out] バッファ
// LPDWORD lpBufferSize // [In, Out] バッファサイズ
// );
[DllImport("Mpr.dll")]
public static extern uint WNetEnumResource(
[In] IntPtr hEnum,
[In, Out] ref uint lpcCount,
[Out] IntPtr lpBuffer,
[In, Out] ref uint lpBufferSize);
// DWORD WNetCloseEnum(
// HANDLE hEnum // 列挙のハンドル
// );
[DllImport("Mpr.dll")]
public static extern uint WNetCloseEnum(
[In] IntPtr hEnum);
#endregion
public HostInfo [] EnumServer()
{
Scope dwScope = Scope.RESOURCE_GLOBALNET;
Type dwType = Type.RESOURCETYPE_ANY;
Usage dwUsage = Usage.RESOURCEUSAGE_ALL;
NETRESOURCE nr = new NETRESOURCE();
nr.dwScope = (uint)Scope.RESOURCE_GLOBALNET;
nr.dwType = (uint)Type.RESOURCETYPE_ANY;
// nr.dwDisplayType = DisplayType.RESOURCEDISPLAYTYPE_DOMAIN;
nr.lpLocalName = null;
nr.dwUsage = (uint)Usage.RESOURCEUSAGE_ALL;
nr.lpRemoteName = "Mshome";
nr.lpProvider = "Microsoft Windows Network";
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(NETRESOURCE)));
Marshal.StructureToPtr(nr, ptr, true);
IntPtr hEnum = new IntPtr();
uint ret = WNetOpenEnum(dwScope, dwType, dwUsage, ptr, out hEnum);
Marshal.FreeHGlobal(ptr);
switch (ret)
{
case NO_ERROR:
break;
case ERROR_NOT_CONTAINER:
// lpNetResource パラメータがコンテナリソースを指していません。
throw(new Exception("lpNetResource パラメータがコンテナリソースを指していません。"));
case ERROR_INVALID_PARAMETER:
// dwScope パラメータまたは dwType パラメータの値が無効です。
// あるいは、パラメータの値の組み合わせが無効です。
throw(new Exception("dwScope パラメータまたは dwType パラメータの値が無効です。"));
case ERROR_NO_NETWORK:
// ネットワークが利用できません。
throw(new Exception("ネットワークが利用できません。"));
case ERROR_EXTENDED_ERROR:
{
// ネットワーク固有のエラーが発生しました。
uint lpError = 0;
StringBuilder lpErrorBuf = new StringBuilder(100);
StringBuilder lpNameBuf = new StringBuilder(100);
uint err = WNetGetLastError(
out lpError,
lpErrorBuf,
(uint)lpErrorBuf.Capacity,
lpNameBuf,
(uint)lpNameBuf.Capacity);
Debug.WriteLine(lpErrorBuf.ToString());
Debug.WriteLine(lpNameBuf.ToString());
throw(new Exception("ネットワーク固有のエラーが発生しました。"));
}
default:
break;
}
// -1 は、できるだけ多くの数を返す。
uint lpcCount = unchecked((uint)(-1));
IntPtr p = Marshal.AllocHGlobal(16*1024);
uint BufSize = 16 * 1024;
uint result = WNetEnumResource(hEnum, ref lpcCount, p, ref BufSize);
HostInfo [] info = null;
switch (result)
{
case NO_ERROR:
{
info = new HostInfo[lpcCount];
for(int i = 0; i < (int)lpcCount; i++)
{
uint pt = (uint)p + (uint)(i * Marshal.SizeOf(new NETRESOURCE()));
NETRESOURCE ppBuf = (NETRESOURCE)Marshal.PtrToStructure((IntPtr)pt, typeof(NETRESOURCE));
info[i].lpRemoteName = ppBuf.lpRemoteName;
info[i].lpComment = ppBuf.lpComment;
info[i].lpLocalName = ppBuf.lpLocalName;
info[i].lpProvider = ppBuf.lpProvider;
Debug.WriteLine("lpRemoteName:" + ppBuf.lpRemoteName);
Debug.WriteLine("lpComment:" + ppBuf.lpComment);
Debug.WriteLine("lpLocalName:" + ppBuf.lpLocalName);
Debug.WriteLine("lpProvider:" + ppBuf.lpProvider);
}
}
break;
case ERROR_NO_MORE_ITEMS:
break;
}
Marshal.FreeHGlobal(p);
WNetCloseEnum(hEnum);
return info;
}
}
}
|
|
|