我需要测试,如果用户实际上可以尝试这样做之前写的文件夹。
我已经实现了以下方法(在C#2.0),试图检索使用该文件夹的安全权限Directory.GetAccessControl()方法。
private bool hasWriteAccessToFolder(string folderPath)
{
try
{
// Attempt to get a list of security permissions from the folder.
// This will raise an exception if the path is read only or do not have access to view the permissions.
System.Security.AccessControl.DirectorySecurity ds = Directory.GetAccessControl(folderPath);
return true;
}
catch (UnauthorizedAccessException)
{
return false;
}
}
当我在谷歌上搜索如何测试写访问没有像这样走过来,显得十分复杂,在Windows实际上测试的权限。 我很担心,我囫囵吞枣的东西,这方法并不十分可靠,但它似乎工作。
将测试我的方法,如果当前用户有正确的写权限的工作?
Answer 1:
这是检查在C#中的文件夹访问一个完全有效的方式。 它可能会掉下来的唯一的地方是,如果你需要在一个紧凑的循环,其中一个异常的开销可能是一个问题调用此。
还有其他类似 的问题以前问。
Answer 2:
我明白,这是在一天这个帖子有点晚了,但你会发现这段代码是有用的。
string path = @"c:\temp";
string NtAccountName = @"MyDomain\MyUserOrGroup";
DirectoryInfo di = new DirectoryInfo(path);
DirectorySecurity acl = di.GetAccessControl(AccessControlSections.All);
AuthorizationRuleCollection rules = acl.GetAccessRules(true, true, typeof(NTAccount));
//Go through the rules returned from the DirectorySecurity
foreach (AuthorizationRule rule in rules)
{
//If we find one that matches the identity we are looking for
if (rule.IdentityReference.Value.Equals(NtAccountName,StringComparison.CurrentCultureIgnoreCase))
{
var filesystemAccessRule = (FileSystemAccessRule)rule;
//Cast to a FileSystemAccessRule to check for access rights
if ((filesystemAccessRule.FileSystemRights & FileSystemRights.WriteData)>0 && filesystemAccessRule.AccessControlType != AccessControlType.Deny)
{
Console.WriteLine(string.Format("{0} has write access to {1}", NtAccountName, path));
}
else
{
Console.WriteLine(string.Format("{0} does not have write access to {1}", NtAccountName, path));
}
}
}
Console.ReadLine();
丢弃到一个控制台应用程序,看看它做你需要什么。
Answer 3:
public bool IsDirectoryWritable(string dirPath, bool throwIfFails = false)
{
try
{
using (FileStream fs = File.Create(
Path.Combine(
dirPath,
Path.GetRandomFileName()
),
1,
FileOptions.DeleteOnClose)
)
{ }
return true;
}
catch
{
if (throwIfFails)
throw;
else
return false;
}
}
Answer 4:
我想大多数的这些,但他们给误报,都出于同样的原因。它是不够的测试目录中可用的权限,则必须检查登录的用户是有一个组的成员允许。 要做到这一点,你得到了用户的身份,并检查它是否是包含FileSystemAccessRule的IdentityReference一组的成员。 我测试了这一点,完美的作品..
/// <summary>
/// Test a directory for create file access permissions
/// </summary>
/// <param name="DirectoryPath">Full path to directory </param>
/// <param name="AccessRight">File System right tested</param>
/// <returns>State [bool]</returns>
public static bool DirectoryHasPermission(string DirectoryPath, FileSystemRights AccessRight)
{
if (string.IsNullOrEmpty(DirectoryPath)) return false;
try
{
AuthorizationRuleCollection rules = Directory.GetAccessControl(DirectoryPath).GetAccessRules(true, true, typeof(System.Security.Principal.SecurityIdentifier));
WindowsIdentity identity = WindowsIdentity.GetCurrent();
foreach (FileSystemAccessRule rule in rules)
{
if (identity.Groups.Contains(rule.IdentityReference))
{
if ((AccessRight & rule.FileSystemRights) == AccessRight)
{
if (rule.AccessControlType == AccessControlType.Allow)
return true;
}
}
}
}
catch { }
return false;
}
Answer 5:
例如,对于所有用户(内建\用户),这种方法效果很好 - 享受。
public static bool HasFolderWritePermission(string destDir)
{
if(string.IsNullOrEmpty(destDir) || !Directory.Exists(destDir)) return false;
try
{
DirectorySecurity security = Directory.GetAccessControl(destDir);
SecurityIdentifier users = new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null);
foreach(AuthorizationRule rule in security.GetAccessRules(true, true, typeof(SecurityIdentifier)))
{
if(rule.IdentityReference == users)
{
FileSystemAccessRule rights = ((FileSystemAccessRule)rule);
if(rights.AccessControlType == AccessControlType.Allow)
{
if(rights.FileSystemRights == (rights.FileSystemRights | FileSystemRights.Modify)) return true;
}
}
}
return false;
}
catch
{
return false;
}
}
Answer 6:
恕我直言,以测试是否可以写入到一个目录只有100%可靠的方法是实际写它,并最终捕获异常。
Answer 7:
试试这个:
try
{
DirectoryInfo di = new DirectoryInfo(path);
DirectorySecurity acl = di.GetAccessControl();
AuthorizationRuleCollection rules = acl.GetAccessRules(true, true, typeof(NTAccount));
WindowsIdentity currentUser = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(currentUser);
foreach (AuthorizationRule rule in rules)
{
FileSystemAccessRule fsAccessRule = rule as FileSystemAccessRule;
if (fsAccessRule == null)
continue;
if ((fsAccessRule.FileSystemRights & FileSystemRights.WriteData) > 0)
{
NTAccount ntAccount = rule.IdentityReference as NTAccount;
if (ntAccount == null)
{
continue;
}
if (principal.IsInRole(ntAccount.Value))
{
Console.WriteLine("Current user is in role of {0}, has write access", ntAccount.Value);
continue;
}
Console.WriteLine("Current user is not in role of {0}, does not have write access", ntAccount.Value);
}
}
}
catch (UnauthorizedAccessException)
{
Console.WriteLine("does not have write access");
}
Answer 8:
你的代码获取DirectorySecurity
对于一个给定的目录,并正确处理异常(由于您没有访问安全信息)。 然而,你的样品中,你实际上并不询问返回的对象,看看允许访问 - 我认为你需要在添加此。
Answer 9:
下面是修改后的版本CsabaS的回答 ,占明确拒绝访问规则。 该函数遍历所有FileSystemAccessRules一个目录,并检查当前用户在访问目录的作用。 如果没有找到这样的角色或用户与拒绝访问的作用,函数返回false。 要检查读取权限,通过FileSystemRights.Read的功能; 为写权限,通过FileSystemRights.Write。 如果您想查询任意用户的权限,而不是当前的,替代currentUser的WindowsIdentity所期望的WindowsIdentity。 我也建议不要依赖于这样的功能,以确定用户是否可以安全使用的目录。 这个答案完全解释为什么。
public static bool UserHasDirectoryAccessRights(string path, FileSystemRights accessRights)
{
var isInRoleWithAccess = false;
try
{
var di = new DirectoryInfo(path);
var acl = di.GetAccessControl();
var rules = acl.GetAccessRules(true, true, typeof(NTAccount));
var currentUser = WindowsIdentity.GetCurrent();
var principal = new WindowsPrincipal(currentUser);
foreach (AuthorizationRule rule in rules)
{
var fsAccessRule = rule as FileSystemAccessRule;
if (fsAccessRule == null)
continue;
if ((fsAccessRule.FileSystemRights & accessRights) > 0)
{
var ntAccount = rule.IdentityReference as NTAccount;
if (ntAccount == null)
continue;
if (principal.IsInRole(ntAccount.Value))
{
if (fsAccessRule.AccessControlType == AccessControlType.Deny)
return false;
isInRoleWithAccess = true;
}
}
}
}
catch (UnauthorizedAccessException)
{
return false;
}
return isInRoleWithAccess;
}
Answer 10:
我用同样的功能检查,如果文件hasWriteAccess:
private static bool HasWriteAccessToFile(string filePath)
{
try
{
// Attempt to get a list of security permissions from the file.
// This will raise an exception if the path is read only or do not have access to view the permissions.
File.GetAccessControl(filePath);
return true;
}
catch (UnauthorizedAccessException)
{
return false;
}
}
Answer 11:
你可以试试下面的代码块来检查目录的写权限。 它检查FileSystemAccessRule。
string directoryPath = "C:\\XYZ"; //folderBrowserDialog.SelectedPath;
bool isWriteAccess = false;
try
{
AuthorizationRuleCollection collection =
Directory.GetAccessControl(directoryPath)
.GetAccessRules(true, true, typeof(System.Security.Principal.NTAccount));
foreach (FileSystemAccessRule rule in collection)
{
if (rule.AccessControlType == AccessControlType.Allow)
{
isWriteAccess = true;
break;
}
}
}
catch (UnauthorizedAccessException ex)
{
isWriteAccess = false;
}
catch (Exception ex)
{
isWriteAccess = false;
}
if (!isWriteAccess)
{
//handle notifications
}
Answer 12:
你在你的代码中潜在的竞争条件 - 会发生什么,如果用户有写入权限,当您检查该文件夹,但在此之前用户实际写入文件夹此权限被撤销? 写入将抛出一个异常,你将需要捕捉和处理。 因此,最初的检查是没有意义的。 你可能也只是做了写和处理任何异常。 这是适合自己情况的标准模式。
Answer 13:
http://www.codeproject.com/KB/files/UserFileAccessRights.aspx
非常有用的类,检查改进的版本在消息中吼叫。
Answer 14:
上述解决方案是好的,但对我来说,我觉得这个代码简单可行。 只要创建一个临时文件。 如果创建一个文件,它意味着用户有写访问。
public static bool HasWritePermission(string tempfilepath)
{
try
{
System.IO.File.Create(tempfilepath + "temp.txt").Close();
System.IO.File.Delete(tempfilepath + "temp.txt");
}
catch (System.UnauthorizedAccessException ex)
{
return false;
}
return true;
}
Answer 15:
只是试图访问该文件中的问题并不一定是不够的。 这不一定是你想测试对用户权限 - 测试将运行该程序的用户的权限运行。
Answer 16:
我同意灰,这应该是罚款。 另外,您可以使用声明CAS,实际上防止程序在第一个位置运行,如果他们用不上。
我相信一些CAS功能可能无法从我所听到的,不知道这可能是一个问题,或不存在在C#4.0。
Answer 17:
我不能让GetAccessControl()扔在Windows 7上的异常,如接受的答案建议。
我结束了使用的变化SDDS的答案:
try
{
bool writeable = false;
WindowsPrincipal principal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
DirectorySecurity security = Directory.GetAccessControl(pstrPath);
AuthorizationRuleCollection authRules = security.GetAccessRules(true, true, typeof(SecurityIdentifier));
foreach (FileSystemAccessRule accessRule in authRules)
{
if (principal.IsInRole(accessRule.IdentityReference as SecurityIdentifier))
{
if ((FileSystemRights.WriteData & accessRule.FileSystemRights) == FileSystemRights.WriteData)
{
if (accessRule.AccessControlType == AccessControlType.Allow)
{
writeable = true;
}
else if (accessRule.AccessControlType == AccessControlType.Deny)
{
//Deny usually overrides any Allow
return false;
}
}
}
}
return writeable;
}
catch (UnauthorizedAccessException)
{
return false;
}
希望这可以帮助。
Answer 18:
我面临着同样的问题:如何验证,如果我能在一个特定的目录的读/写。 我结束了简单的解决方案...其实测试。 这里是我的简单但有效的解决方案。
class Program
{
/// <summary>
/// Tests if can read files and if any are present
/// </summary>
/// <param name="dirPath"></param>
/// <returns></returns>
private genericResponse check_canRead(string dirPath)
{
try
{
IEnumerable<string> files = Directory.EnumerateFiles(dirPath);
if (files.Count().Equals(0))
return new genericResponse() { status = true, idMsg = genericResponseType.NothingToRead };
return new genericResponse() { status = true, idMsg = genericResponseType.OK };
}
catch (DirectoryNotFoundException ex)
{
return new genericResponse() { status = false, idMsg = genericResponseType.ItemNotFound };
}
catch (UnauthorizedAccessException ex)
{
return new genericResponse() { status = false, idMsg = genericResponseType.CannotRead };
}
}
/// <summary>
/// Tests if can wirte both files or Directory
/// </summary>
/// <param name="dirPath"></param>
/// <returns></returns>
private genericResponse check_canWrite(string dirPath)
{
try
{
string testDir = "__TESTDIR__";
Directory.CreateDirectory(string.Join("/", dirPath, testDir));
Directory.Delete(string.Join("/", dirPath, testDir));
string testFile = "__TESTFILE__.txt";
try
{
TextWriter tw = new StreamWriter(string.Join("/", dirPath, testFile), false);
tw.WriteLine(testFile);
tw.Close();
File.Delete(string.Join("/", dirPath, testFile));
return new genericResponse() { status = true, idMsg = genericResponseType.OK };
}
catch (UnauthorizedAccessException ex)
{
return new genericResponse() { status = false, idMsg = genericResponseType.CannotWriteFile };
}
}
catch (UnauthorizedAccessException ex)
{
return new genericResponse() { status = false, idMsg = genericResponseType.CannotWriteDir };
}
}
}
public class genericResponse
{
public bool status { get; set; }
public genericResponseType idMsg { get; set; }
public string msg { get; set; }
}
public enum genericResponseType
{
NothingToRead = 1,
OK = 0,
CannotRead = -1,
CannotWriteDir = -2,
CannotWriteFile = -3,
ItemNotFound = -4
}
希望能帮助到你 !
文章来源: C# Test if user has write access to a folder