Подскажите пожалуйста в чем может быть проблема при обращении к NetServerEnum.
Код честно скопирован множество раз с разных сайтов и из msdn.
Как только доходит до строки обращения к внешней функции (выделено красным цветом) возникает ошибка:
An unhandled exception of type 'System.NullReferenceException' occurred in Test.exe
Additional information: Object reference not set to an instance of an object.
По честному отсмотрел кучу постов о том, как получить список машин в домене, но такой проблемы ни у кого не возникало.
Код прилагается, спасибо за помощь
Option Explicit Off
Imports System.Runtime.InteropServices
Public Class Form1
Inherits System.Windows.Forms.Form
Const ERROR_SUCCESS = 0
Const ERROR_MORE_DATA = 234
Const SV_TYPE_WORKSTATION = &H8
Const SIZE_SI_101 = 24
Public Structure SERVER_INFO_100
Public sv100_platform_id As Long
Public sv100_name As Long
End Structure
Public Enum SV_101_TYPES
SV_TYPE_WORKSTATION = &H1
SV_TYPE_SERVER = &H2
SV_TYPE_ALL = &H0
End Enum
Public Structure SERVER_INFO_101
Public dwPlatformId As Long
Public lpszServerName As String
Public dwVersionMajor As Long
Public dwVersionMinor As Long
Public dwType As Long
Public lpszComment As Long
End Structure
Declare Auto Function NetServerEnum Lib "netapi32.dll" (ByVal servername As String, _
ByVal level As Long, _
ByRef buffer As Long, _
ByVal prefmaxlen As Long, _
ByRef entriesread As Long, _
ByRef totalentries As Long, _
ByVal ByValservertype As System.Runtime.InteropServices.UnmanagedType, _
ByVal domain As String, _
ByRef resumehandle As Long) As Long
Declare Auto Function NetApiBufferFree Lib "netapi32.dll" ( _
ByVal BufPtr As Long) As Long
Declare Sub RtlMoveMemory Lib "KERNEL32" ( _
ByRef hpvDest As SERVER_INFO_101, _
ByVal hpvSource As Long, _
ByVal cbCopy As Long)
Declare Function lstrcpyW Lib "KERNEL32" ( _
ByVal lpszDest As String, _
ByVal lpszSrc As Long) As Long
Private Function PointerToString(ByVal lpszString As Long) As String
Dim intPos As Integer
Dim lpszStr2 As String
Dim nRes As Long
Dim lpszStr1 As New String("*"c, 1000)
nRes = lstrcpyW(lpszStr1, lpszString)
lpszStr2 = lpszStr1
intPos = InStr(lpszStr2, Chr(0)) — 1
PointerToString = Microsoft.VisualBasic.Left(lpszStr2, intPos)
End Function
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim pszTemp As String
Dim pszServer As String
Dim pszDomain As String
Dim nLevel As Long, i As Long, BufPtr As Long, TempBufPtr As Long
Dim nPrefMaxLen As Long, nEntriesRead As Long, nTotalEntries As Long
Dim nServerType As Long, nResumeHandle As Long, nRes As Long
Dim ServerInfo As SERVER_INFO_101
Dim sWSName As String
pszServer = Nothing
pszDomain = Nothing
nLevel = 101
BufPtr = 0
nPrefMaxLen = -1
nEntriesRead = 0
nTotalEntries = 0
nServerType = SV_TYPE_WORKSTATION
nResumeHandle = IntPtr.Zero.ToInt32
Do
nRes = NetServerEnum("", _
nLevel, _
BufPtr, _
nPrefMaxLen, _
nEntriesRead, _
nTotalEntries, _
SV_101_TYPES.SV_TYPE_SERVER, _
"", _
nResumeHandle)
If ((nRes = ERROR_SUCCESS) Or (nRes = ERROR_MORE_DATA)) And _
(nEntriesRead > 0) Then
TempBufPtr = BufPtr
For i = 1 To nEntriesRead
RtlMoveMemory(ServerInfo, TempBufPtr, SIZE_SI_101)
sWSName = PointerToString(ServerInfo.lpszServerName)
TempBufPtr = TempBufPtr + SIZE_SI_101
Next i
Else
MsgBox("NetServerEnum failed: " & nRes)
End If
NetApiBufferFree(BufPtr)
Loop While nEntriesRead < nTotalEntries
End Sub
End Class
S>Подскажите пожалуйста в чем может быть проблема при обращении к NetServerEnum.
Разбираться лениво, но вот рабочий кусок кода
отсюдаАвтор(ы): Агуров П.В.
При написании программ особенно важно не тратить время на поиск стандартных решений, а сосредоточиться на решении конкретной задачи, используя готовый эффективный код, разработанный и проверенный коллегой-программистом. В этой книге собраны лучшие рецепты и решения, которые пригодятся вам при разработке программ любой сложности и помогут создать действительно качественный и быстрый код. Вам не потребуется читать множество документации — ведь можно просто взять готовый пример. Книга будет полезна как разработчикам программ на С#, так и тем, кто переходит на язык С# с других языков программирования.
На компакт-диске размещены все исходные коды, приведенные в книге.
:
using System;
using System.Collections;
using System.Runtime.InteropServices;
namespace ServerEnum
{
internal class Class1
{
[DllImport("netapi32.dll", EntryPoint="NetServerEnum")]
public static extern NERR NetServerEnum (
[MarshalAs(UnmanagedType.LPWStr)] string ServerName,
int Level, out IntPtr BufPtr, int PrefMaxLen,
ref int EntriesRead, ref int TotalEntries,
SV_101_TYPES ServerType,
[MarshalAs(UnmanagedType.LPWStr)] string Domain,
int ResumeHandle);
[DllImport("netapi32.dll", EntryPoint="NetApiBufferFree")]
public static extern NERR NetApiBufferFree (IntPtr Buffer);
//
// типы серверов
//
[Flags]
public enum SV_101_TYPES : uint
{
SV_TYPE_WORKSTATION = 0x00000001,
SV_TYPE_SERVER = 0x00000002,
SV_TYPE_SQLSERVER = 0x00000004,
SV_TYPE_DOMAIN_CTRL = 0x00000008,
SV_TYPE_DOMAIN_BAKCTRL = 0x00000010,
SV_TYPE_TIME_SOURCE = 0x00000020,
SV_TYPE_AFP = 0x00000040,
SV_TYPE_NOVELL = 0x00000080,
SV_TYPE_DOMAIN_MEMBER = 0x00000100,
SV_TYPE_PRINTQ_SERVER = 0x00000200,
SV_TYPE_DIALIN_SERVER = 0x00000400,
SV_TYPE_XENIX_SERVER = 0x00000800,
SV_TYPE_SERVER_UNIX = SV_TYPE_XENIX_SERVER,
SV_TYPE_NT = 0x00001000,
SV_TYPE_WFW = 0x00002000,
SV_TYPE_SERVER_MFPN = 0x00004000,
SV_TYPE_SERVER_NT = 0x00008000,
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,
SV_TYPE_DFS = 0x00800000,
SV_TYPE_CLUSTER_NT = 0x01000000,
SV_TYPE_TERMINALSERVER = 0x02000000,
SV_TYPE_CLUSTER_VS_NT = 0x04000000,
SV_TYPE_DCE = 0x10000000,
SV_TYPE_ALTERNATE_XPORT = 0x20000000,
SV_TYPE_LOCAL_LIST_ONLY = 0x40000000,
SV_TYPE_DOMAIN_ENUM = 0x80000000,
SV_TYPE_ALL = 0xFFFFFFFF,
}
[StructLayout(LayoutKind.Sequential)]
public struct SERVER_INFO_101
{
[MarshalAs(UnmanagedType.U4)] public uint sv101_platform_id;
[MarshalAs(UnmanagedType.LPWStr)] public string sv101_name;
[MarshalAs(UnmanagedType.U4)] public uint sv101_version_major;
[MarshalAs(UnmanagedType.U4)] public uint sv101_version_minor;
[MarshalAs(UnmanagedType.U4)] public uint sv101_type;
[MarshalAs(UnmanagedType.LPWStr)] public string sv101_comment;
}
//
// оперционная система
//
public enum PLATFORM_ID : uint
{
PLATFORM_ID_DOS = 300,
PLATFORM_ID_OS2 = 400,
PLATFORM_ID_NT = 500,
PLATFORM_ID_OSF = 600,
PLATFORM_ID_VMS = 700,
}
//
// список ошибок, возвращаемых NetServerEnum
//
public enum NERR
{
NERR_Success = 0, // Успех
ERROR_ACCESS_DENIED = 5,
ERROR_NOT_ENOUGH_MEMORY = 8,
ERROR_BAD_NETPATH = 53,
ERROR_NETWORK_BUSY = 54,
ERROR_INVALID_PARAMETER = 87,
ERROR_INVALID_LEVEL = 124,
ERROR_MORE_DATA = 234,
ERROR_EXTENDED_ERROR = 1208,
ERROR_NO_NETWORK = 1222,
ERROR_INVALID_HANDLE_STATE = 1609,
ERROR_NO_BROWSER_SERVERS_FOUND = 6118,
}
public static ArrayList GetServerList(SV_101_TYPES type)
{
SERVER_INFO_101 si;
IntPtr pInfo = IntPtr.Zero;
int etriesread = 0;
int totalentries = 0;
ArrayList srvs = new ArrayList();
try
{
NERR err = NetServerEnum(null, 101, out pInfo, -1,
ref etriesread, ref totalentries, type, null, 0);
if ((err == NERR.NERR_Success ||
err == NERR.ERROR_MORE_DATA) &&
pInfo != IntPtr.Zero)
{
int ptr = pInfo.ToInt32();
for (int i = 0; i < etriesread; i++)
{
si = (SERVER_INFO_101) Marshal.PtrToStructure(
new IntPtr(ptr), typeof (SERVER_INFO_101));
srvs.Add(si.sv101_name); // добавляем имя
// сервера в список
ptr += Marshal.SizeOf(si);
}
}
}
catch (Exception)
{
}
finally
{ // освобождаем выделенную память
if (pInfo != IntPtr.Zero)
{
NetApiBufferFree(pInfo);
}
}
return (srvs);
}
[STAThread]
static void Main()
{
Console.WriteLine("{0} WORKSTATION", new string('=', 10));
ArrayList list =
GetServerList(SV_101_TYPES.SV_TYPE_WORKSTATION);
foreach (string name in list)
{
Console.WriteLine(name);
}
Console.WriteLine("{0} UNIX", new string('=', 10));
list = GetServerList(SV_101_TYPES.SV_TYPE_SERVER_UNIX);
foreach (string name in list)
{
Console.WriteLine(name);
}
}
}
}