Skip to content

Commit f887443

Browse files
committed
v1.3.4102.0
1 parent 8576762 commit f887443

25 files changed

+788
-187
lines changed

VirtualFileSystem/Framework/Syncronyzation/UserFileSystemMonitor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ internal class UserFileSystemMonitor : Logger, IDisposable
3232
private FileSystemWatcher watcher = new FileSystemWatcher();
3333

3434
/// <summary>
35-
/// User file system root path. Folder to minitor changes in.
35+
/// User file system root path. Folder to monitor for changes.
3636
/// </summary>
3737
private string userFileSystemRootPath;
3838

VirtualFileSystem/Framework/VfsFile.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
using System.Threading;
88
using System.Threading.Tasks;
99
using VirtualFileSystem.Syncronyzation;
10-
using Windows.UI.Xaml;
1110

1211
namespace VirtualFileSystem
1312
{

VirtualFileSystem/Program.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,9 @@ static async Task<int> Main(string[] args)
5959
XmlConfigurator.Configure(logRepository, new FileInfo("log4net.config"));
6060

6161
log.Info($"\n{System.Diagnostics.Process.GetCurrentProcess().ProcessName}");
62-
log.Info("\nPress any other key to exit without unregistering (simulate reboot).");
63-
log.Info("\nPress 'q' to unregister file system and exit (simulate uninstall).");
6462
log.Info("\nPress 'Q' to unregister file system, delete all files/folders and exit (simulate uninstall with full cleanup).");
63+
log.Info("\nPress 'q' to unregister file system and exit (simulate uninstall).");
64+
log.Info("\nPress any other key to exit without unregistering (simulate reboot).");
6565
log.Info("\n----------------------\n");
6666

6767
// Typically you will register sync root during your application installation.
@@ -70,7 +70,7 @@ static async Task<int> Main(string[] args)
7070
{
7171
Directory.CreateDirectory(Settings.UserFileSystemRootPath);
7272
log.Info($"\nRegistering {Settings.UserFileSystemRootPath} sync root.");
73-
await Registrar.RegisterAsync(SyncRootId, Settings.UserFileSystemRootPath, "My Virtual File System");
73+
await Registrar.RegisterAsync(SyncRootId, Settings.UserFileSystemRootPath, Settings.ProductName);
7474
}
7575
else
7676
{

VirtualFileSystem/README.md

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
<p>To run the sample open the project in Visual Studio and run the project in a debug mode.&nbsp;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&nbsp;two instances of Windows File Manager, one of which will show a user file system and another a folder simulating remote storage:</p>
2222
<p>&nbsp;<img id="__mcenew" alt="Virtual File System Sample Initial Run" src="https://www.userfilesystem.com/media/1985/virtualfilesysteminitialrun.png" rel="116795"></p>
2323
<p>You can start managing and editing files in the <span class="code">\RemoteStorage\</span> 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.</p>
24-
<p>This sample implements on-demand loading. After running the sample all files and folders are marked with a cloud icon<img id="__mcenew" alt="Offline File" src="https://www.userfilesystem.com/media/1988/offilefile.png" rel="116798" data-allowlink="false">, 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 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 folders placeholders are being created when Windows File Manager listed the root folder content. Folders located deeper in the hierarchy is not loaded, until their content is being requested by platform file system calls.&nbsp;</p>
24+
<p>This sample implements on-demand loading. After running the sample all files and folders are marked with a cloud icon<img id="__mcenew" alt="Offline File" src="https://www.userfilesystem.com/media/1988/offilefile.png" rel="116798" data-allowlink="false">, 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 folders 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.&nbsp;</p>
2525
<p>When any application is accessing the file, located under the <span class="code">\VFS\</span> 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<img id="__mcenew" alt="Local File" src="https://www.userfilesystem.com/media/1986/localfile.png" rel="116799" data-allowlink="false">, which means the file content is present on the local disk:</p>
2626
<p style="text-align: center;"><img id="__mcenew" alt="Local Cloud File. Green check-mark on a white background icon means the file content is present on the local disk." src="https://www.userfilesystem.com/media/1983/localcloudfile.png" rel="116801"></p>
2727
<p>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&nbsp;"Always keep on this device" the file or entire folder structure will be recursively loaded to the local disk and all files content will be loaded to local disk and will become available offline. All files and folders are be marked with a pinned file icon<img id="__mcenew" alt="Pinned File" src="https://www.userfilesystem.com/media/1989/pinnedfile.png" rel="116800" data-allowlink="false">. Pinned files will not be deleted from the drive even if it runs low on space.</p>
@@ -32,9 +32,10 @@
3232
<h2>Microsoft Office Documents Synchronization</h2>
3333
<p>This sample supports the synchronization of the MS Office documents, avoiding the creation of the temporary files in remote storage. Note that for the sake of simplicity this sample filters MS Office temporary files only during user file system to remote storage synchronization. It is expected that MS Office temporary files are not created in remote storage and you do not need to synchronize them from server to client. Do NOT edit MS Office files directly in the folder simulating the remote storage.</p>
3434
<h2>Stopping the Sample</h2>
35-
<p>You can exit the sample running in the debug mode in 2 ways:</p>
35+
<p>You can exit the sample running in the debug mode in 3 ways:</p>
3636
<ul>
37-
<li>If you press 'q' the user file system will be unregistered. All files and folders downloaded on disk will be converted into the regular files and folders. The offline files and folders will disappear. This simulates your application's uninstallation process.</li>
37+
<li>If you press 'Q' the user file system will be unregistered and all files will be deleted. This simulates uninstall with complete cleanup.&nbsp;</li>
38+
<li>If you press 'q' the user file system will be unregistered. All files and folders downloaded on disk will be converted into regular files and folders. The offline files and folders will disappear. This simulates your application's uninstallation process.</li>
3839
<li>If you press any other key, the application will exit without unregistering the user file system. All files and folders placeholders, their attributes, and states remain in the user file system, even though most of the functionality, such as downloading file content or listing folder content for offline folders are unavailable. You can start this sample again to continue managing documents. This simulates the machine reboot or application failure.</li>
3940
</ul>
4041
<h2>How the Sample Works</h2>
@@ -57,9 +58,11 @@
5758
<p>The complete synchronization is performed in the&nbsp;<span class="code">SyncService</span> class. Due to the nature of this sample, this class goes folder-by-folder to synchronize the entire file system. This class first processes moved/renamed files and folders and then creates, deletes, and updates files and folders.</p>
5859
<p>Because of the simplicity of this sample, the files deleted in the user file system, then this Virtual File System sample application was not running, or during network or server outage, are not synched to remote storage (they are normally deleted inside <span class="code">VfsFileSystemItem</span>.<span class="code">DeleteAsync()</span>&nbsp;call). Instead, the file will be restored in the user file system when the synchronization service runs.</p>
5960
<p>You can adapt the <span class="code">SyncService</span> class implementation to your needs depending on your remote storage type.</p>
61+
<h2>File ETags</h2>
62+
<p>When listing folder content the client reads file ETags and saves them in local file system. When sending modified content to the server, the client attaches the saved etag to the request. The server compares etags to ensure the file was not modified on the server since the file was read by the client. In the case of Microsoft Office documents, etags provide one more level of protection against overwriting server changes in addition to locks.</p>
63+
<p>Because of the nature of the remote storage simulation, this sample is using file/folder last modification date/time as an ETag. In your real-life storage, you will update ETag during each file modification in your storage and will NOT use the file/folder modification date.</p>
6064
<h2>In-Sync Status and ETag Usage For Synchronization</h2>
61-
<p>Synchronization in this Virtual File System sample is based on In-Sync file status as well as on ETag received from the server.</p>
62-
<p>During remote storage to user file system synchronization, each file/folder receives an ETag from the server and stores it in custom data associated with the file/folder in the user file system. The remote storage to user file system synchronization is performed only if the file on the client is marked as In-Sync (<img id="__mcenew" alt="In-Sync icon" src="https://www.userfilesystem.com/media/1986/localfile.png" rel="118449">&nbsp;or&nbsp;<img id="__mcenew" alt="Pinned file" src="https://www.userfilesystem.com/media/1989/pinnedfile.png" rel="118452">&nbsp;or&nbsp;<img id="__mcenew" alt="Cloud file" src="https://www.userfilesystem.com/media/1988/offilefile.png" rel="118451">)&nbsp;with the server. If the file is modified on the server and is marked as not In-Sync on the client, the files are considered to be in conflict, the conflict icon is displayed.</p>
63-
<p>When any file or folder in the user file system is updated it is marked as not In-Sync<img id="__mcenew" alt="Not in sync icon" src="https://www.userfilesystem.com/media/1987/notinsyncfile.png" rel="118450">, which means the content must be sent to the server. During the user file system to remote storage synchronization, the ETag stored with the file on the client is compared with the ETag in the remote storage, to avoid the server changes to be overwritten. The file/folder is updated only if the ETags match. Otherwise, the file/folder is considered to be in conflict and marked with the conflict icon.</p>
64-
<p>Because of the nature of the remote storage simulation, this sample is using file/folder last modification date/time as an ETag. Instead, in your real-life storage, you will update ETag during each file modification in your storage and will NOT use the file/folder modification date.</p>
65+
<p>Synchronization in this sample is based on In-Sync file status as well as on the ETag received from the server.</p>
66+
<p>The server to client synchronization is performed only if the file on the client is marked as In-Sync&nbsp;with the server&nbsp;(it is marked with<img id="__mcenew" alt="In-Sync icon" src="https://www.userfilesystem.com/media/1986/localfile.png" rel="118449">&nbsp;or&nbsp;<img id="__mcenew" alt="Pinned file" src="https://www.userfilesystem.com/media/1989/pinnedfile.png" rel="118452">&nbsp;or&nbsp;<img id="__mcenew" alt="Cloud file" src="https://www.userfilesystem.com/media/1988/offilefile.png" rel="118451">icon). If the file is modified on the server and is marked as not In-Sync on the client, the files are considered to be in conflict and the conflict icon is displayed.</p>
67+
<p>When any file or folder on the client is updated, it is marked as not In-Sync<img id="__mcenew" alt="Not in sync icon" src="https://www.userfilesystem.com/media/1987/notinsyncfile.png" rel="118450">, which means the content must be sent to the server. When the updated file is being sent from client to server, the server compares the ETag sent from the client with the ETag stored on the server, to avoid the server changes to be overwritten. The file/folder is updated only if the ETags match. Otherwise, the file/folder is considered to be in conflict and marked with the conflict icon.</p>
6568

VirtualFileSystem/RemoteStorageMonitor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ internal class RemoteStorageMonitor : Logger, IDisposable
3232
private FileSystemWatcher watcher = new FileSystemWatcher();
3333

3434
/// <summary>
35-
/// Remote storage path. Folder to minitor changes in.
35+
/// Remote storage path. Folder to monitor for changes.
3636
/// </summary>
3737
private string remoteStorageRootPath;
3838

VirtualFileSystem/Settings.cs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
using Microsoft.Extensions.Configuration;
22
using System;
33
using System.Collections.Generic;
4+
using System.Diagnostics;
45
using System.IO;
6+
using System.Reflection;
57
using System.Text;
68
using System.Threading.Tasks;
79

@@ -46,6 +48,12 @@ public class Settings
4648
/// </summary>
4749
public string IconsFolderPath { get; set; }
4850

51+
/// <summary>
52+
/// Product name. Displayed as a mounted folder name under Desktop as
53+
/// well in every location where product name is required.
54+
/// </summary>
55+
public string ProductName { get; set; }
56+
4957
/// <summary>
5058
/// Path to the folder that stores ETags, locks and other data associated with files and folders.
5159
/// </summary>
@@ -109,13 +117,17 @@ public static Settings ReadSettings(this IConfiguration configuration)
109117
Directory.CreateDirectory(settings.UserFileSystemRootPath);
110118
}
111119

120+
string assemblyLocation = Assembly.GetEntryAssembly().Location;
121+
112122
// Icons folder.
113-
settings.IconsFolderPath = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), @"Images");
123+
settings.IconsFolderPath = Path.Combine(Path.GetDirectoryName(assemblyLocation), @"Images");
114124

115-
// Folder where eTags and file locks are sored.
116-
string localApplicationDataFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
117-
settings.ServerDataFolderPath = Path.Combine(localApplicationDataFolderPath, settings.UserFileSystemRootPath.Replace(":", ""), "ServerData");
125+
// Load product name from entry exe file.
126+
settings.ProductName = FileVersionInfo.GetVersionInfo(assemblyLocation).ProductName;
118127

128+
// Folder where eTags and file locks are stored.
129+
string localApplicationDataFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
130+
settings.ServerDataFolderPath = Path.Combine(localApplicationDataFolderPath, settings.ProductName, settings.UserFileSystemRootPath.Replace(":", ""), "ServerData");
119131

120132
return settings;
121133
}

VirtualFileSystem/VirtualFileSystem.csproj

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
<Product>Virtual File System</Product>
88
<Copyright>IT Hit LTD.</Copyright>
99
<Platforms>AnyCPU</Platforms>
10+
<Description>A virtual file system 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.
11+
12+
To simulate the remote storage, this sample is using a folder in the local file system on the same machine.</Description>
1013
</PropertyGroup>
1114
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
1215
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
@@ -29,7 +32,7 @@
2932
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.7" />
3033
</ItemGroup>
3134
<ItemGroup>
32-
<PackageReference Include="ITHit.FileSystem.Windows" Version="1.3.4067.0" />
35+
<PackageReference Include="ITHit.FileSystem.Windows" Version="1.3.4102.0" />
3336
</ItemGroup>
3437
<ItemGroup>
3538
<None Update="appsettings.json">

0 commit comments

Comments
 (0)