Pergunta

Eu percorrer um monte de diretórios de forma recursiva. Alguns deles (como D: \ $ RECYCLE.BIN \ S-1-5-20 ) me dê um System.UnauthorizedAccessException. Suponho que posso apenas pegá-lo e seguir em frente, mas eu preferiria descobrir isso com antecedência.

Então, quando eu tenho um objeto DirectoryInfo. Como posso ver se eu estou autorizado a GetDirectories() e possivelmente Delete()-lo?

Foi útil?

Solução

Se você pretende excluí-lo, tente apagá-lo e, em seguida, proceder (manipulação de exceção conforme o caso).

Se você executar um check-e-depois-delete se-deve ser-capaz-to-delete existe a chance de uma condição de corrida no sistema de arquivos, no entanto ligeira. Isto aplica-se à maioria das todas as operações de acesso a arquivos / diretórios. A maioria das operações do sistema de arquivos são projetados para ser atômica e movendo-se esta lógica em código de utilizador em conflito esta atomicidade e seria ainda necessidade de lidar com uma possível exceção sendo levantados.

Outras dicas

Eu construí seguinte código. Por favor, ver se isso ajuda:

//using System.IO;
//using System.Security.AccessControl;
//using System.Security.Principal;

string[] directories = Directory.GetDirectories(
    Path.Combine(Environment.CurrentDirectory, @"..\.."), 
    "*", SearchOption.AllDirectories);
foreach (string directory in directories)
{
    DirectoryInfo info = new DirectoryInfo(directory);
    DirectorySecurity security = info.GetAccessControl();
    Console.WriteLine(info.FullName);
    foreach (FileSystemAccessRule rule in 
             security.GetAccessRules(true, true, typeof(NTAccount)))
    {
        Console.WriteLine("\tIdentityReference = {0}", rule.IdentityReference);
        Console.WriteLine("\tInheritanceFlags  = {0}", rule.InheritanceFlags );
        Console.WriteLine("\tPropagationFlags  = {0}", rule.PropagationFlags );
        Console.WriteLine("\tAccessControlType = {0}", rule.AccessControlType);
        Console.WriteLine("\tFileSystemRights  = {0}", rule.FileSystemRights );
        Console.WriteLine();
    }
}

Resultado:

D:\Projects\ConsoleApplication1\bin
    IdentityReference = BUILTIN\Administrators
    InheritanceFlags  = ContainerInherit, ObjectInherit
    PropagationFlags  = None
    AccessControlType = Allow
    FileSystemRights  = FullControl

Note que IdentityReference e FileSystemRights propriedades; provavelmente deve testar o ACL atual contra eles antes de tentar excluir um diretório.

Eu acredito que você terá que escrever o seu próprio método GetDirectories(); que recursivly recebe os dentro do mesmo.

Esta Microsoft artigo tem um bom artigo sobre como fazê-lo, com um pouco de funcionar, você pode limpá-lo de usar listas genéricas e torná-lo apto a sua solução.

Simplificando, System.IO.Directory.GetDirectories () irá falhar cada vez que recebe uma dessas excepções.

código mais ou menos assim (copiado de cima) deve começar

    List<String> directories = new List<String>();
    void DirSearch(string sDir) 
    {
        try 
        {
            foreach (string d in Directory.GetDirectories(sDir)) 
            {
                //foreach (string f in Directory.GetFiles(d, txtFile.Text)) 
                //{
                //    
                //}
                // use this to search for files recursivly.
                directories.Add(d);
                DirSearch(d);
            }
        }
        catch (System.Exception excpt) 
        {
            Console.WriteLine(excpt.Message);
        }
    }

Depois de ter sua lista de diretórios, então você pode executar operações sobre eles, com alguns mods o método acima deve garantir que você tenha permissões de leitura em qualquer coisa na lista.

Eu encontrei este ao tentar resolver o problema ...

Parece relacionado, mas o código muito unmaintained, eu não experimentá-lo

http: //technolog.nl/blogs/eprogrammer/archive/2009/06/18/Howto_3A00_-Properly-use-the-AccessCheck-API.aspx

relação

Mario

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top