File system change notifications in WinRT

October 03, 2012
Windows 8 WinRT File System C#
 

.NET framework for Windows 8 Store apps provides a subset of features included in full .NET framework profile. Microsoft excluded many APIs considered obsolete or unsafe. One of the removed classes is FileSystemWatcher, a class that proves its usefulness in applications intensively working with Windows file system. Instead, WinRT provides an alternative mechanism for folders monitoring based on queries.

Any folder can be queried to filter and enumerate files in the folder. For example the following code will return all Word documents in app’s local storage.


async void SearchFolder()
{
   var options = new Windows.Storage.Search.QueryOptions { FileTypeFilter = { ".docx" } };
   var query = ApplicationData.Current.LocalFolder.CreateFileQueryWithOptions(options);
   var files = await query.GetFilesAsync();
   
   // …
}

This is one time search that returns current state of the target folder. If continuous folder monitoring is required, app needs to be subscribed on query’s ContentsChanged event.


async void SearchFolder()
{
   var options = new Windows.Storage.Search.QueryOptions { FileTypeFilter = { ".docx" } };
   var query = ApplicationData.Current.LocalFolder.CreateFileQueryWithOptions(options);
   
   query.ContentsChanged += QueryContentsChanged; //subscription

   var files = await query.GetFilesAsync();

   // …
}

void QueryContentsChanged(Windows.Storage.Search.IStorageQueryResultBase sender, object args)
{
   // handle changes
} 

QueryContentsChanged will be called for every file system event that happens in the target folder. File type filter is not taken into account – WinRT will notify about new files of any type, new or deleted folders, etc.

At the same time, another query option – FolderDepth – affects content change notifications. E.g. for the query defined above WinRT will not send notifications for subfolders of LocalFolder. Next sample creates query that will track changes in LocalFolder and all subfolders, at any depth.


async void SearchFolder()
{
   var options = new Windows.Storage.Search.QueryOptions 
         { 
            FileTypeFilter = { ".docx" } ,
            FolderDepth = Windows.Storage.Search.FolderDepth.Deep
         };

   var query = ApplicationData.Current.LocalFolder.CreateFileQueryWithOptions(options);
   query.ContentsChanged += QueryContentsChanged;
   var files = await query.GetFilesAsync();

   // …
}

Additional details

  • GetFileAsync() needs to be called for query in order to start receiving notifications

  • Deletion and re-creation of the target folder does not invalidate query. Even more, WinRT notifies about both of these events.

  • ContentsChanged is triggered not only by creation or deletion of files or folders. Attributes change or content change for some file type trigger event as well.

  • If app is suspended, all events are recorded and notifications are fired when app is resumed.

Limitations

  • There is no way to identify reason of the event (new file, deleted folder, modified attribute, etc.)
  • args, ContentsChanged second parameter, seems to be always null. There is no information about affected items.
blog comments powered by Disqus