2010-10-05 11 views
15

yo era capaz de eliminar con éxito atributo de sólo lectura en un archivo con el siguiente fragmento de código:Extracción atributo de sólo lectura en un directorio usando C#

En main.cs

FileSystemInfo[] sqlParentFileSystemInfo = dirInfo.GetFileSystemInfos(); 

foreach (var childFolderOrFile in sqlParentFileSystemInfo) 
{ 
    RemoveReadOnlyFlag(childFolderOrFile); 
} 

private static void RemoveReadOnlyFlag(FileSystemInfo fileSystemInfo) 
{ 
    fileSystemInfo.Attributes = FileAttributes.Normal; 
    var di = fileSystemInfo as DirectoryInfo; 

    if (di != null) 
    { 
     foreach (var dirInfo in di.GetFileSystemInfos()) 
      RemoveReadOnlyFlag(dirInfo); 
    } 
} 

Por desgracia, este doesn' t trabajo en las carpetas. Después de ejecutar el código, cuando voy a la carpeta, haga clic y hacer propiedades bien, esto es lo que veo:

alt text

La única bandera leer todavía está marcada a pesar de que lo sacó de los archivos por debajo de ella. Esto hace que un proceso falle al eliminar esta carpeta. Cuando elimino manualmente el indicador y vuelvo a ejecutar el proceso (un archivo bat), puedo eliminar el archivo (así sé que esto no es un problema con el archivo bat)

¿Cómo elimino este marcador en C#?

Respuesta

8

También podría hacer algo como lo siguiente sólo lectura a recursiva clara (y archivo, etc.) para todos los directorios y archivos dentro de un directorio especificado:

private void ClearReadOnly(DirectoryInfo parentDirectory) 
{ 
    if(parentDirectory != null) 
    { 
     parentDirectory.Attributes = FileAttributes.Normal; 
     foreach (FileInfo fi in parentDirectory.GetFiles()) 
     { 
      fi.Attributes = FileAttributes.Normal; 
     } 
     foreach (DirectoryInfo di in parentDirectory.GetDirectories()) 
     { 
      ClearReadOnly(di); 
     } 
    } 
} 

Por lo tanto, puede llamar a este modo:

public void Main() 
{ 
    DirectoryInfo parentDirectoryInfo = new DirectoryInfo(@"c:\test"); 
    ClearReadOnly(parentDirectoryInfo); 
} 
6

Trate DirectoryInfo en lugar de FileInfo

DirectoryInfo di = new DirectoryInfo(@"c:\temp\content"); 
di.Attributes = FileAttributes.Normal; 

Para limpiar attrbutes en Files-

foreach (string fileName in System.IO.Directory.GetFiles(@"c:\temp\content")) 
{ 
    System.IO.FileInfo fileInfo = new System.IO.FileInfo(fileName); 
    fileInfo.Attributes = FileAttributes.Normal; 
} 
+0

Esto no parece estar funcionando en el directorio. Aún veo los atributos con solo set de lectura. – DotnetDude

1

Establecer la propiedad Attributes en el original dirInfo:

dirInfo.Attributes = FileAttributes.Normal; 

FileSystemInfo[] sqlParentFileSystemInfo = dirInfo.GetFileSystemInfos(); 

foreach (var childFolderOrFile in sqlParentFileSystemInfo) 
{ 
    RemoveReadOnlyFlag(childFolderOrFile); 
} 
+0

No funciona. Todavía se ven los atributos con el indicador de solo lectura en el estado 'intdeterminado' – DotnetDude

3

El diálogo simplemente funciona de una manera bastante extraña. Siempre muestra la forma en que lo ve en la captura de pantalla, sea cual sea el estado del atributo ReadOnly. La casilla de verificación está en el estado 'indeterminado'. Tienes que hacer clic en él y borrarlo o marcarlo para que realice su acción. Y a pesar del texto rápido (pero no la sugerencia al lado de la casilla de verificación), solo cambia el atributo ReadOnly en los archivos en el directorio, no en el directorio en sí.

Utilice el comando de línea de comando attrib para ver qué está pasando realmente. Con toda probabilidad, su código falla porque el directorio contiene archivos que tienen su conjunto de atributos ReadOnly. Tendrás que iterarlos.

0

Veo que @DotnetDude dijo en comentarios que las soluciones de los chicos no funcionan. En mi opinión, sucede porque los chicos no mencionaron que es necesario usar el método File.SetAttributes para aplicar nuevos atributos.

-1
Shell("net share sharefolder=c:\sharefolder/GRANT:Everyone,FULL") 


Shell("net share sharefolder= c:\sharefolder/G:Everyone:F /SPEC B") 


Shell("Icacls C:\sharefolder/grant Everyone:F /inheritance:e /T") 


Shell("attrib -r +s C:\\sharefolder\*.* /s /d", AppWinStyle.Hide) 

este código está trabajando para mí .. para compartir una carpeta para cada uno con el permiso de lectura y escritura

+0

¿Hay algún código fuente completo sobre la clase Shell? – Kiquenet

+0

@Kiquenet, 'Shell' no es una clase; es una función de VB.NET. En C#, puede usar Process.Start() para un comportamiento similar (es decir, iniciar otro proceso). Busque la documentación de las clases 'Process' y' ProcessStartInfo' para obtener más información. Con el único propósito de desactivar la propiedad de solo lectura, como era la pregunta original, recomendaría utilizar la respuesta de Mark Avenius, en lugar de comenzar un nuevo proceso. – reirab

1

Sólo en caso de cualquiera que pasa a través de esta tarde ...

TODO el otras respuestas publicadas antes de la mía son incorrectas o usan recursión innecesaria.

En primer lugar, la casilla de verificación "Solo lectura" en el cuadro de diálogo de propiedad de windows siempre tiene el marcador de tres estados para las carpetas. Esto se debe a que la carpeta en sí misma no es solo de lectura, sino que puede ser dentro de los archivos.

Si desea establecer/desactivar la bandera de solo lectura para TODOS los archivos. puede hacerlo simplemente de la siguiente manera:

void SetReadOnlyFlagForAllFiles(DirectoryInfo directory, bool isReadOnly) 
{ 
    // Iterate over ALL files using "*" wildcard and choosing to search all directories. 
    foreach(FileInfo File in directory.GetFiles("*", SearchOption.All.Directories)) 
    { 
     // Set flag. 
     File.IsReadOnly = isReadOnly; 
    } 
} 
+0

¿Y qué hace cuando el directorio es de solo lectura por lo que no puede agregar/eliminar archivos del directorio? Eso es lo que el OP preguntó. – Dunk

+0

@Dunk No es lo que se preguntó. Y todavía tiene una extraña idea de que un "Directorio" tiene un atributo de solo lectura ... no es así. ¿Has probado alguno de los códigos? El código OP realmente funciona, pero solo porque puede convertir DirectoryInfo en FileInfo. Lo que realmente hace es simplemente establecer el atributo en todos los archivos, pruébelo usted mismo. Un directorio no puede establecerse en FileAttibutes.Normal o .ReadOnly siempre es .Directory. Como dije, el explorador SIEMPRE muestra el estado intermedio para los directorios. Además, un archivo BAT puede eliminar el directorio "Solo lectura" de cualquier forma, por lo que es más probable que se cierre algo más en su PC. –

1

solución IEnumerable/Lambda de forma recursiva para la eliminación de sólo lectura atributo de directorios y archivos:

new DirectoryInfo(@"some\test\path").GetDirectories("*", SearchOption.AllDirectories).ToList().ForEach(
    di => { 
     di.Attributes &= ~FileAttributes.ReadOnly; 
     di.GetFiles("*", SearchOption.TopDirectoryOnly).ToList().ForEach(fi => fi.IsReadOnly = false); 
    } 
); 
2

La bandera de sólo lectura en los directorios de Windows es en realidad un nombre inapropiado. La carpeta no usa el indicador de solo lectura. El problema va a ser con la personalización. Windows usa la marca para identificar que hay personalizaciones en la carpeta.

Esta es una publicación anterior, con un problema que está oscureciendo, pero, pensé que la gente todavía podría toparse con ella, ya que es bastante molesto cuando la golpeas.

Microsoft's Explanation

+0

estás en modo correcto. – STLDeveloper

0

Esto puede o no puede estar directamente relacionado, pero el problema radica en su caso puede ser causado por los archivos subyacentes. Por ejemplo, me encontré con este problema tratando de eliminar un directorio:

System.IO.Directory.Delete(someDirectory, true) 

Esto se traduce en "Acceso a la 'bla' ruta denegado". Para resolver este problema subyacente, eliminé el atributo de solo lectura en subarchivos y luego pude eliminar el directorio principal. En mi caso, estaba usando powershell, por lo que puede usar el equivalente de .NET.

dir -r $PrePackageDirectory |% {if ($_.PSIsContainer -ne $true){$_.IsReadOnly = $false}} 
Cuestiones relacionadas