Virtual File System Sample for Windows in .NET, C#
This sample implements a virtual file system for Windows with synchronization support, on-demand loading, selective offline files support, upload and download progress, and error reporting. It synchronizes files and folders both from remote storage to the user file system and from the user file system to remote storage. It is written in .NET Core, C#.
Since IT Hit User File System v5.5 Beta 2 this sample supports Microsoft Office and AutoCAD documents editing and synchronization.
To simulate the remote storage, this sample is using a folder in the local file system on the same machine.
The purpose of this sample is to demonstrate the major features of the IT Hit User File System for .NET and provide patterns for its programming. You will use this sample as a starting point for creating a OneDrive-like file system for your DMS/CRM/ERP and will reprogram it to publish data from your real storage instead of the local file system. This sample provides a bare minimum code and functionality for demo purposes. For advanced features, such as thumbnails support, context menu, automatic locking and custom states/properties support see the Virtual Drive sample and WebDAV Drive sample.
- .NET 6 or later or .NET Framework 4.8.
- Microsoft Windows 10 Creators Update or later version.
- NTFS file system.
Configuring the Sample
By default, the sample will use the \RemoteStorage\ folder, located under the project root, to simulate the remote storage file structure. To specify a different folder edit the "RemoteStorageRootPath" parameter in appsettings.json. This could be either an absolute path or a path relative to the application root.
This sample mounts the user file system under the %USERPROFILE%\VFS\ folder (typically C:\Users\<username>\VFS\). To specify a different folder edit the "UserFileSystemRootPath" parameter in appsettings.json.
Setting the License
To run the example, you will need a valid IT Hit User File System Engine for .NET License. You can download the license in the product download area. Note that the Engine is fully functional with a trial license and does not have any limitations. The trial license is valid for one month and the engine will stop working after this. You can check the expiration date inside the license file. Download the license file and specify its content in the UserFileSystemLicense field in appsettings.json file. Set the license content directly as a value (NOT as a path to the license file). Do not forget to escape quotes: \":
"UserFileSystemLicense": "<?xml version=\"1.0\" encoding=\"utf-8\"?><License…
You can also run the sample without explicitly specifying a license for 5 days. In this case, the Engine will automatically request the trial license from the IT Hit website https://www.userfilesystem.com. Make sure it is accessible via firewalls if any. After 5 days the Engine will stop working. To extend the trial period you will need to download a license in a product download area and specify it in appsettings.json
Running the Sample
To run the sample open the project in Visual Studio and run the project in debug mode. In the debug mode this sample provides additional support for the development and testing convenience. When starting in the debug mode, it will automatically create a folder in which the virtual file system will reside, register the user file system with the platform and then open two instances of Windows File Manager, one of which will show a user file system and another a folder simulating remote storage:
You can start managing and editing files in the \RemoteStorage\ folder immediately after the Windows File Managers open and will see all changes being propagated to the user file system. You can also edit documents and manage file structure in the user file system and all changes will automatically appear in the remote storage folder.
This sample implements on-demand loading. After running the sample all files and folders are marked with a cloud icon , which means that the content of this file or folder is not available locally but instead resides in the remote location. Even though the file shows the correct size in the Size column, the file occupies zero bytes on the disk. You can open the file Properties dialog to check the "Size on disk" value. You can see in the console log that only root folder files and folder placeholders are being created when Windows File Manager listed the root folder content. Folders located deeper in the hierarchy are not loaded until their content is being requested by the platform file system calls.
When any application is accessing the file, located under the \VFS\ folder, opening it for reading or writing, the operating system redirects the call to this sample, which loads file content from the remote storage folder. The file becomes marked with a green check-mark on a white background icon, which means the file content is present on the local disk:
The Windows File Manager provides the "Always keep on this device" and "Free up space" context menus, which are standard menus provided by Windows OS. If you select the "Always keep on this device" the file or entire folder structure will be recursively loaded to the local disk and files content will be loaded to the local disk and will become available offline. All files and folders are marked with a pinned file icon. Pinned files will not be deleted from the drive even if it runs low on space.
To remove content from the local disk select the "Free up space" menu. It will restore the cloud icon .
When a large file is being downloaded from the remote storage, this sample submits progress reports to the operation system, to show a standard Windows "Downloading" dialog. At the same time, the Windows File Manager also shows progress in the files list view:
For debugging and development purposes this sample provides the following console commands:
- 'Esc' - simulates app uninstall. The sync root will be unregistered and all files will be deleted.
- 'Space' - simulates machine reboot or application failure. The application exits without unregistering the sync root. All files and folders placeholders, their attributes, and states remain in the user file system.
- 'e' - starts/stops the Engine and all sync services. When the Engine is stopped, the user can still edit hydrated documents but can not hydrate files, access offline folders, or sync with remote storage.
- 's' - to start/stop synchronization service.
- 'm' - starts/stops remote storage monitor. When the remote storage monitor is stopped the sample does not receive notifications from the remote storage.
- 'd' - enable/disable debug and performance logging.
- 'l' - opens a log file.
- 'b' - opens Help & Support portal to submit support tickets, report bugs, suggest features.
Microsoft Office and AutoCAD Files Editing Support
This sample supports editing and synchronization of the MS Office/AutoCAD documents.
Any temporary Microsoft Office and AutoCAD documents (~$docfile.docx, G57BURP.tmp, etc) are stored in the local file system only and are NOT synchronized to the server. Temporary Microsoft Office/AutoCAD documents are being automatically deleted by Microsoft Office/AutoCAD when the document is close.
How the Sample Works
Initially, when you start the application, the user file system does not contain any file or folder placeholders, except the sync root folder. The content of the folders is populated only when any application is listing folder content. The content of files is loaded only when an application is opening a file for reading or writing.
Platform File System Operations Handling
Folder content listing, file reads, move/rename and delete are performed by the VirtualEngine , VirtualFile and VirtuaFolder classes.
The initial folder content listing is done inside VirtualFolder.GetChildrenAsync() method call. When any application is listing folder content, the VirtualEngine class creates the VirtualFolder class instance that corresponds to the requested folder inside the VirtualEngine.GetFileSystemItemAsync() factory method. Then the VirtualEngine class calls GetChildrenAsync() method on the returned folder item.
As soon as the folder content is populated with placeholders during the first access, the GetChildrenAsync() is never called again for this particular folder. Instead, to update the folder content, this sample monitors changes in the remote storage and applies them to the user file system. See the "Remote Storage to User File System Synchronization" section below.
Hydration/Dehydration via Windows File Manager Commands
When the user selects "Always keep on this device" or the "Free up space" in the Windows file manager, the file is marked with a Pinned or Unpinned attribute respectively. The Engine detects these flags triggering hydration or dehydration if needed. To hydrate the file the VirtualFile.ReadAsync() method is called.
Remote Storage to User File System Synchronization
The remote storage is simulated by the dedicated folder in the file system (\RemoteStorage\ by default). The sample monitors changes in it using RemoteStorageMonitor class that generates events and applies corresponding changes in the user file system. The RemoteStorageMonitor class is using a FileSystemWatcherQueued class which is similar to FileSystemWatcher which can monitor the creation, update of file content and attributes, deletion, and rename. But unlike the FileSystemWatcher, the FileSystemWatcherQueued class can process a large number of events and is tested on the highly loaded file system.
Note that the FileSystemWatcherQueued class (as well as FileSystemWatcher class) can NOT monitor the move event. In your real-life application, you will replace the FileSystemWatcherQueued class with web sockets or any other technology that will send events from your server to all connected clients.
User File System to Remote Storage Synchronization
The user file system to remote storage synchronization is performed by VirtualFile and VirtualFolder classes. When a file or folder is created in the file system, the VirtualFolder.CreateFileAsync() and VirtualFolder.CreateFolderAsync() methods are called. When the file content is modified on the client the VirtualFile.WriteAsync() method is called. When a file or folder is moved or deleted the VfsFileSystemItem.MoveToAsync()/MoveToCompletionAsync() and VfsFileSystemItem.DeleteAsync()/DeleteCompletion() methods are called.
Synchronization after Application Restart
When your application is not running and a user modifies any documents or creates, deletes or moves any files or folders on the drive, this sample will automatically find all changes and will sync them to the server. See this paragraph for more details.