«отметьте метод 'findfirstfile' с 'LibraryImportAttribute' вместо« dllimportAttribute 'для генерации P/Invoke Marshalling Code во время компиляции ».
Код: Выделить всё
public partial class WindowsDirectoryTreeTraversal : IDisposable
{
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern nint FindFirstFile(string lpFileName, out WIN32_FIND_DATA lpFindFileData);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool FindNextFile(nint hFindFile, out WIN32_FIND_DATA lpFindFileData);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool FindClose(nint hFindFile);
private bool disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// Dispose managed resources here, if any
}
// Release unmanaged resources (close opened directories, etc.)
// Note: Ensure you call closedir here for any remaining open directories
disposed = true;
}
}
private static bool IsArchive(WIN32_FIND_DATA findFileData)
{
return (findFileData.dwFileAttributes & FileAttributes.Archive) != 0;
}
public async Task GetDirectoryTreeAsync(string path)
{
var directoryNode = new DirectoryNode(path, true);
var tasks = new List();
var stack = new Stack();
stack.Push((directoryNode, path));
try
{
while (stack.Count > 0)
{
var (currentNode, currentPath) = stack.Pop();
tasks.Add(ProcessDirectoryAsync(currentNode, currentPath));
}
await Task.WhenAll(tasks);
}
catch (Exception e)
{
Console.WriteLine($"Error accessing {path}: {e.Message}");
}
return directoryNode;
}
private async Task ProcessDirectoryAsync(DirectoryNode currentNode, string currentPath)
{
IntPtr hFindFile = FindFirstFile(Path.Combine(currentPath, "*"), out WIN32_FIND_DATA findFileData);
if (hFindFile == IntPtr.Zero)
{
Console.WriteLine($"Error finding files in directory {currentPath}");
return;
}
try
{
do
{
string entryName = findFileData.cFileName;
if (entryName == "." || entryName == "..")
continue;
string entryPath = Path.Combine(currentPath, entryName);
if ((findFileData.dwFileAttributes & FileAttributes.Directory) != 0)
{
var subNode = new DirectoryNode(entryPath, true);
currentNode.Subitems.Add(subNode);
await ProcessDirectoryAsync(subNode, entryPath);
}
else if (IsArchive(findFileData) && ArchiveRegex().IsMatch(entryName[entryName.LastIndexOf(".")..]))
{
currentNode.Subitems.Add(new DirectoryNode(entryPath, false));
}
} while (FindNextFile(hFindFile, out findFileData));
}
catch (Exception e)
{
Console.WriteLine($"Error reading dir {currentPath}: {e.Message}");
}
finally
{
FindClose(hFindFile);
}
}
[GeneratedRegex("\\.(zip|tar|7z|rar|zipx)$")]
private static partial Regex ArchiveRegex();
}
}
win32_find_data "/>
win32_find_data"/> />
Код: Выделить всё
public class AdditionalInfo
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct WIN32_FIND_DATA
{
public FileAttributes dwFileAttributes;
public uint ftCreationTime_dwLowDateTime;
public uint ftCreationTime_dwHighDateTime;
public uint ftLastAccessTime_dwLowDateTime;
public uint ftLastAccessTime_dwHighDateTime;
public uint ftLastWriteTime_dwLowDateTime;
public uint ftLastWriteTime_dwHighDateTime;
public uint nFileSizeHigh;
public uint nFileSizeLow;
public uint dwReserved0;
public uint dwReserved1;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string cFileName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
public string cAlternateFileName;
}
}
Подробнее здесь: https://stackoverflow.com/questions/768 ... -code-at-c