繁体   English   中英

NetFileEnum返回ERROR_MORE_DATA

[英]NetFileEnum returns ERROR_MORE_DATA

尝试从文件服务器中检索打开的文件的较大列表将返回ERROR_MORE_DATA值(错误号234),但在仅处理少量文件列表时就可以正常工作(似乎可以返回约84个条目)。 此代码基于以下示例: http : //pinvoke.net/default.aspx/netapi32/NetFileEnum.html

我发现的大多数示例并没有真正涉及如何处理大量文件。 据我了解,这与resume_handle有关,但是我不确定需要做什么。 我是否需要以某种方式在循环中调用此方法?

代码如下:

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;
        }
    }
}

以我有限的经验,非常多的结果可能会比最大缓冲区大。 在这种情况下,会给出更多的数据响应,并指示我们使用提供的恢复句柄再次调用。 在您的示例中,恢复句柄将不会更改,因为DllImport签名未将其定义为out参数。 使用第一个调用的恢复句柄结果(传递零表示第一个调用)可以接收下一批。 循环播放,直到收到成功响应或其他错误。

确保解决了定义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及其结果的恢复句柄。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM