Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何检查写入目录或文件的权限?_C#_.net - Fatal编程技术网

C# 如何检查写入目录或文件的权限?

C# 如何检查写入目录或文件的权限?,c#,.net,C#,.net,我得到了一个程序,它使用下面的方法将一些数据写入文件 public void ExportToFile(string filename) { using(FileStream fstream = new FileStream(filename,FileMode.Create)) using (TextWriter writer = new StreamWriter(fstream)) { // try catch block for write

我得到了一个程序,它使用下面的方法将一些数据写入文件


public void ExportToFile(string filename)
{
     using(FileStream fstream = new FileStream(filename,FileMode.Create))
     using (TextWriter writer = new StreamWriter(fstream))
     {
         // try catch block for write permissions 
         writer.WriteLine(text);


     }
}
运行程序时,我收到一个错误:

未处理的异常:System.UnauthorizedAccessException:对路径“mypath”的访问被拒绝。 在System.IO.\uuu Error.WinIOError(Int32 errorCode,字符串maybeFullPath) 在System.IO.FileStream.Init(字符串路径、文件模式、文件访问、, nt32权限、布尔用户权限、文件共享共享、Int32 bufferSize、文件选项 选项、安全属性(secAttrs、字符串msgPath、布尔bFromProxy) 在System.IO.FileStream..ctor(字符串路径、文件模式、文件访问 FileShare共享、Int32 bufferSize、FileOptions选项、字符串msgPath、Boolea bFromProxy)


问题:我需要什么代码来捕获此信息,以及如何授予访问权限?

更新:

修改了基于的代码以摆脱过时的方法

您可以使用安全命名空间来检查以下内容:

public void ExportToFile(string filename)
{
    var permissionSet = new PermissionSet(PermissionState.None);    
    var writePermission = new FileIOPermission(FileIOPermissionAccess.Write, filename);
    permissionSet.AddPermission(writePermission);

    if (permissionSet.IsSubsetOf(AppDomain.CurrentDomain.PermissionSet))
    {
        using (FileStream fstream = new FileStream(filename, FileMode.Create))
        using (TextWriter writer = new StreamWriter(fstream))
        {
            // try catch block for write permissions 
            writer.WriteLine("sometext");


        }
    }
    else
    {
        //perform some recovery action here
    }

}

就获得这些权限而言,您必须要求用户以某种方式为您这样做。如果您可以按编程方式执行此操作,那么我们都会遇到麻烦;)

当代码执行以下操作时:

  • 检查当前用户是否具有执行某些操作的权限
  • 执行需要签入权限1的操作
  • 您将面临权限在1和2之间更改的风险,因为您无法预测在运行时系统上还会发生什么。因此,即使您以前检查过权限,代码也应该处理引发UnauthorizedAccessException的情况

    请注意,SecurityManager类用于检查CAS权限,实际上并不与操作系统一起检查当前用户是否具有对指定位置的写入权限(通过ACL和ACE)。因此,对于本地运行的应用程序,isgrant将始终返回true

    示例(源自):


    尝试基于原始ACL(可通过System.Security.AccessControl类获得的所有ACL)以编程方式计算文件夹中的有效权限是很棘手的,不建议这样做。关于堆栈溢出和更广泛的web的其他答案建议尝试执行该操作,以了解是否允许权限。post总结了实现权限计算所需的内容,应该足以让您推迟执行此操作。

    您可以尝试以下代码块来检查目录是否具有写访问权限

    它检查文件系统AccessRule

               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                 
               }
    

    抱歉,以前的解决方案对我都没有帮助。我需要检查双方:SecurityManager和其他权限。我通过Josh代码和iain answer学到了很多,但我担心我需要使用Rakesh代码(也要感谢他)。只有一个bug:我发现他只检查允许权限,而不检查拒绝权限。因此,我的建议是:

            string folder;
            AuthorizationRuleCollection rules;
            try {
                rules = Directory.GetAccessControl(folder)
                    .GetAccessRules(true, true, typeof(System.Security.Principal.NTAccount));
            } catch(Exception ex) { //Posible UnauthorizedAccessException
                throw new Exception("No permission", ex);
            }
    
            var rulesCast = rules.Cast<FileSystemAccessRule>();
            if(rulesCast.Any(rule => rule.AccessControlType == AccessControlType.Deny)
                || !rulesCast.Any(rule => rule.AccessControlType == AccessControlType.Allow))
                throw new Exception("No permission");
    
            //Here I have permission, ole!
    
    字符串文件夹;
    授权规则收集规则;
    试一试{
    规则=目录.GetAccessControl(文件夹)
    .GetAccessRules(true、true、typeof(System.Security.Principal.NTAccount));
    }捕获(异常示例){//Posible UnauthorizedAccessException
    抛出新异常(“无许可”,例如);
    }
    var rulesCast=rules.Cast();
    if(rulesCast.Any(rule=>rule.AccessControlType==AccessControlType.Deny)
    ||!rulesCast.Any(rule=>rule.AccessControlType==AccessControlType.Allow))
    抛出新异常(“无许可”);
    //这是我的许可,奥立!
    
    这些都不适合我。。它们返回为真,即使它们不是真的。问题是,您必须根据当前进程用户权限测试可用权限,这将测试文件创建权限,只需将FileSystemRights子句更改为“Write”即可测试写访问

    /// <summary>
    /// Test a directory for create file access permissions
    /// </summary>
    /// <param name="DirectoryPath">Full directory path</param>
    /// <returns>State [bool]</returns>
    public static bool DirectoryCanCreate(string DirectoryPath)
    {
        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 ((FileSystemRights.CreateFiles & rule.FileSystemRights) == FileSystemRights.CreateFiles)
                    {
                        if (rule.AccessControlType == AccessControlType.Allow)
                            return true;
                    }
                }
            }
        }
        catch {}
        return false;
    }
    
    //
    ///测试目录的创建文件访问权限
    /// 
    ///完整目录路径
    ///国家[布尔]
    公共静态bool DirectoryCanCreate(字符串DirectoryPath)
    {
    if(string.IsNullOrEmpty(DirectoryPath))返回false;
    尝试
    {
    AuthorizationRuleCollection rules=Directory.GetAccessControl(DirectoryPath).GetAccessRules(true,true,typeof(System.Security.Principal.SecurityIdentifier));
    WindowsIdentity=WindowsIdentity.GetCurrent();
    foreach(规则中的FileSystemAccessRule规则)
    {
    if(identity.Groups.Contains(rule.IdentityReference))
    {
    if((FileSystemRights.CreateFiles&rule.FileSystemRights)==FileSystemRights.CreateFiles)
    {
    if(rule.AccessControlType==AccessControlType.Allow)
    返回true;
    }
    }
    }
    }
    捕获{}
    返回false;
    }
    
    由于此项尚未关闭,我想为任何希望某项功能正常运行的人提交一份新条目。。。使用我在这里发现的内容的合并,以及使用DirectoryServices调试代码本身并找到合适的代码来使用,以下是我发现的在任何情况下都适用于我的内容。。。请注意,我的解决方案扩展了DirectoryInfo对象…:

        public static bool IsReadable(this DirectoryInfo me)
        {
    
            AuthorizationRuleCollection rules;
            WindowsIdentity identity;
            try
            {
                rules = me.GetAccessControl().GetAccessRules(true, true, typeof(System.Security.Principal.SecurityIdentifier));
                identity = WindowsIdentity.GetCurrent();
            }
            catch (Exception ex)
            { //Posible UnauthorizedAccessException
                return false;
            }
    
            bool isAllow=false;
            string userSID = identity.User.Value;
    
            foreach (FileSystemAccessRule rule in rules)
            {
                if (rule.IdentityReference.ToString() == userSID || identity.Groups.Contains(rule.IdentityReference))
                {
                    if ((rule.FileSystemRights.HasFlag(FileSystemRights.Read) ||
                        rule.FileSystemRights.HasFlag(FileSystemRights.ReadAndExecute) ||
                        rule.FileSystemRights.HasFlag(FileSystemRights.ReadAttributes) ||
                        rule.FileSystemRights.HasFlag(FileSystemRights.ReadData) ||
                        rule.FileSystemRights.HasFlag(FileSystemRights.ReadExtendedAttributes) ||
                        rule.FileSystemRights.HasFlag(FileSystemRights.ReadPermissions)) && rule.AccessControlType == AccessControlType.Deny)
                        return false;
                    else if ((rule.FileSystemRights.HasFlag(FileSystemRights.Read) ||
                        rule.FileSystemRights.HasFlag(FileSystemRights.ReadAndExecute) ||
                        rule.FileSystemRights.HasFlag(FileSystemRights.ReadAttributes) ||
                        rule.FileSystemRights.HasFlag(FileSystemRights.ReadData) ||
                        rule.FileSystemRights.HasFlag(FileSystemRights.ReadExtendedAttributes) ||
                        rule.FileSystemRights.HasFlag(FileSystemRights.ReadPermissions)) && rule.AccessControlType == AccessControlType.Allow)
                        isAllow = true;
                }
            }
    
            return isAllow;
        }
    
        public static bool IsWriteable(this DirectoryInfo me)
        {
            AuthorizationRuleCollection rules;
            WindowsIdentity identity;
            try
            {
                rules = me.GetAccessControl().GetAccessRules(true, true, typeof(System.Security.Principal.SecurityIdentifier));
                identity = WindowsIdentity.GetCurrent();
            }
            catch (Exception ex)
            { //Posible UnauthorizedAccessException
                return false;
            }
    
            bool isAllow = false;
            string userSID = identity.User.Value;
    
            foreach (FileSystemAccessRule rule in rules)
            {
                if (rule.IdentityReference.ToString() == userSID || identity.Groups.Contains(rule.IdentityReference))
                {
                    if ((rule.FileSystemRights.HasFlag(FileSystemRights.Write) ||
                        rule.FileSystemRights.HasFlag(FileSystemRights.WriteAttributes) ||
                        rule.FileSystemRights.HasFlag(FileSystemRights.WriteData) ||
                        rule.FileSystemRights.HasFlag(FileSystemRights.WriteExtendedAttributes) ||
                        rule.FileSystemRights.HasFlag(FileSystemRights.CreateDirectories) ||
                        rule.FileSystemRights.HasFlag(FileSystemRights.CreateFiles)) && rule.AccessControlType == AccessControlType.Deny)
                        return false;
                    else if ((rule.FileSystemRights.HasFlag(FileSystemRights.Write) ||
                        rule.FileSystemRights.HasFlag(FileSystemRights.WriteAttributes) ||
                        rule.FileSystemRights.HasFlag(FileSystemRights.WriteData) ||
                        rule.FileSystemRights.HasFlag(FileSystemRights.WriteExtendedAttributes) ||
                        rule.FileSystemRights.HasFlag(FileSystemRights.CreateDirectories) ||
                        rule.FileSystemRights.HasFlag(FileSystemRights.CreateFiles)) && rule.AccessControlType == AccessControlType.Allow)
                        isAllow = true;
                }
            }
    
            return me.IsReadable() && isAllow;
        }
    

    它是MaxOvrdrv的固定版本


    哇……这个线程中有很多低级安全代码——其中大部分对我来说也不起作用——尽管我在这个过程中学到了很多。我了解到的一件事是,这段代码的大部分并不适用于寻求每用户访问权限的应用程序——它适用于希望以编程方式更改权限的管理员,正如已经指出的那样,这不是一件好事。作为一名开发人员,我不能使用“简单的方法”——以管理员的身份运行——这——我不是运行代码的机器上的人,我的用户也不是——因此,尽管这些解决方案很聪明——它们不适合我的情况,也可能不适合大多数级别和级别
        public static bool IsReadable(this DirectoryInfo me)
        {
    
            AuthorizationRuleCollection rules;
            WindowsIdentity identity;
            try
            {
                rules = me.GetAccessControl().GetAccessRules(true, true, typeof(System.Security.Principal.SecurityIdentifier));
                identity = WindowsIdentity.GetCurrent();
            }
            catch (Exception ex)
            { //Posible UnauthorizedAccessException
                return false;
            }
    
            bool isAllow=false;
            string userSID = identity.User.Value;
    
            foreach (FileSystemAccessRule rule in rules)
            {
                if (rule.IdentityReference.ToString() == userSID || identity.Groups.Contains(rule.IdentityReference))
                {
                    if ((rule.FileSystemRights.HasFlag(FileSystemRights.Read) ||
                        rule.FileSystemRights.HasFlag(FileSystemRights.ReadAndExecute) ||
                        rule.FileSystemRights.HasFlag(FileSystemRights.ReadAttributes) ||
                        rule.FileSystemRights.HasFlag(FileSystemRights.ReadData) ||
                        rule.FileSystemRights.HasFlag(FileSystemRights.ReadExtendedAttributes) ||
                        rule.FileSystemRights.HasFlag(FileSystemRights.ReadPermissions)) && rule.AccessControlType == AccessControlType.Deny)
                        return false;
                    else if ((rule.FileSystemRights.HasFlag(FileSystemRights.Read) ||
                        rule.FileSystemRights.HasFlag(FileSystemRights.ReadAndExecute) ||
                        rule.FileSystemRights.HasFlag(FileSystemRights.ReadAttributes) ||
                        rule.FileSystemRights.HasFlag(FileSystemRights.ReadData) ||
                        rule.FileSystemRights.HasFlag(FileSystemRights.ReadExtendedAttributes) ||
                        rule.FileSystemRights.HasFlag(FileSystemRights.ReadPermissions)) && rule.AccessControlType == AccessControlType.Allow)
                        isAllow = true;
                }
            }
    
            return isAllow;
        }
    
        public static bool IsWriteable(this DirectoryInfo me)
        {
            AuthorizationRuleCollection rules;
            WindowsIdentity identity;
            try
            {
                rules = me.GetAccessControl().GetAccessRules(true, true, typeof(System.Security.Principal.SecurityIdentifier));
                identity = WindowsIdentity.GetCurrent();
            }
            catch (Exception ex)
            { //Posible UnauthorizedAccessException
                return false;
            }
    
            bool isAllow = false;
            string userSID = identity.User.Value;
    
            foreach (FileSystemAccessRule rule in rules)
            {
                if (rule.IdentityReference.ToString() == userSID || identity.Groups.Contains(rule.IdentityReference))
                {
                    if ((rule.FileSystemRights.HasFlag(FileSystemRights.Write) ||
                        rule.FileSystemRights.HasFlag(FileSystemRights.WriteAttributes) ||
                        rule.FileSystemRights.HasFlag(FileSystemRights.WriteData) ||
                        rule.FileSystemRights.HasFlag(FileSystemRights.WriteExtendedAttributes) ||
                        rule.FileSystemRights.HasFlag(FileSystemRights.CreateDirectories) ||
                        rule.FileSystemRights.HasFlag(FileSystemRights.CreateFiles)) && rule.AccessControlType == AccessControlType.Deny)
                        return false;
                    else if ((rule.FileSystemRights.HasFlag(FileSystemRights.Write) ||
                        rule.FileSystemRights.HasFlag(FileSystemRights.WriteAttributes) ||
                        rule.FileSystemRights.HasFlag(FileSystemRights.WriteData) ||
                        rule.FileSystemRights.HasFlag(FileSystemRights.WriteExtendedAttributes) ||
                        rule.FileSystemRights.HasFlag(FileSystemRights.CreateDirectories) ||
                        rule.FileSystemRights.HasFlag(FileSystemRights.CreateFiles)) && rule.AccessControlType == AccessControlType.Allow)
                        isAllow = true;
                }
            }
    
            return me.IsReadable() && isAllow;
        }
    
    public static bool IsReadable(this DirectoryInfo di)
    {
        AuthorizationRuleCollection rules;
        WindowsIdentity identity;
        try
        {
            rules = di.GetAccessControl().GetAccessRules(true, true, typeof(SecurityIdentifier));
            identity = WindowsIdentity.GetCurrent();
        }
        catch (UnauthorizedAccessException uae)
        {
            Debug.WriteLine(uae.ToString());
            return false;
        }
    
        bool isAllow = false;
        string userSID = identity.User.Value;
    
        foreach (FileSystemAccessRule rule in rules)
        {
            if (rule.IdentityReference.ToString() == userSID || identity.Groups.Contains(rule.IdentityReference))
            {
                if ((rule.FileSystemRights.HasFlag(FileSystemRights.Read) ||
                    rule.FileSystemRights.HasFlag(FileSystemRights.ReadAttributes) ||
                    rule.FileSystemRights.HasFlag(FileSystemRights.ReadData)) && rule.AccessControlType == AccessControlType.Deny)
                    return false;
                else if ((rule.FileSystemRights.HasFlag(FileSystemRights.Read) &&
                    rule.FileSystemRights.HasFlag(FileSystemRights.ReadAttributes) &&
                    rule.FileSystemRights.HasFlag(FileSystemRights.ReadData)) && rule.AccessControlType == AccessControlType.Allow)
                    isAllow = true;
    
            }
        }
        return isAllow;
    }
    
    public static bool IsWriteable(this DirectoryInfo me)
    {
        AuthorizationRuleCollection rules;
        WindowsIdentity identity;
        try
        {
            rules = me.GetAccessControl().GetAccessRules(true, true, typeof(System.Security.Principal.SecurityIdentifier));
            identity = WindowsIdentity.GetCurrent();
        }
        catch (UnauthorizedAccessException uae)
        {
            Debug.WriteLine(uae.ToString());
            return false;
        }
    
        bool isAllow = false;
        string userSID = identity.User.Value;
    
        foreach (FileSystemAccessRule rule in rules)
        {
            if (rule.IdentityReference.ToString() == userSID || identity.Groups.Contains(rule.IdentityReference))
            {
                if ((rule.FileSystemRights.HasFlag(FileSystemRights.Write) ||
                    rule.FileSystemRights.HasFlag(FileSystemRights.WriteAttributes) ||
                    rule.FileSystemRights.HasFlag(FileSystemRights.WriteData) ||
                    rule.FileSystemRights.HasFlag(FileSystemRights.CreateDirectories) ||
                    rule.FileSystemRights.HasFlag(FileSystemRights.CreateFiles)) && rule.AccessControlType == AccessControlType.Deny)
                    return false;
                else if ((rule.FileSystemRights.HasFlag(FileSystemRights.Write) &&
                    rule.FileSystemRights.HasFlag(FileSystemRights.WriteAttributes) &&
                    rule.FileSystemRights.HasFlag(FileSystemRights.WriteData) &&
                    rule.FileSystemRights.HasFlag(FileSystemRights.CreateDirectories) &&
                    rule.FileSystemRights.HasFlag(FileSystemRights.CreateFiles)) && rule.AccessControlType == AccessControlType.Allow)
                    isAllow = true;
    
            }
        }
        return isAllow;
    }
    
      Private Function CheckUserAccessLevel(folder As String) As Boolean
    Try
      Dim newDir As String = String.Format("{0}{1}{2}",
                                           folder,
                                           If(folder.EndsWith("\"),
                                              "",
                                              "\"),
                                           "LookWhatICanDo")
      Dim lookWhatICanDo = Directory.CreateDirectory(newDir)
    
      Directory.Delete(newDir)
      Return True
    
    Catch ex As Exception
      Return False
    End Try