问题  返回数据问题

Nohairmonk

新成员
已加入
2020年11月28日
留言内容
1
编程经验
Beginner
你好,
我正在尝试使用NtfsUsnJournal对文件夹和文件进行计数,我已经修改了代码,但是关于返回代码的问题。我想返回folderCount的值,该怎么做?
C#:
public UsnJournalReturnCode
            GetNtfsVolumeFolders(out List<Win32Api.UsnEntry> folders)
        {
            DateTime startTime = DateTime.Now;
            folders = new List<Win32Api.UsnEntry>();
            UsnJournalReturnCode usnRtnCode = UsnJournalReturnCode.VOLUME_NOT_NTFS;
           Int32 FoldersCount = 0;
            if (bNtfsVolume)
            {
              
                if (_usnJournalRootHandle.ToInt32() != Win32Api.INVALID_HANDLE_VALUE)
                {
                    usnRtnCode = UsnJournalReturnCode.USN_JOURNAL_SUCCESS;

                    Win32Api.USN_JOURNAL_DATA usnState = new Win32Api.USN_JOURNAL_DATA();
                    usnRtnCode = QueryUsnJournal(ref usnState);

                    if (usnRtnCode == UsnJournalReturnCode.USN_JOURNAL_SUCCESS)
                    {
                        //
                        // set up MFT_ENUM_DATA structure
                        //
                        Win32Api.MFT_ENUM_DATA med;
                        med.StartFileReferenceNumber = 0;
                        med.LowUsn = 0;
                        med.HighUsn = usnState.NextUsn;
                        Int32 sizeMftEnumData = Marshal.SizeOf(med);
                        IntPtr medBuffer = Marshal.AllocHGlobal(sizeMftEnumData);
                        Win32Api.ZeroMemory(medBuffer, sizeMftEnumData);
                        Marshal.StructureToPtr(med, medBuffer, true);

                        //
                        // set up the data buffer which receives the USN_RECORD data
                        //
                        int pDataSize = sizeof(UInt64) + 10000;
                        IntPtr pData = Marshal.AllocHGlobal(pDataSize);
                        Win32Api.ZeroMemory(pData, pDataSize);
                        uint outBytesReturned = 0;
                        Win32Api.UsnEntry usnEntry = null;

                        //
                        // Gather up volume's directories
                        //
                        while (false != Win32Api.DeviceIoControl(
                            _usnJournalRootHandle,
                            Win32Api.FSCTL_ENUM_USN_DATA,
                            medBuffer,
                            sizeMftEnumData,
                            pData,
                            pDataSize,
                            out outBytesReturned,
                            IntPtr.Zero))
                        {
                            IntPtr pUsnRecord = new IntPtr(pData.ToInt32() + sizeof(Int64));
                            while (outBytesReturned > 60)
                            {
                                usnEntry = new Win32Api.UsnEntry(pUsnRecord);
                                //
                                // check for directory entries
                                //
                                if (usnEntry.IsFolder)
                                {
                                    folders.Add(usnEntry);
                                    FoldersCount += 1;
                                }
                                pUsnRecord = new IntPtr(pUsnRecord.ToInt32() + usnEntry.RecordLength);
                                outBytesReturned -= usnEntry.RecordLength;
                            }
                            Marshal.WriteInt64(medBuffer, Marshal.ReadInt64(pData, 0));
                        }

                        Marshal.FreeHGlobal(pData);
                        usnRtnCode = ConvertWin32ErrorToUsnError((Win32Api.GetLastErrorEnum)Marshal.GetLastWin32Error());
                        if (usnRtnCode == UsnJournalReturnCode.ERROR_HANDLE_EOF)
                        {
                            usnRtnCode = UsnJournalReturnCode.USN_JOURNAL_SUCCESS;
                        }
                    }
                }
                else
                {
                    usnRtnCode = UsnJournalReturnCode.INVALID_HANDLE_VALUE;
                }
            }
            folders.Sort();
            System.Windows.MessageBox.Show(Convert.ToString(FoldersCount));
            //return FoldersCount;
            return usnRtnCode;
        }

附件为完整代码。
 

附件

  • NtfsUsnJournal.zip
    7.2 KB · Views: 2
由主持人最后编辑:

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,523
地点
悉尼,澳大利亚
编程经验
10+
请不要在代码中输入您的问题。该代码应为代码。代码中的注释应该是关于代码的注释。在帖子中提问。那就是帖子的目的。我们不必滚动浏览所有代码即可找到问题。
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,529
地点
弗吉尼亚州切萨皮克
编程经验
10+
我怀疑问题的部分原因在于,OP似乎已经将某些C样式的代码音译为C#代码,但是要使从C样式的过程向C#面向对象的飞跃有些困难。
 

暂存

新成员
已加入
2020年11月30日
留言内容
3
编程经验
5-10
如果你需要退货"usnRtnCode" and this "FoldersCount",只需将此函数放在同一个类中

C#:
private int _FC;
public static int _FoldersCount { get { return _FC;} set{ _FC = value;}}

然后及时返回您的值,将其放入代码中

C#:
_FoldersCount = FoldersCount;

这个变量"_FoldersCount"它看起来像一个静态成员,您可以在另一个类中看到,使用函数后,您可以使用

C#:
var Result = UsnJournalReturnCode._FoldersCount;
//or anything u want
_ =  UsnJournalReturnCode._FoldersCount;
 

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,523
地点
悉尼,澳大利亚
编程经验
10+
if u need return "usnRtnCode" and this "FoldersCount",只需将此函数放在同一个类中

C#:
private int _FC;
public static int _FoldersCount { get { return _FC;} set{ _FC = value;}}

然后及时返回您的值,将其放入代码中

C#:
_FoldersCount = FoldersCount;

这个变量"_FoldersCount"它看起来像一个静态成员,您可以在另一个类中看到,使用函数后,您可以使用

C#:
var Result = UsnJournalReturnCode._FoldersCount;
//or anything u want
_ =  UsnJournalReturnCode._FoldersCount;
The field would need to be static as well or the property couldn't access it. That said, if you were going to go that way, the field would be pointless and you should just use an auto-property.
 

暂存

新成员
已加入
2020年11月30日
留言内容
3
编程经验
5-10
你可以试试看。

创建一个结构

C#:
public struct CodeResult { public UsnJournalReturnCode JornalResult; public int FoldersCount; }

并定义值类型返回此结构,在示例中是"CodeResult".

在您的代码中,您会生成此结构的新实例并返回其。
C#:
代码结果 Result = new CodeResult
{
JornalResult = usnRtnCode,
FoldersCount = FoldersCount
};
return Result;
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,529
地点
弗吉尼亚州切萨皮克
编程经验
10+
ValueTuple会更加方便:
C#:
public (UsnJournalReturnCode code, int folderCount)
       GetNtfsVolumeFolders(out List<Win32Api.UsnEntry> folders)
{
    DateTime startTime = DateTime.Now;
    folders = new List<Win32Api.UsnEntry>();
    UsnJournalReturnCode usnRtnCode = UsnJournalReturnCode.VOLUME_NOT_NTFS;
    Int32 FoldersCount = 0;
    if (bNtfsVolume)
    {
        if (_usnJournalRootHandle.ToInt32() != Win32Api.INVALID_HANDLE_VALUE)
        {
            usnRtnCode = UsnJournalReturnCode.USN_JOURNAL_SUCCESS;

            Win32Api.USN_JOURNAL_DATA usnState = new Win32Api.USN_JOURNAL_DATA();
            usnRtnCode = QueryUsnJournal(ref usnState);

            if (usnRtnCode == UsnJournalReturnCode.USN_JOURNAL_SUCCESS)
            {
                //
                // set up MFT_ENUM_DATA structure
                //
                Win32Api.MFT_ENUM_DATA med;
                med.StartFileReferenceNumber = 0;
                med.LowUsn = 0;
                med.HighUsn = usnState.NextUsn;
                Int32 sizeMftEnumData = Marshal.SizeOf(med);
                IntPtr medBuffer = Marshal.AllocHGlobal(sizeMftEnumData);
                Win32Api.ZeroMemory(medBuffer, sizeMftEnumData);
                Marshal.StructureToPtr(med, medBuffer, true);

                //
                // set up the data buffer which receives the USN_RECORD data
                //
                int pDataSize = sizeof(UInt64) + 10000;
                IntPtr pData = Marshal.AllocHGlobal(pDataSize);
                Win32Api.ZeroMemory(pData, pDataSize);
                uint outBytesReturned = 0;
                Win32Api.UsnEntry usnEntry = null;

                //
                // Gather up volume's directories
                //
                while (false != Win32Api.DeviceIoControl(
                    _usnJournalRootHandle,
                    Win32Api.FSCTL_ENUM_USN_DATA,
                    medBuffer,
                    sizeMftEnumData,
                    pData,
                    pDataSize,
                    out outBytesReturned,
                    IntPtr.Zero))
                {
                    IntPtr pUsnRecord = new IntPtr(pData.ToInt32() + sizeof(Int64));
                    while (outBytesReturned > 60)
                    {
                        usnEntry = new Win32Api.UsnEntry(pUsnRecord);
                        //
                        // check for directory entries
                        //
                        if (usnEntry.IsFolder)
                        {
                            folders.Add(usnEntry);
                            FoldersCount += 1;
                        }
                        pUsnRecord = new IntPtr(pUsnRecord.ToInt32() + usnEntry.RecordLength);
                        outBytesReturned -= usnEntry.RecordLength;
                    }
                    Marshal.WriteInt64(medBuffer, Marshal.ReadInt64(pData, 0));
                }

                Marshal.FreeHGlobal(pData);
                usnRtnCode = ConvertWin32ErrorToUsnError((Win32Api.GetLastErrorEnum)Marshal.GetLastWin32Error());
                if (usnRtnCode == UsnJournalReturnCode.ERROR_HANDLE_EOF)
                {
                    usnRtnCode = UsnJournalReturnCode.USN_JOURNAL_SUCCESS;
                }
            }
        }
        else
        {
            usnRtnCode = UsnJournalReturnCode.INVALID_HANDLE_VALUE;
        }
    }
    folders.Sort();
    System.Windows.MessageBox.Show(Convert.ToString(FoldersCount));
    //return FoldersCount;
    return (usnRtnCode, FoldersCount);
}
但是,这样做仍然可以使C样式代码向C#代码的音译效果不佳。真正需要的是将代码编写为面向对象的第一类C#方法,而不是过程C函数。
 
最佳 底部