UPDATE: showing code that actually works.

As a prelude to a series I’m hoping to do on file queries and file information, I just wanted to share a little snippet for making a file read-only. Although you can retrieve the current status through the StorageFile.Attributes property, it just returns an enumeration rather than a property set you can manipulate.

Changing attributes instead has to go through the StorageFile.properties property, which is a StorageItemContentProperties object. Its savePropertiesAsync method is the one you want. For this you need to create a Windows.Foundation.Collections.PropertySet object (see this previous post), populate it with the properties you need, then call savePropertiesAsync.

The specific property you need to set is “System.FileAttributes” with the value FILE_ATTRIBUTE_READONLY, which is just 1 as described for the Win32 SetFileAttributes function. The code looks like this, where I’m just working with a test.jpg in the pictures library to demonstrate:

JavaScript (you can add a completed handler if you need to take other action after savePropertiesAsync):

var key = "System.FileAttributes";
var FILE_ATTRIBUTES_READONLY = 1;
var file;
var pix = Windows.Storage.KnownFolders.picturesLibrary;
pix.getFileAsync("test.jpg").then(function (fileTemp) {
    file = fileTemp;
    return file.properties.retrievePropertiesAsync([key]);
}).done(function (props) {                
    if (props) {                    
        props[key] |= FILE_ATTRIBUTES_READONLY;
    } else {
        props = new Windows.Foundation.Collections.PropertySet();
        props.insert(key, FILE_ATTRIBUTES_READONLY);                    
    }

    file.properties.savePropertiesAsync(props);
});

 

C#:

String key = "System.FileAttributes";
UInt32 FILE_ATTRIBUTES_READONLY = 1;
var pix = Windows.Storage.KnownFolders.PicturesLibrary;

var file = await pix.GetFileAsync("test.jpg");                                
String [] retrieveList = new String [] { key };

var props = await file.Properties.RetrievePropertiesAsync(retrieveList);

if (props != null) {
    var temp = (UInt32)props[key] | FILE_ATTRIBUTES_READONLY;
    props[key] = temp;
} else {
    props = new Windows.Foundation.Collections.PropertySet();                
    props.Add(key, FILE_ATTRIBUTES_READONLY);                    
}

await file.Properties.SavePropertiesAsync(props);

2 Comments

  1. Doug
    Posted September 5, 2013 at 8:01 pm | Permalink

    FILE_ATTRIBUTE_READONLY is not recognized in the c# version. And assuming file.Properties is actually storageFile.Properties – Properties cannot be resolved. Is this meant to work in C# windows store apps? if not, do you know how to do it in store apps?

    • Posted September 12, 2013 at 10:24 pm | Permalink

      Yeah, the code is wrong here (corrected)–the FILE_ATTRIBUTE_READONLY value is 1 as noted.