我正在尝试使用名为netapi32.dll
的Windows API .dll来操作DFS共享。我们在Windows Server 2008 R2上使用DFS,而我使用的是.NET 4.0。我之前从未在.NET中使用过这样的东西,但我无法理解失败的原因。
我正在使用DllImport
来调用NetDfsGetInfo来测试获取有关DFS共享的信息。我必须为我希望从函数中接收的信息级别创建结构。
public struct DFS_INFO_3
{
[MarshalAs(UnmanagedType.LPWStr)]
public string EntryPath;
[MarshalAs(UnmanagedType.LPWStr)]
public string Comment;
public UInt32 State;
public UInt32 NumberOfStorages;
public IntPtr Storage;
}
public struct DFS_STORAGE_INFO
{
public ulong State;
[MarshalAs(UnmanagedType.LPWStr)]
public string ServerName;
[MarshalAs(UnmanagedType.LPWStr)]
public string ShareName;
}
我使用以下代码来获取和读取结果:
[DllImport("netapi32", CallingConvention = CallingConvention.Winapi)]
public static extern int NetDfsGetInfo(
[MarshalAs(UnmanagedType.LPWStr)] string DfsEntryPath,
[MarshalAs(UnmanagedType.LPWStr)]string ServerName,
[MarshalAs(UnmanagedType.LPWStr)]string ShareName,
int Level,
out IntPtr Buffer);
public void GetInfo() {
IntPtr buffer;
string dfsPath = "\\\\server\\share";
int result = NetDfsGetInfo(EntryPath, null, null, 3, out buffer);
if (result == 0) { //0 is Success
DFS_INFO_3 info = (DFS_INFO_3)Marshal.PtrToStructure(buffer, typeof(DFS_INFO_3));
DFS_STORAGE_INFO storage = (DFS_STORAGE_INFO)Marshal.PtrToStructure(info.Storage, typeof(DFS_STORAGE_INFO)); //Error
Console.WriteLine("{0}, {1}, {2} ", storage.ServerName, storage.ShareName, storage.State);
}
}
一切顺利,直到它读到storage
行。
我有时会收到错误消息:
运行时遇到了致命错误。错误的地址位于0x626ac91c,位于线程0x1d44上。错误代码是0xc0000005。此错误可能是CLR中的错误,也可能是用户代码的不安全或不可验证部分中的错误。此错误的常见来源包括COM-interop或PInvoke的用户封送错误,这可能会破坏堆栈。
错误类型是fatalExecutionEngineError,这不是.NET异常,所以我无法理解它。它不会每次都发生,但我会说大约有50%的时间我得到这个错误。查看Windows error codes,我发现5是“拒绝访问”。仅仅是介绍级别的Comp Sci精通,我对指针(这是IntPtr
对象是什么)有点了解,并且指针可能已经溢出到结果的一部分,它不应该?我仍然不明白为什么这个错误只会在某些时候发生。
我如何理解/避免此错误?
答案 0 :(得分:2)
您对DFS_STORAGE_INFO
的定义不正确。在.NET中,long/ulong
是64位,而在非托管Win32中,它只有32位(与int / uint相同)
public struct DFS_STORAGE_INFO
{
public UInt32 State;
[MarshalAs(UnmanagedType.LPWStr)]
public string ServerName;
[MarshalAs(UnmanagedType.LPWStr)]
public string ShareName;
}
当您整理DFS_STORAGE_INFO
时,您将读取结构末尾4个字节 - 根据结构后面的内容可能会或可能不会起作用。