使用Windows API时出现fatalExecutionEngineError

时间:2012-07-09 15:55:30

标签: .net winforms netapi32

我正在尝试使用名为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对象是什么)有点了解,并且指针可能已经溢出到结果的一部分,它不应该?我仍然不明白为什么这个错误只会在某些时候发生。

我如何理解/避免此错误?

1 个答案:

答案 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个字节 - 根据结构后面的内容可能会或可能不会起作用。