c# - 網頁標題 - 如何處理名稱超過259個字符的文件?
網頁摘要 (4)
我正在開發一個應用程序,它遍歷某些目錄中的每個文件,並對這些文件執行某些操作。 其中,我必須檢索文件大小和修改此文件的日期。
一些文件全名(目錄+文件名)太長,我無法使用.NET Framework FileInfo
,它僅限於MAX_PATH
(260個字符)。 許多Web資源建議通過P / Invoke使用本機Win32函數來訪問名稱太長的文件。
目前,Win32函數似乎出現了完全相同的問題。 例如, GetFileAttributesEx
(kernel32.dll)失敗,Win32錯誤3 ERROR_PATH_NOT_FOUND為270字節的路徑。
可以從Notepad2成功打開同一個文件,並使用Windows資源管理器成功顯示(但Visual Studio 2010因為259個字符限制¹而無法打開它)。
當文件路徑長度為270個字符時,如何才能訪問文件?
筆記:
刪除或忽略文件路徑長度超過259個字符的文件不是解決方案。
我只是在尋找兼容Unicode的解決方案。
該應用程序將在安裝了.NET Framework 4的Windows 2008 / Vista或更高版本下運行。
¹令人驚訝的是,Microsoft Word 2007失敗了,在沒有任何軟盤驅動器的計算機上抱怨“軟盤太小”,或者當剩下4 GB的RAM時,“RAM內存很低”,或者最後“防病毒軟件[...]需要更新”。 他們有一天會停止顯示至少在像Microsoft Office這樣的關鍵產品中出現這種愚蠢無意義的錯誤嗎?
https://code.i-harness.com
.NET Core現在支持長路徑名,而無需擴展語法 。
在此函數的ANSI版本中,名稱僅限於MAX_PATH字符。 要將此限制擴展為32,767個寬字符,請調用該函數的Unicode版本並在路徑前加上“\\?\”。 有關更多信息,請參閱命名文件 。
因此,您希望使用GetFileAttributesExW並在路徑前加上“\\?\”
您可以嘗試使用Delimon庫,它是Microsoft TechNet上基於.NET Framework 4的庫,用於克服長文件名問題:
Delimon.Win32.I O Library(V4.0)。
它有自己的System.IO關鍵方法版本。 例如,您將替換:
System.IO.Directory.GetFiles
同
Delimon.Win32.IO.Directory.GetFiles
這將讓你處理長文件和文件夾。
來自網站:
Delimon.Win32.IO取代了System.IO的基本文件功能,並支持最多32,767個字符的文件和文件夾名稱。
此庫是在.NET Framework 4.0上編寫的,可以在x86和x64系統上使用。 標準System.IO命名空間的文件和文件夾限制可以使用文件名中包含260個字符且文件夾名稱中包含240個字符的文件(MAX_PATH通常配置為260個字符)。 通常,您使用標準.NET庫遇到System.IO.PathTooLongException錯誤。
我創建了自己的LongFile
和LongDirectory
類來解決這個問題。 每當我正常使用System.IO.File
時,我都會使用它。
可能有優化等,但它已經很好地工作多年了。
public static class LongFile
{
private const int MAX_PATH = 260;
public static bool Exists(string path)
{
if (path.Length < MAX_PATH) return System.IO.File.Exists(path);
var attr = NativeMethods.GetFileAttributesW(GetWin32LongPath(path));
return (attr != NativeMethods.INVALID_FILE_ATTRIBUTES && ((attr & NativeMethods.FILE_ATTRIBUTE_ARCHIVE) == NativeMethods.FILE_ATTRIBUTE_ARCHIVE));
}
public static void Delete(string path)
{
if (path.Length < MAX_PATH) System.IO.File.Delete(path);
else
{
bool ok = NativeMethods.DeleteFileW(GetWin32LongPath(path));
if (!ok) ThrowWin32Exception();
}
}
public static void AppendAllText(string path, string contents)
{
AppendAllText(path, contents, Encoding.Default);
}
public static void AppendAllText(string path, string contents, Encoding encoding)
{
if (path.Length < MAX_PATH)
{
System.IO.File.AppendAllText(path, contents, encoding);
}
else
{
var fileHandle = CreateFileForAppend(GetWin32LongPath(path));
using (var fs = new System.IO.FileStream(fileHandle, System.IO.FileAccess.Write))
{
var bytes = encoding.GetBytes(contents);
fs.Position = fs.Length;
fs.Write(bytes, 0, bytes.Length);
}
}
}
public static void WriteAllText(string path, string contents)
{
WriteAllText(path, contents, Encoding.Default);
}
public static void WriteAllText(string path, string contents, Encoding encoding)
{
if (path.Length < MAX_PATH)
{
System.IO.File.WriteAllText(path, contents, encoding);
}
else
{
var fileHandle = CreateFileForWrite(GetWin32LongPath(path));
using (var fs = new System.IO.FileStream(fileHandle, System.IO.FileAccess.Write))
{
var bytes = encoding.GetBytes(contents);
fs.Write(bytes, 0, bytes.Length);
}
}
}
public static void WriteAllBytes(string path, byte[] bytes)
{
if (path.Length < MAX_PATH)
{
System.IO.File.WriteAllBytes(path, bytes);
}
else
{
var fileHandle = CreateFileForWrite(GetWin32LongPath(path));
using (var fs = new System.IO.FileStream(fileHandle, System.IO.FileAccess.Write))
{
fs.Write(bytes, 0, bytes.Length);
}
}
}
public static void Copy(string sourceFileName, string destFileName)
{
Copy(sourceFileName, destFileName, false);
}
public static void Copy(string sourceFileName, string destFileName, bool overwrite)
{
if (sourceFileName.Length < MAX_PATH && (destFileName.Length < MAX_PATH)) System.IO.File.Copy(sourceFileName, destFileName, overwrite);
else
{
var ok = NativeMethods.CopyFileW(GetWin32LongPath(sourceFileName), GetWin32LongPath(destFileName), !overwrite);
if (!ok) ThrowWin32Exception();
}
}
public static void Move(string sourceFileName, string destFileName)
{
if (sourceFileName.Length < MAX_PATH && (destFileName.Length < MAX_PATH)) System.IO.File.Move(sourceFileName, destFileName);
else
{
var ok = NativeMethods.MoveFileW(GetWin32LongPath(sourceFileName), GetWin32LongPath(destFileName));
if (!ok) ThrowWin32Exception();
}
}
public static string ReadAllText(string path)
{
return ReadAllText(path, Encoding.Default);
}
public static string ReadAllText(string path, Encoding encoding)
{
if (path.Length < MAX_PATH) { return System.IO.File.ReadAllText(path, encoding); }
var fileHandle = GetFileHandle(GetWin32LongPath(path));
using (var fs = new System.IO.FileStream(fileHandle, System.IO.FileAccess.Read))
{
var data = new byte[fs.Length];
fs.Read(data, 0, data.Length);
return encoding.GetString(data);
}
}
public static string[] ReadAllLines(string path)
{
return ReadAllLines(path, Encoding.Default);
}
public static string[] ReadAllLines(string path, Encoding encoding)
{
if (path.Length < MAX_PATH) { return System.IO.File.ReadAllLines(path, encoding); }
var fileHandle = GetFileHandle(GetWin32LongPath(path));
using (var fs = new System.IO.FileStream(fileHandle, System.IO.FileAccess.Read))
{
var data = new byte[fs.Length];
fs.Read(data, 0, data.Length);
var str = encoding.GetString(data);
if (str.Contains("\r")) return str.Split(new[] { "\r\n" }, StringSplitOptions.None);
return str.Split('\n');
}
}
public static byte[] ReadAllBytes(string path)
{
if (path.Length < MAX_PATH) return System.IO.File.ReadAllBytes(path);
var fileHandle = GetFileHandle(GetWin32LongPath(path));
using (var fs = new System.IO.FileStream(fileHandle, System.IO.FileAccess.Read))
{
var data = new byte[fs.Length];
fs.Read(data, 0, data.Length);
return data;
}
}
public static void SetAttributes(string path, FileAttributes attributes)
{
if (path.Length < MAX_PATH)
{
System.IO.File.SetAttributes(path, attributes);
}
else
{
var longFilename = GetWin32LongPath(path);
NativeMethods.SetFileAttributesW(longFilename, (int)attributes);
}
}
#region Helper methods
private static SafeFileHandle CreateFileForWrite(string filename)
{
if (filename.Length >= MAX_PATH) filename = GetWin32LongPath(filename);
SafeFileHandle hfile = NativeMethods.CreateFile(filename, (int)NativeMethods.FILE_GENERIC_WRITE, NativeMethods.FILE_SHARE_NONE, IntPtr.Zero, NativeMethods.CREATE_ALWAYS, 0, IntPtr.Zero);
if (hfile.IsInvalid) ThrowWin32Exception();
return hfile;
}
private static SafeFileHandle CreateFileForAppend(string filename)
{
if (filename.Length >= MAX_PATH) filename = GetWin32LongPath(filename);
SafeFileHandle hfile = NativeMethods.CreateFile(filename, (int)NativeMethods.FILE_GENERIC_WRITE, NativeMethods.FILE_SHARE_NONE, IntPtr.Zero, NativeMethods.CREATE_NEW, 0, IntPtr.Zero);
if (hfile.IsInvalid)
{
hfile = NativeMethods.CreateFile(filename, (int)NativeMethods.FILE_GENERIC_WRITE, NativeMethods.FILE_SHARE_NONE, IntPtr.Zero, NativeMethods.OPEN_EXISTING, 0, IntPtr.Zero);
if (hfile.IsInvalid) ThrowWin32Exception();
}
return hfile;
}
internal static SafeFileHandle GetFileHandle(string filename)
{
if (filename.Length >= MAX_PATH) filename = GetWin32LongPath(filename);
SafeFileHandle hfile = NativeMethods.CreateFile(filename, (int)NativeMethods.FILE_GENERIC_READ, NativeMethods.FILE_SHARE_READ, IntPtr.Zero, NativeMethods.OPEN_EXISTING, 0, IntPtr.Zero);
if (hfile.IsInvalid) ThrowWin32Exception();
return hfile;
}
internal static SafeFileHandle GetFileHandleWithWrite(string filename)
{
if (filename.Length >= MAX_PATH) filename = GetWin32LongPath(filename);
SafeFileHandle hfile = NativeMethods.CreateFile(filename, (int)(NativeMethods.FILE_GENERIC_READ | NativeMethods.FILE_GENERIC_WRITE | NativeMethods.FILE_WRITE_ATTRIBUTES), NativeMethods.FILE_SHARE_NONE, IntPtr.Zero, NativeMethods.OPEN_EXISTING, 0, IntPtr.Zero);
if (hfile.IsInvalid) ThrowWin32Exception();
return hfile;
}
public static System.IO.FileStream GetFileStream(string filename, FileAccess access = FileAccess.Read)
{
var longFilename = GetWin32LongPath(filename);
SafeFileHandle hfile;
if (access == FileAccess.Write)
{
hfile = NativeMethods.CreateFile(longFilename, (int)(NativeMethods.FILE_GENERIC_READ | NativeMethods.FILE_GENERIC_WRITE | NativeMethods.FILE_WRITE_ATTRIBUTES), NativeMethods.FILE_SHARE_NONE, IntPtr.Zero, NativeMethods.OPEN_EXISTING, 0, IntPtr.Zero);
}
else
{
hfile = NativeMethods.CreateFile(longFilename, (int)NativeMethods.FILE_GENERIC_READ, NativeMethods.FILE_SHARE_READ, IntPtr.Zero, NativeMethods.OPEN_EXISTING, 0, IntPtr.Zero);
}
if (hfile.IsInvalid) ThrowWin32Exception();
return new System.IO.FileStream(hfile, access);
}
[DebuggerStepThrough]
public static void ThrowWin32Exception()
{
int code = Marshal.GetLastWin32Error();
if (code != 0)
{
throw new System.ComponentModel.Win32Exception(code);
}
}
public static string GetWin32LongPath(string path)
{
if (path.StartsWith(@"\\?\")) return path;
if (path.StartsWith("\\"))
{
path = @"\\?\UNC\" + path.Substring(2);
}
else if (path.Contains(":"))
{
path = @"\\?\" + path;
}
else
{
var currdir = Environment.CurrentDirectory;
path = Combine(currdir, path);
while (path.Contains("\\.\\")) path = path.Replace("\\.\\", "\\");
path = @"\\?\" + path;
}
return path.TrimEnd('.'); ;
}
private static string Combine(string path1, string path2)
{
return path1.TrimEnd('\\') + "\\" + path2.TrimStart('\\').TrimEnd('.'); ;
}
#endregion
public static void SetCreationTime(string path, DateTime creationTime)
{
long cTime = 0;
long aTime = 0;
long wTime = 0;
using (var handle = GetFileHandleWithWrite(path))
{
NativeMethods.GetFileTime(handle, ref cTime, ref aTime, ref wTime);
var fileTime = creationTime.ToFileTimeUtc();
if (!NativeMethods.SetFileTime(handle, ref fileTime, ref aTime, ref wTime))
{
throw new Win32Exception();
}
}
}
public static void SetLastAccessTime(string path, DateTime lastAccessTime)
{
long cTime = 0;
long aTime = 0;
long wTime = 0;
using (var handle = GetFileHandleWithWrite(path))
{
NativeMethods.GetFileTime(handle, ref cTime, ref aTime, ref wTime);
var fileTime = lastAccessTime.ToFileTimeUtc();
if (!NativeMethods.SetFileTime(handle, ref cTime, ref fileTime, ref wTime))
{
throw new Win32Exception();
}
}
}
public static void SetLastWriteTime(string path, DateTime lastWriteTime)
{
long cTime = 0;
long aTime = 0;
long wTime = 0;
using (var handle = GetFileHandleWithWrite(path))
{
NativeMethods.GetFileTime(handle, ref cTime, ref aTime, ref wTime);
var fileTime = lastWriteTime.ToFileTimeUtc();
if (!NativeMethods.SetFileTime(handle, ref cTime, ref aTime, ref fileTime))
{
throw new Win32Exception();
}
}
}
public static DateTime GetLastWriteTime(string path)
{
long cTime = 0;
long aTime = 0;
long wTime = 0;
using (var handle = GetFileHandleWithWrite(path))
{
NativeMethods.GetFileTime(handle, ref cTime, ref aTime, ref wTime);
return DateTime.FromFileTimeUtc(wTime);
}
}
}
和相應的LongDirectory
:
public class LongDirectory
{
private const int MAX_PATH = 260;
public static void CreateDirectory(string path)
{
if (string.IsNullOrWhiteSpace(path)) return;
if (path.Length < MAX_PATH)
{
System.IO.Directory.CreateDirectory(path);
}
else
{
var paths = GetAllPathsFromPath(GetWin32LongPath(path));
foreach (var item in paths)
{
if (!LongExists(item))
{
var ok = NativeMethods.CreateDirectory(item, IntPtr.Zero);
if (!ok)
{
ThrowWin32Exception();
}
}
}
}
}
public static void Delete(string path)
{
Delete(path, false);
}
public static void Delete(string path, bool recursive)
{
if (path.Length < MAX_PATH && !recursive)
{
System.IO.Directory.Delete(path, false);
}
else
{
if (!recursive)
{
bool ok = NativeMethods.RemoveDirectory(GetWin32LongPath(path));
if (!ok) ThrowWin32Exception();
}
else
{
DeleteDirectories(new string[] { GetWin32LongPath(path) });
}
}
}
private static void DeleteDirectories(string[] directories)
{
foreach (string directory in directories)
{
string[] files = LongDirectory.GetFiles(directory, null, System.IO.SearchOption.TopDirectoryOnly);
foreach (string file in files)
{
LongFile.Delete(file);
}
directories = LongDirectory.GetDirectories(directory, null, System.IO.SearchOption.TopDirectoryOnly);
DeleteDirectories(directories);
bool ok = NativeMethods.RemoveDirectory(GetWin32LongPath(directory));
if (!ok) ThrowWin32Exception();
}
}
public static bool Exists(string path)
{
if (path.Length < MAX_PATH) return System.IO.Directory.Exists(path);
return LongExists(GetWin32LongPath(path));
}
private static bool LongExists(string path)
{
var attr = NativeMethods.GetFileAttributesW(path);
return (attr != NativeMethods.INVALID_FILE_ATTRIBUTES && ((attr & NativeMethods.FILE_ATTRIBUTE_DIRECTORY) == NativeMethods.FILE_ATTRIBUTE_DIRECTORY));
}
public static string[] GetDirectories(string path)
{
return GetDirectories(path, null, SearchOption.TopDirectoryOnly);
}
public static string[] GetDirectories(string path, string searchPattern)
{
return GetDirectories(path, searchPattern, SearchOption.TopDirectoryOnly);
}
public static string[] GetDirectories(string path, string searchPattern, System.IO.SearchOption searchOption)
{
searchPattern = searchPattern ?? "*";
var dirs = new List<string>();
InternalGetDirectories(path, searchPattern, searchOption, ref dirs);
return dirs.ToArray();
}
private static void InternalGetDirectories(string path, string searchPattern, System.IO.SearchOption searchOption, ref List<string> dirs)
{
NativeMethods.WIN32_FIND_DATA findData;
IntPtr findHandle = NativeMethods.FindFirstFile(System.IO.Path.Combine(GetWin32LongPath(path), searchPattern), out findData);
try
{
if (findHandle != new IntPtr(-1))
{
do
{
if ((findData.dwFileAttributes & System.IO.FileAttributes.Directory) != 0)
{
if (findData.cFileName != "." && findData.cFileName != "..")
{
string subdirectory = System.IO.Path.Combine(path, findData.cFileName);
dirs.Add(GetCleanPath(subdirectory));
if (searchOption == SearchOption.AllDirectories)
{
InternalGetDirectories(subdirectory, searchPattern, searchOption, ref dirs);
}
}
}
} while (NativeMethods.FindNextFile(findHandle, out findData));
NativeMethods.FindClose(findHandle);
}
else
{
ThrowWin32Exception();
}
}
catch (Exception)
{
NativeMethods.FindClose(findHandle);
throw;
}
}
public static string[] GetFiles(string path)
{
return GetFiles(path, null, SearchOption.TopDirectoryOnly);
}
public static string[] GetFiles(string path, string searchPattern)
{
return GetFiles(path, searchPattern, SearchOption.TopDirectoryOnly);
}
public static string[] GetFiles(string path, string searchPattern, System.IO.SearchOption searchOption)
{
searchPattern = searchPattern ?? "*";
var files = new List<string>();
var dirs = new List<string> { path };
if (searchOption == SearchOption.AllDirectories)
{
//Add all the subpaths
dirs.AddRange(LongDirectory.GetDirectories(path, null, SearchOption.AllDirectories));
}
foreach (var dir in dirs)
{
NativeMethods.WIN32_FIND_DATA findData;
IntPtr findHandle = NativeMethods.FindFirstFile(System.IO.Path.Combine(GetWin32LongPath(dir), searchPattern), out findData);
try
{
if (findHandle != new IntPtr(-1))
{
do
{
if ((findData.dwFileAttributes & System.IO.FileAttributes.Directory) == 0)
{
string filename = System.IO.Path.Combine(dir, findData.cFileName);
files.Add(GetCleanPath(filename));
}
} while (NativeMethods.FindNextFile(findHandle, out findData));
NativeMethods.FindClose(findHandle);
}
}
catch (Exception)
{
NativeMethods.FindClose(findHandle);
throw;
}
}
return files.ToArray();
}
public static void Move(string sourceDirName, string destDirName)
{
if (sourceDirName.Length < MAX_PATH || destDirName.Length < MAX_PATH)
{
System.IO.Directory.Move(sourceDirName, destDirName);
}
else
{
var ok = NativeMethods.MoveFileW(GetWin32LongPath(sourceDirName), GetWin32LongPath(destDirName));
if (!ok) ThrowWin32Exception();
}
}
#region Helper methods
[DebuggerStepThrough]
public static void ThrowWin32Exception()
{
int code = Marshal.GetLastWin32Error();
if (code != 0)
{
throw new System.ComponentModel.Win32Exception(code);
}
}
public static string GetWin32LongPath(string path)
{
if (path.StartsWith(@"\\?\")) return path;
var newpath = path;
if (newpath.StartsWith("\\"))
{
newpath = @"\\?\UNC\" + newpath.Substring(2);
}
else if (newpath.Contains(":"))
{
newpath = @"\\?\" + newpath;
}
else
{
var currdir = Environment.CurrentDirectory;
newpath = Combine(currdir, newpath);
while (newpath.Contains("\\.\\")) newpath = newpath.Replace("\\.\\", "\\");
newpath = @"\\?\" + newpath;
}
return newpath.TrimEnd('.');
}
private static string GetCleanPath(string path)
{
if (path.StartsWith(@"\\?\UNC\")) return @"\\" + path.Substring(8);
if (path.StartsWith(@"\\?\")) return path.Substring(4);
return path;
}
private static List<string> GetAllPathsFromPath(string path)
{
bool unc = false;
var prefix = @"\\?\";
if (path.StartsWith(prefix + @"UNC\"))
{
prefix += @"UNC\";
unc = true;
}
var split = path.Split('\\');
int i = unc ? 6 : 4;
var list = new List<string>();
var txt = "";
for (int a = 0; a < i; a++)
{
if (a > 0) txt += "\\";
txt += split[a];
}
for (; i < split.Length; i++)
{
txt = Combine(txt, split[i]);
list.Add(txt);
}
return list;
}
private static string Combine(string path1, string path2)
{
return path1.TrimEnd('\\') + "\\" + path2.TrimStart('\\').TrimEnd('.');
}
#endregion
}
NativeMethods
:
internal static class NativeMethods
{
internal const int FILE_ATTRIBUTE_ARCHIVE = 0x20;
internal const int INVALID_FILE_ATTRIBUTES = -1;
internal const int FILE_READ_DATA = 0x0001;
internal const int FILE_WRITE_DATA = 0x0002;
internal const int FILE_APPEND_DATA = 0x0004;
internal const int FILE_READ_EA = 0x0008;
internal const int FILE_WRITE_EA = 0x0010;
internal const int FILE_READ_ATTRIBUTES = 0x0080;
internal const int FILE_WRITE_ATTRIBUTES = 0x0100;
internal const int FILE_SHARE_NONE = 0x00000000;
internal const int FILE_SHARE_READ = 0x00000001;
internal const int FILE_ATTRIBUTE_DIRECTORY = 0x10;
internal const long FILE_GENERIC_WRITE = STANDARD_RIGHTS_WRITE |
FILE_WRITE_DATA |
FILE_WRITE_ATTRIBUTES |
FILE_WRITE_EA |
FILE_APPEND_DATA |
SYNCHRONIZE;
internal const long FILE_GENERIC_READ = STANDARD_RIGHTS_READ |
FILE_READ_DATA |
FILE_READ_ATTRIBUTES |
FILE_READ_EA |
SYNCHRONIZE;
internal const long READ_CONTROL = 0x00020000L;
internal const long STANDARD_RIGHTS_READ = READ_CONTROL;
internal const long STANDARD_RIGHTS_WRITE = READ_CONTROL;
internal const long SYNCHRONIZE = 0x00100000L;
internal const int CREATE_NEW = 1;
internal const int CREATE_ALWAYS = 2;
internal const int OPEN_EXISTING = 3;
internal const int MAX_PATH = 260;
internal const int MAX_ALTERNATE = 14;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal struct WIN32_FIND_DATA
{
public System.IO.FileAttributes dwFileAttributes;
public FILETIME ftCreationTime;
public FILETIME ftLastAccessTime;
public FILETIME ftLastWriteTime;
public uint nFileSizeHigh; //changed all to uint, otherwise you run into unexpected overflow
public uint nFileSizeLow; //|
public uint dwReserved0; //|
public uint dwReserved1; //v
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)]
public string cFileName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_ALTERNATE)]
public string cAlternate;
}
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern SafeFileHandle CreateFile(string lpFileName, int dwDesiredAccess, int dwShareMode, IntPtr lpSecurityAttributes, int dwCreationDisposition, int dwFlagsAndAttributes, IntPtr hTemplateFile);
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern bool CopyFileW(string lpExistingFileName, string lpNewFileName, bool bFailIfExists);
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern int GetFileAttributesW(string lpFileName);
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern bool DeleteFileW(string lpFileName);
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern bool MoveFileW(string lpExistingFileName, string lpNewFileName);
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern bool SetFileTime(SafeFileHandle hFile, ref long lpCreationTime, ref long lpLastAccessTime, ref long lpLastWriteTime);
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern bool GetFileTime(SafeFileHandle hFile, ref long lpCreationTime, ref long lpLastAccessTime, ref long lpLastWriteTime);
[DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern IntPtr FindFirstFile(string lpFileName, out WIN32_FIND_DATA lpFindFileData);
[DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern bool FindNextFile(IntPtr hFindFile, out WIN32_FIND_DATA lpFindFileData);
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern bool FindClose(IntPtr hFindFile);
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern bool RemoveDirectory(string path);
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern bool CreateDirectory(string lpPathName, IntPtr lpSecurityAttributes);
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern int SetFileAttributesW(string lpFileName, int fileAttributes);
}