本文介绍了PInvoke NetLocalGroupGetMembers遇到FatalExecutionEngineError的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我需要在C#中使用win32 NetLocalGroupGetMembers
.我找到并测试了三种解决方案.所有这三个都失败,并带有FatalExecutionEngineError
.该框架是.net 4.0
I need to use win32 NetLocalGroupGetMembers
in C#. I found and tested three solutions. All three fail with an FatalExecutionEngineError
. The framework is .net 4.0
这是一个完整的例子:
对api的引用:
static class NetworkAPI
{
[DllImport("Netapi32.dll")]
public extern static int NetLocalGroupGetMembers([MarshalAs(UnmanagedType.LPWStr)] string servername, [MarshalAs(UnmanagedType.LPWStr)] string localgroupname, int level, out IntPtr bufptr, int prefmaxlen, out int entriesread, out int totalentries, out int resumehandle);
[DllImport("Netapi32.dll")]
public extern static int NetApiBufferFree(IntPtr Buffer);
// LOCALGROUP_MEMBERS_INFO_1 - Structure for holding members details
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct LOCALGROUP_MEMBERS_INFO_1
{
public int lgrmi1_sid;
public int lgrmi1_sidusage;
public string lgrmi1_name;
}
}
调用函数:
static void Main(string[] args)
{
int EntriesRead;
int TotalEntries;
int Resume;
IntPtr bufPtr;
string groupName = "Administrators";
NetworkAPI.NetLocalGroupGetMembers(null, groupName, 1, out bufPtr, -1, out EntriesRead, out TotalEntries, out Resume);
if (EntriesRead > 0)
{
NetworkAPI.LOCALGROUP_MEMBERS_INFO_1[] Members = new NetworkAPI.LOCALGROUP_MEMBERS_INFO_1[EntriesRead];
IntPtr iter = bufPtr;
// EntriesRead has the correct quantity of members of the group, so the group is found
for (int i = 0; i < EntriesRead; i++)
{
// --------------------------------------------------
// ==> here the FatalExecutionEngineError happens:
Members[i] = (NetworkAPI.LOCALGROUP_MEMBERS_INFO_1)Marshal.PtrToStructure(iter, typeof(NetworkAPI.LOCALGROUP_MEMBERS_INFO_1));
//
// --------------------------------------------------
iter = (IntPtr)((int)iter + Marshal.SizeOf(typeof(NetworkAPI.LOCALGROUP_MEMBERS_INFO_1)));
Console.WriteLine(Members[i].lgrmi1_name);
}
NetworkAPI.NetApiBufferFree(bufPtr);
}
}
推荐答案
我看到以下错误:
- 简历句柄是一个指针.使用
ref IntPtr resumehandle
作为该参数,并在第一次调用时传递IntPtr.Zero
.或者,如果您不需要使用简历句柄,则将参数声明为IntPtr resumehandle
并传递IntPtr.Zero
.有关完整的详细信息,请查阅MSDN上的功能文档. - 该结构的
lgrmi1_sid
成员是一个指针.这样声明:public IntPtr lgrmi1_sid
. - 将
IntPtr
投射到int
将导致指针在64位上被截断.可以直接在IntPtr
上使用算术,或者对转换为long
的旧C#版本使用算术.前者更好,例如:iter += Marshal.SizeOf(typeof(NetworkAPI.LOCALGROUP_MEMBERS_INFO_1));
. - 您不检查返回值是否有错误.
- The resume handle is a pointer. Use
ref IntPtr resumehandle
for that parameter, and passIntPtr.Zero
on the first call. Or if you don't need to use a resume handle declare the parameter asIntPtr resumehandle
and passIntPtr.Zero
. Consult the function documentation on MSDN for the full details. - The
lgrmi1_sid
member of the struct is a pointer. Declare it as such:public IntPtr lgrmi1_sid
. - Casting an
IntPtr
to anint
will lead to pointer truncation on 64 bit. Either use arithmetic directly on theIntPtr
, or for older C# versions cast tolong
. The former is better, like so:iter += Marshal.SizeOf(typeof(NetworkAPI.LOCALGROUP_MEMBERS_INFO_1));
. - You do not check the return value for errors.
修复这些错误,您的程序将正确运行.
Fix those errors and your program will run correctly.
这篇关于PInvoke NetLocalGroupGetMembers遇到FatalExecutionEngineError的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!