fatalExecutionEngineError при использовании Windows API
Я пытаюсь использовать Windows API .dll под названием netapi32.dll
манипулировать акциями DFS. Мы используем DFS в Windows Server 2008 R2, а я использую.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-взаимодействия или PInvoke, которые могут повредить стек.
Тип ошибки - fatalExecutionEngineError, который не является исключением.NET, поэтому я не могу его перехватить. Это происходит не каждый раз, но я бы сказал, что в 50% случаев я получаю эту ошибку. Просматривая коды ошибок Windows, я вижу, что 5 - "Отказано в доступе". Будучи только начинающим специалистом по Comp Sci, я немного разбираюсь в указателях (что IntPtr
объект есть), и что указатель, возможно, перетек в часть результата, который он не должен был? Я до сих пор не понимаю, почему эта ошибка возникает только иногда.
Как я понимаю / избежать этой ошибки?
1 ответ
Ваше определение 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 байта после конца структуры - что может работать или не работать в зависимости от того, что находится после структуры.