91

Let say, a file has the following attributes: ReadOnly, Hidden, Archived, System. How can I remove only one Attribute? (for example ReadOnly)

If I use the following, it removes all the attributes:

IO.File.SetAttributes("File.txt",IO.FileAttributes.Normal)
Kuzon
  • 782
  • 5
  • 20
  • 49
MilMike
  • 12,571
  • 15
  • 65
  • 82

8 Answers8

145

Answering on your question in title regarding ReadOnly attribute:

FileInfo fileInfo = new FileInfo(pathToAFile);
fileInfo.IsReadOnly = false;

To get control over any attribute yourself you can use File.SetAttributes() method. The link also provides an example.

Kobi
  • 135,331
  • 41
  • 252
  • 292
sll
  • 61,540
  • 22
  • 104
  • 156
  • 1
    this works great! but only for ReadOnly Attribute, (I know i asked for it in the title but I also need other attributes) – MilMike Sep 13 '11 at 11:46
  • 1
    @qxxx: you are right, as I mentioned you have to use SetAttributes() method to modify another attributes – sll Sep 13 '11 at 12:00
  • 4
    As a one-liner: new FileInfo(fileName) {IsReadOnly = false}.Refresh() – Ohad Schneider Aug 19 '13 at 16:36
  • 2
    Is Refresh() necessary? [This example on MSDN](http://msdn.microsoft.com/en-us/library/system.io.fileinfo.isreadonly(v=vs.110).aspx) suggests it isn't, and my code (admittedly with Mono) works if I don't call it. – entheh Dec 10 '13 at 20:03
  • 1
    Refresh() seems not necessary for me either. – Jerther Nov 13 '14 at 16:07
  • 1
    You don't need `Refresh` here. [`IsReadOnly` is setting `Attributes`](http://referencesource.microsoft.com/#mscorlib/system/io/fileinfo.cs,37ee700f18773394), and [setting `Attributes` triggers the file system change](http://referencesource.microsoft.com/#mscorlib/system/io/filesysteminfo.cs,397d905785886f44). The state of the `FileInfo` should be up to date, so `Refresh` is redundant, so I'll go ahead and remove it, if nobody minds. – Kobi Jan 29 '15 at 11:29
113

From MSDN: You can remove any attribute like this

(but @sll's answer for just ReadOnly is better for just that attribute)

using System;
using System.IO;
using System.Text;
class Test 
{
    public static void Main() 
    {
        string path = @"c:\temp\MyTest.txt";

        // Create the file if it exists.
        if (!File.Exists(path)) 
        {
            File.Create(path);
        }

        FileAttributes attributes = File.GetAttributes(path);

        if ((attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
        {
            // Make the file RW
            attributes = RemoveAttribute(attributes, FileAttributes.ReadOnly);
            File.SetAttributes(path, attributes);
            Console.WriteLine("The {0} file is no longer RO.", path);
        } 
        else 
        {
            // Make the file RO
            File.SetAttributes(path, File.GetAttributes(path) | FileAttributes.Hidden);
            Console.WriteLine("The {0} file is now RO.", path);
        }
    }

    private static FileAttributes RemoveAttribute(FileAttributes attributes, FileAttributes attributesToRemove)
    {
        return attributes & ~attributesToRemove;
    }
}
Preet Sangha
  • 64,563
  • 18
  • 145
  • 216
14
string file = "file.txt";
FileAttributes attrs = File.GetAttributes(file);
if (attrs.HasFlag(FileAttributes.ReadOnly))
    File.SetAttributes(file, attrs & ~FileAttributes.ReadOnly);
Rubens Farias
  • 57,174
  • 8
  • 131
  • 162
3
if ((oFileInfo.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
    oFileInfo.Attributes ^= FileAttributes.ReadOnly;
T.S.
  • 18,195
  • 11
  • 58
  • 78
alternatefaraz
  • 374
  • 1
  • 5
  • 18
1
/// <summary>
/// Addes the given FileAttributes to the given File.
/// It's possible to combine FileAttributes: FileAttributes.Hidden | FileAttributes.ReadOnly
/// </summary>
public static void AttributesSet(this FileInfo pFile, FileAttributes pAttributes)
{
    pFile.Attributes = pFile.Attributes | pAttributes;
    pFile.Refresh();
}

/// <summary>
/// Removes the given FileAttributes from the given File.
/// It's possible to combine FileAttributes: FileAttributes.Hidden | FileAttributes.ReadOnly
/// </summary>
public static void AttributesRemove(this FileInfo pFile, FileAttributes pAttributes)
{
    pFile.Attributes = pFile.Attributes & ~pAttributes;
    pFile.Refresh();
}

/// <summary>
/// Checks the given File on the given Attributes.
/// It's possible to combine FileAttributes: FileAttributes.Hidden | FileAttributes.ReadOnly
/// </summary>
/// <returns>True if any Attribute is set, False if non is set</returns>
public static bool AttributesIsAnySet(this FileInfo pFile, FileAttributes pAttributes)
{
    return ((pFile.Attributes & pAttributes) > 0);
}

/// <summary>
/// Checks the given File on the given Attributes.
/// It's possible to combine FileAttributes: FileAttributes.Hidden | FileAttributes.ReadOnly
/// </summary>
/// <returns>True if all Attributes are set, False if any is not set</returns>
public static bool AttributesIsSet(this FileInfo pFile, FileAttributes pAttributes)
{
    return (pAttributes == (pFile.Attributes & pAttributes));
}

Example:

private static void Test()
{
    var lFileInfo = new FileInfo(@"C:\Neues Textdokument.txt");
    lFileInfo.AttributesSet(FileAttributes.Hidden | FileAttributes.ReadOnly);
    lFileInfo.AttributesSet(FileAttributes.Temporary);
    var lBool1 = lFileInfo.AttributesIsSet(FileAttributes.Hidden);
    var lBool2 = lFileInfo.AttributesIsSet(FileAttributes.Temporary);
    var lBool3 = lFileInfo.AttributesIsSet(FileAttributes.Encrypted);
    var lBool4 = lFileInfo.AttributesIsSet(FileAttributes.ReadOnly | FileAttributes.Temporary);
    var lBool5 = lFileInfo.AttributesIsSet(FileAttributes.ReadOnly | FileAttributes.Encrypted);
    var lBool6 = lFileInfo.AttributesIsAnySet(FileAttributes.ReadOnly | FileAttributes.Temporary);
    var lBool7 = lFileInfo.AttributesIsAnySet(FileAttributes.ReadOnly | FileAttributes.Encrypted);
    var lBool8 = lFileInfo.AttributesIsAnySet(FileAttributes.Encrypted);
    lFileInfo.AttributesRemove(FileAttributes.Temporary);
    lFileInfo.AttributesRemove(FileAttributes.Hidden | FileAttributes.ReadOnly);
}
user2029101
  • 116
  • 9
1

Lots of code in these examples, if you want a simple solution(without Shell):

File.SetAttributes(filepath, ~FileAttributes.ReadOnly & File.GetAttributes(filepath));
AEM
  • 1,354
  • 8
  • 20
  • 30
spinlock
  • 17
  • 3
1

For a one line solution (provided that the current user has access to change the attributes of the mentioned file) here is how I would do it:

VB.Net

Shell("attrib file.txt -r")

the negative sign means to remove and the r is for read-only. if you want to remove other attributes as well you would do:

Shell("attrib file.txt -r -s -h -a")

That will remove the Read-Only, System-File, Hidden and Archive attributes.

if you want to give back these attributes, here is how:

Shell("attrib file.txt +r +s +h +a")

the order does not matter.

C#

Process.Start("cmd.exe", "attrib file.txt +r +s +h +a");

References

George Stocker
  • 57,289
  • 29
  • 176
  • 237
Ahmad
  • 12,336
  • 6
  • 48
  • 88
  • These are not major content *changes*, they're content additions, and none of them run counter to the spirit of Stack Overflow. They're good edits, they should stay. – George Stocker Jul 31 '14 at 20:09
  • 4
    This seems like the equivalent of asking where to add a quart of oil to your car but being told you should take it to your dealership for an oil change. Why execute a shell command just to flip a file attribute bit? The answer technically works so I didn't downvote, but I did in my heart. – JMD Sep 04 '14 at 15:28
  • @GeorgeStocker Thanks for reviewing it, I appreciate that! – tehDorf Dec 06 '14 at 01:47
0

Use this:

private static FileAttributes RemoveAttribute(FileAttributes attributes, FileAttributes attributesToRemove)

Read detail here in MSDN: http://msdn.microsoft.com/en-us/library/system.io.file.setattributes.aspx

Kangkan
  • 15,267
  • 10
  • 70
  • 113