C# NetFileEnum返回错误\u更多\u数据
尝试从文件服务器检索打开的文件的大列表会返回错误\u MORE\u数据值(错误号234),但在仅处理一小部分文件(似乎返回大约84个条目)时效果良好。此代码基于以下示例: 我发现的大多数示例都没有真正涉及如何处理大量文件。据我所知,这与简历手柄有关,但我不确定需要做什么。我需要在循环中调用这个方法吗 代码如下:C# NetFileEnum返回错误\u更多\u数据,c#,pinvoke,netapi32,C#,Pinvoke,Netapi32,尝试从文件服务器检索打开的文件的大列表会返回错误\u MORE\u数据值(错误号234),但在仅处理一小部分文件(似乎返回大约84个条目)时效果良好。此代码基于以下示例: 我发现的大多数示例都没有真正涉及如何处理大量文件。据我所知,这与简历手柄有关,但我不确定需要做什么。我需要在循环中调用这个方法吗 代码如下: using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Inter
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace OpenFiles
{
class Program
{
public static string computername = "computername";
static void Main(string[] args)
{
List<string> theFileList = NativeMethods.GetFiles(computername);
foreach (string file in theFileList)
{
Console.WriteLine(file);
}
}
}
static class NativeMethods
{
[DllImport("netapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
static extern int NetFileEnum(
string servername,
string basepath,
string username,
int level,
ref IntPtr bufptr,
int prefmaxlen,
out int entriesread,
out int totalentries,
IntPtr resume_handle
);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
struct FILE_INFO_3
{
public int fi3_id;
public int fi3_permission;
public int fi3_num_locks;
[MarshalAs(UnmanagedType.LPWStr)]
public string fi3_pathname;
[MarshalAs(UnmanagedType.LPWStr)]
public string fi3_username;
}
[DllImport("Netapi32.dll", SetLastError = true)]
static extern int NetApiBufferFree(IntPtr Buffer);
public static List<string> GetFiles(string Computername)
{
const int MAX_PREFERRED_LENGTH = -1;
int dwReadEntries;
int dwTotalEntries;
IntPtr pBuffer = IntPtr.Zero;
FILE_INFO_3 pCurrent = new FILE_INFO_3();
List<string> fileList = new List<string>();
int dwStatus = NetFileEnum(Computername, null, null, 3, ref pBuffer, MAX_PREFERRED_LENGTH, out dwReadEntries, out dwTotalEntries, IntPtr.Zero);
if (dwStatus == 0)
{
for (int dwIndex = 0; dwIndex < dwReadEntries; dwIndex++)
{
IntPtr iPtr = new IntPtr(pBuffer.ToInt32() + (dwIndex * Marshal.SizeOf(pCurrent)));
pCurrent = (FILE_INFO_3)Marshal.PtrToStructure(iPtr, typeof(FILE_INFO_3));
string fileInfo = pCurrent.fi3_id + "," +
pCurrent.fi3_num_locks + "," +
pCurrent.fi3_pathname + "," +
pCurrent.fi3_permission + "," +
pCurrent.fi3_username;
fileList.Add(fileInfo);
}
NetApiBufferFree(pBuffer);
}
else
{
Console.WriteLine("error: " + dwStatus);
}
return fileList;
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Runtime.InteropServices;
使用系统文本;
使用System.Threading.Tasks;
命名空间开放文件
{
班级计划
{
公共静态字符串computername=“computername”;
静态void Main(字符串[]参数)
{
列出filelist=NativeMethods.GetFiles(computername);
foreach(文件列表中的字符串文件)
{
Console.WriteLine(文件);
}
}
}
静态类NativeMethods
{
[DllImport(“netapi32.dll”,SetLastError=true,CharSet=CharSet.Unicode)]
静态外部内部NetFileEnum(
字符串servername,
字符串基路径,
字符串用户名,
整数级,
参考IntPtr bufptr,
int prefmaxlen,
在我们的头上,
输入整数,
IntPtr resume_句柄
);
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Auto)]
结构文件信息3
{
公共int fi3_id;
公共int fi3_许可;
公共int fi3_num_锁;
[Marshallas(UnmanagedType.LPWStr)]
公共字符串fi3_路径名;
[Marshallas(UnmanagedType.LPWStr)]
公共字符串fi3_用户名;
}
[DllImport(“Netapi32.dll”,SetLastError=true)]
静态外部int NetApiBufferFree(IntPtr缓冲区);
公共静态列表GetFiles(字符串Computername)
{
const int MAX_PREFERRED_LENGTH=-1;
int-dwReadEntries;
int dwTotalEntries;
IntPtr pBuffer=IntPtr.Zero;
FILE_INFO_3 pCurrent=新文件_INFO_3();
List fileList=新列表();
int dwStatus=NetFileEnum(Computername,null,null,3,ref pBuffer,MAX_PREFERRED_LENGTH,out dwReadEntries,out dwTotalEntries,IntPtr.Zero);
如果(dwStatus==0)
{
对于(int-dwIndex=0;dwIndex
根据我有限的经验,大量结果可能大于最大缓冲区。在这种情况下,会给出更多的数据响应,并指示我们使用提供的恢复句柄再次调用。在您的示例中,恢复句柄不会更改,因为DllImport签名没有将其定义为out参数。使用第一次调用的resume句柄结果(传入零表示第一次调用)可以接收下一批。循环,直到收到成功响应或其他错误
请确保修复定义NetFileEnum签名的问题。
恢复句柄没有用out定义,因此不能由调用的函数更改
请尝试以下DLL导入签名:
[DllImport("netapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
static extern int NetFileEnum(
string servername,
string basepath,
string username,
int level,
ref IntPtr bufptr,
int prefmaxlen,
out int entriesread,
out int totalentries,
out IntPtr resume_handle
);
当收到更多数据响应时,您应该能够使用生成的恢复句柄多次重新调用NetFileEnum。我的理解是,这应该是不可能的,因为您正在传递MAX\u PREFERRED\u LENGTH
。