我正在编写一个封装临时文件夹的类。该文件夹将在程序与它们一起使用时保存文件,然后在处理对象时自行删除。
我想防止临时文件夹在使用时被搞砸。我知道可以在不更改任何权限的情况下保持文件夹“锁定” - 例如,如果打开命令提示符并将工作目录设置为特定文件夹,则无法删除该文件夹,除非您关闭命令提示符或将工作目录更改为其他内容。有没有办法在c#中以编程方式执行此操作?
我知道这有可能:
var path = @"c:\temp\MyFolderName";
System.IO.Directory.CreateDirectory(path);
System.Environment.CurrentDirectory = path;
System.IO.Directory.Delete(path); //Throws error
...但是这限制了我一个工作文件夹(看起来有点像kludgy)。
我知道我们可以通过打开它来锁定文件,但似乎没有办法“打开”目录。
答案 0 :(得分:3)
最直接的方法是在该目录中创建临时文件并将其锁定(使用FileShare.None
打开):
var directory = @"G:\tmp\so\locked";
var fileHandle = new FileStream(
Path.Combine(directory, ".lock"),
FileMode.Create,
FileAccess.ReadWrite,
FileShare.None);
try {
// now, you cannot delete or rename that folder until you press a key
Console.ReadKey();
}
finally {
fileHandle.Dispose();
}
如果由于某种原因不满足您 - 您可以获取目录本身的句柄。我不知道用纯.NET做到这一点的方法,但是你可以用原生的winapi(CreateFile
来做到这一点,但是尽管它的名字,它不会创建文件或目录,只需获取句柄):
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true, BestFitMapping = false)]
private static extern SafeFileHandle CreateFile(string lpFileName, FileAccess dwDesiredAccess, FileShare dwShareMode, IntPtr securityAttrs, FileMode dwCreationDisposition, int dwFlagsAndAttributes, IntPtr hTemplateFile);
var directory = @"G:\tmp\so\locked";
var directoryHandle = CreateFile(
directory,
FileAccess.ReadWrite,
FileShare.Read,
IntPtr.Zero,
FileMode.Open,
0x02000000, // << this flag is needed to obtain handle to directory
IntPtr.Zero);
if (directoryHandle.IsInvalid)
throw new Exception("Failed to obtain handle to directory");
try {
Console.ReadKey();
}
finally {
directoryHandle.Dispose();
}
它会产生相同的效果(在释放句柄之前无法删除或重命名目录),但没有其他文件。
答案 1 :(得分:-3)
DirectorySecurity
个班级
直接从文档中获取的示例:
AddDirectorySecurity(DirectoryName, @"MYDOMAIN\MyAccount", FileSystemRights.ReadData, AccessControlType.Allow);
public static void AddDirectorySecurity(string FileName, string Account, FileSystemRights Rights, AccessControlType ControlType)
{
// Create a new DirectoryInfo object.
DirectoryInfo dInfo = new DirectoryInfo(FileName);
// Get a DirectorySecurity object that represents the
// current security settings.
DirectorySecurity dSecurity = dInfo.GetAccessControl();
// Add the FileSystemAccessRule to the security settings.
dSecurity.AddAccessRule(new FileSystemAccessRule(Account, Rights, ControlType));
// Set the new access settings.
dInfo.SetAccessControl(dSecurity);
}