如何在.NET中创建一个带有离线文件的虚拟文件系统(类似于OneDrive)?
How to create a virtual file system with offline files (similar to OneDrive) in .NET?
我需要创建一个虚拟文件系统,将文件从我的 Azure 应用服务同步到本地驱动器并向后同步。我只需要将一些文件和文件夹同步到我的本地文件系统并可以离线使用。 files/folders 应在首次访问期间或用户选择“始终保留在此设备上”菜单时进行同步。类似于 OneDrive 的做法。我发现 Microsoft CloudMirror C++ 示例具有一些基本的 OneDrive 功能,但它会在启动期间同步所有文件一次,并且在第一次访问时不会 listing/loading。
是否可以完全在 .NET 中构建具有上述功能的虚拟文件系统?
要构建一个 OneDrive-like 客户端,您需要使用云过滤器 API 创建同步提供程序,这主要是通过 Win32 编程的(有一些例外,见下文),但您可以构建一个在 .NET 中完成 OneDrive 模拟,包括“始终保留在此设备上”菜单和 on-demand 加载。
以下是可通过 .NET 获得的功能,因此您无需 PInvoke:
- 同步根注册可以在 .NET 中通过 StorageProviderSyncRootManager and StorageProviderSyncRootInfo classes.
- 您可以使用 StorageProviderItemProperty class and IStorageProviderItemPropertySource 界面在 .NET 中创建属性。
- Windows 文件和文件夹的文件管理器中的图标可以通过 StorageProviderItemProperties.SetAsync() 方法和 StorageFile/StorageFolder class.
设置
- 您可以使用 File.GetAttributes() / File.SetAttributes() 在 .NET 中读取和设置文件属性。您将需要它们来读取离线属性、固定和非固定属性。
- URI 映射的文件系统路径可以通过实现 IStorageProviderUriSource 接口来完成。
以下是仅通过 Win32 函数可用的功能,您需要通过 PInvoke 调用它:
- 文件夹 on-demand 枚举,on-demand 文件内容加载仅可通过 Win32 回调进行。您需要使用 CfConnectSyncRoot().
注册回调
- 文件 hydration/dehydration 通过 Windows 资源管理器菜单。您将需要监控文件系统并调用 CfHydratePlaceholder() and CfUpdatePlaceholder().
- 下载进度报告、错误报告、通知 Windows、同步提供商状态报告。要报告进度,请使用 CfReportProviderProgress(). Errors are reported via CfExecute().
- 检测是文件是常规 file/folder 或占位符 file/folder。可以通过 CfGetPlaceholderStateFromFileInfo() 调用完成。
- 占位符的创建和占位符信息的更新。可以使用 CfCreatePlaceholders() and CfUpdatePlaceholder() 函数来完成。
- 将 files/folders 转换为占位符并返回。可以使用 CfConvertToPlaceholder() and CfRevertPlaceholder().
完成
- 设置和读取占位符状态,例如in-sync/not in-sync。可以使用 CfGetPlaceholderStateFromFileInfo() 和 CfGetPlaceholderInfo().
完成
以下是在 .NET 中编写所有代码的方法:
一种选择是 import all required Win32 functions 使用 extern to .NET,例如:
[DllImport("cldapi.dll", SetLastError = true, ExactSpelling = true)]
public static extern int CfGetPlaceholderStateFromFileInfo(IntPtr infoBuffer, FILE_INFO_BY_HANDLE_CLASS infoClass);
[DllImport("cldapi.dll", SetLastError = true, ExactSpelling = true)]
public static extern HRESULT CfSetPinState(IntPtr fileHandle, int pinState, int pinFlags, IntPtr overlapped);
另一个选项可以是 using this sample。
关于构建 OneDrive-like 文件系统的更多注意事项:
- 同步根注册时自动显示“始终保留在此设备上”/“释放 space”。但它只设置 Pinned 和 Unpinned 文件属性。您需要监视文件系统,检查 pinned/unpinned 属性,并 hydrate/dehydrate 每个文件。
- on-demand 文件夹列表在 CF_CALLBACK_TYPE_FETCH_PLACEHOLDERS 回调中完成。您需要使用 CfConnectSyncRoot() 注册回调并在 .NET 代码中收听它。
- on-demand 文件内容下载(水化)在 CF_CALLBACK_TYPE_FETCH_DATA 回调中完成。您需要在.NET 代码中注册并收听它。
我需要创建一个虚拟文件系统,将文件从我的 Azure 应用服务同步到本地驱动器并向后同步。我只需要将一些文件和文件夹同步到我的本地文件系统并可以离线使用。 files/folders 应在首次访问期间或用户选择“始终保留在此设备上”菜单时进行同步。类似于 OneDrive 的做法。我发现 Microsoft CloudMirror C++ 示例具有一些基本的 OneDrive 功能,但它会在启动期间同步所有文件一次,并且在第一次访问时不会 listing/loading。
是否可以完全在 .NET 中构建具有上述功能的虚拟文件系统?
要构建一个 OneDrive-like 客户端,您需要使用云过滤器 API 创建同步提供程序,这主要是通过 Win32 编程的(有一些例外,见下文),但您可以构建一个在 .NET 中完成 OneDrive 模拟,包括“始终保留在此设备上”菜单和 on-demand 加载。
以下是可通过 .NET 获得的功能,因此您无需 PInvoke:
- 同步根注册可以在 .NET 中通过 StorageProviderSyncRootManager and StorageProviderSyncRootInfo classes.
- 您可以使用 StorageProviderItemProperty class and IStorageProviderItemPropertySource 界面在 .NET 中创建属性。
- Windows 文件和文件夹的文件管理器中的图标可以通过 StorageProviderItemProperties.SetAsync() 方法和 StorageFile/StorageFolder class. 设置
- 您可以使用 File.GetAttributes() / File.SetAttributes() 在 .NET 中读取和设置文件属性。您将需要它们来读取离线属性、固定和非固定属性。
- URI 映射的文件系统路径可以通过实现 IStorageProviderUriSource 接口来完成。
以下是仅通过 Win32 函数可用的功能,您需要通过 PInvoke 调用它:
- 文件夹 on-demand 枚举,on-demand 文件内容加载仅可通过 Win32 回调进行。您需要使用 CfConnectSyncRoot(). 注册回调
- 文件 hydration/dehydration 通过 Windows 资源管理器菜单。您将需要监控文件系统并调用 CfHydratePlaceholder() and CfUpdatePlaceholder().
- 下载进度报告、错误报告、通知 Windows、同步提供商状态报告。要报告进度,请使用 CfReportProviderProgress(). Errors are reported via CfExecute().
- 检测是文件是常规 file/folder 或占位符 file/folder。可以通过 CfGetPlaceholderStateFromFileInfo() 调用完成。
- 占位符的创建和占位符信息的更新。可以使用 CfCreatePlaceholders() and CfUpdatePlaceholder() 函数来完成。
- 将 files/folders 转换为占位符并返回。可以使用 CfConvertToPlaceholder() and CfRevertPlaceholder(). 完成
- 设置和读取占位符状态,例如in-sync/not in-sync。可以使用 CfGetPlaceholderStateFromFileInfo() 和 CfGetPlaceholderInfo(). 完成
以下是在 .NET 中编写所有代码的方法:
一种选择是 import all required Win32 functions 使用 extern to .NET,例如:
[DllImport("cldapi.dll", SetLastError = true, ExactSpelling = true)] public static extern int CfGetPlaceholderStateFromFileInfo(IntPtr infoBuffer, FILE_INFO_BY_HANDLE_CLASS infoClass); [DllImport("cldapi.dll", SetLastError = true, ExactSpelling = true)] public static extern HRESULT CfSetPinState(IntPtr fileHandle, int pinState, int pinFlags, IntPtr overlapped);
另一个选项可以是 using this sample。
关于构建 OneDrive-like 文件系统的更多注意事项:
- 同步根注册时自动显示“始终保留在此设备上”/“释放 space”。但它只设置 Pinned 和 Unpinned 文件属性。您需要监视文件系统,检查 pinned/unpinned 属性,并 hydrate/dehydrate 每个文件。
- on-demand 文件夹列表在 CF_CALLBACK_TYPE_FETCH_PLACEHOLDERS 回调中完成。您需要使用 CfConnectSyncRoot() 注册回调并在 .NET 代码中收听它。
- on-demand 文件内容下载(水化)在 CF_CALLBACK_TYPE_FETCH_DATA 回调中完成。您需要在.NET 代码中注册并收听它。