1

I am working on an UWP text editor. I have added desktop extension to it to modify system files and other read only files. The problem I have is there is no reliable way to detect if a file has read-only attribute. FileInfo.IsReadOnly doesn't work and StorageFile.Attributes has FileAttributes.ReadOnly when file is dragged and dropped from file explorer.

How do I reliably check whether the file has read only flag or not?

File with Read-only attribute

Soumya Mahunt
  • 2,148
  • 12
  • 30
  • You mentioned `FileInfo.IsReadOnly` does not work, does it throw an error? What if your call the API from the desktop extension instead? – Martin Zikmund Jun 27 '20 at 22:06
  • Callining `FileInfo.IsReadOnly` throws error in uwp app. Yes I can call the desktop extension for this. But this slows down the whole process of saving file. – Soumya Mahunt Jun 27 '20 at 22:42
  • Just to understand, what is the scenario where `StorageFile.Attributes` does not correctly report `ReadOnly`? – Martin Zikmund Jun 28 '20 at 06:29
  • If file was drag and dropped from file-explorer, then `StorageFile.Attributes` reports `ReadOnly` even if the file itself doesn't have Read-only checked. – Soumya Mahunt Jun 28 '20 at 06:33
  • I have added an answer to detect readonly attribute. – Soumya Mahunt Aug 02 '20 at 04:01

3 Answers3

1

While there is no way to detect the readonly attribute by using dotnet methods, however GetFileAttributesExFromApp can be used to get a lot of attributes(readonly, hidden etc.) of the file that aren't available via StorageFile api. Also, SetFileAttributesFromApp can be used to change/remove these attributes.

Edit

After some research and deep dive in MSDN, I came to know about RetrievePropertiesAsync(IEnumerable<String>) and SavePropertiesAsync(IEnumerable<KeyValuePair<String,Object>>) methods for Windows.Storage.FileProperties.StorageItemContentProperties which can be used to get and set properties by name (Full list of properties names), the name System.FileAttributes can be used to get file attributes and can be used to detect if read-only flag is present. While retrieving properties always works modifying properties will only work if app has write access to file (Windows.Storage.StorageFile.Attributes doesn't contain ReadOnly flag), although SetFileAttributesFromApp works for that scenario but limitation of SetFileAttributesFromApp is it won't work for sensitive file types (.bat, .cmd etc.). So both those methods could be used combined to have maximum effect.

Soumya Mahunt
  • 2,148
  • 12
  • 30
  • 1
    @A.Caillet I can confirm this works. If you want an example check [this](https://github.com/JasonStein/Notepads/pull/636) PR in which I implemented checking read-only flag and changing read-only flag in UWP app [Notepads](https://github.com/JasonStein/Notepads). If you specifically want to know how you call these funcions check [this](https://github.com/JasonStein/Notepads/pull/636/files#diff-949c1c37e9cf816cfb2d43ad54e6e401) file. – Soumya Mahunt Sep 16 '20 at 11:11
-1

You can see the Attributes property has ReadOnly or not.

    var filePicker = new Windows.Storage.Pickers.FileOpenPicker();
    filePicker.ViewMode = Windows.Storage.Pickers.PickerViewMode.Thumbnail;
    filePicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.VideosLibrary;
    foreach (string format in HelperUP.subtitlesFormat)
        filePicker.FileTypeFilter.Add(format);
    var file = await filePicker.PickSingleFileAsync();
    if (file == null)
        return;

    Debug.WriteLine(file.Attributes);

F

Vincent
  • 3,124
  • 3
  • 21
  • 40
  • I have mentioned in my question that my app supports drag and drop functionality and for files that are drag and dropped `StorageFile.Attributes` returns `FileAttributes.ReadOnly` too. – Soumya Mahunt Jun 28 '20 at 05:21
  • For the files you drag-drop, it's always read-only. This is by design. – Vincent Jun 28 '20 at 06:45
  • See this issue, https://github.com/microsoft/microsoft-ui-xaml/issues/2421 – Vincent Jun 28 '20 at 06:46
  • I have seen the issue you linked and I know the drag and drop files are read-only (and I know workaround to bypass that in uwp using `Windows.Storage.PathIO`). My question is to detect whether the Read-only flag is enabled in file properties. – Soumya Mahunt Jun 28 '20 at 07:49
  • I have added an answer to detect readonly attribute. – Soumya Mahunt Aug 02 '20 at 04:01
-1

The reason FileAttributes.ReadOnly throws an exception is that the System.IO APIs don't have access to arbitrary file locations on the hard drive in UWP.

On the other hand, a StorageFile opened in the app via drag & drop has this attribute set too, which is a problem that is continuously being discussed and hopefully will be fixed in a future version.

The only workaround I can think of (apart from always using the desktop extension) is declaring the broadFileSystemAccess capability (I have described the process here for example). This is a capability which gives you access to the whole filesystem and allows you to get a file using an arbitrary path with the StorageFile.GetFileFromPathAsync method (see Docs). Please note you will need to explain why this capability is required when you submit the application to the Microsoft Store.

With broad filesystem access, you could take the drag & drop StorageFile, take its Path and retrieve the same file again using StorageFile.GetFileFromPathAsync. This new copy of the file will no longer have the "false-positive" Read Only attribute and will reflect the actual attribute state from the filesystem.

Martin Zikmund
  • 38,440
  • 7
  • 70
  • 91
  • So there is no way in uwp to detect if readonly flag is enabled for a file?? Also you don't need `broadFileSystemAccess` to write to file that has been dragged-dropped from explorer (seems overkill and unreliable to me). I have posted a way [here](https://stackoverflow.com/questions/62638922/write-to-file-in-uwp-that-has-been-drag-dropped-from-explorer/62638923#62638923) using a workaround with `PathIO` api. – Soumya Mahunt Jun 29 '20 at 13:17