/// <summary> /// Recursively updates and creates files and folders in remote storage. /// Synchronizes only folders already loaded into the user file system. /// </summary> /// <param name="userFileSystemFolderPath">Folder path in user file system.</param> internal async Task SyncronizeFolderAsync(string userFileSystemFolderPath) { // In case of on-demand loading the user file system contains only a subset of the server files and folders. // Here we sync folder only if its content already loaded into user file system (folder is not offline). // The folder content is loaded inside IFolder.GetChildrenAsync() method. if (new DirectoryInfo(userFileSystemFolderPath).Attributes.HasFlag(System.IO.FileAttributes.Offline)) { // LogMessage("Folder offline, skipping:", userFileSystemFolderPath); return; } IEnumerable <string> userFileSystemChildren = Directory.EnumerateFileSystemEntries(userFileSystemFolderPath, "*"); // LogMessage("Synchronizing:", userFileSystemFolderPath); // Update and create files/folders in remote storage. userFileSystemChildren = Directory.EnumerateFileSystemEntries(userFileSystemFolderPath, "*"); foreach (string userFileSystemPath in userFileSystemChildren) { try { if (!FsPath.AvoidSync(userFileSystemPath)) { if (PlaceholderItem.GetItem(userFileSystemPath).IsNew(virtualDrive)) { // Create a file/folder in the remote storage. FileSystemItemTypeEnum itemType = FsPath.GetItemType(userFileSystemPath); await virtualDrive.GetRemoteStorageRawItem(userFileSystemPath, itemType, this).CreateAsync(); } else if (!PlaceholderItem.GetItem(userFileSystemPath).IsMoved()) { // Update file/folder in the remote storage. Unlock if auto-locked. FileSystemItemTypeEnum itemType = FsPath.GetItemType(userFileSystemPath); await virtualDrive.GetRemoteStorageRawItem(userFileSystemPath, itemType, this).UpdateAsync(); } } } catch (Exception ex) { LogError("Update failed", userFileSystemPath, null, ex); } // Synchronize subfolders. try { if (Directory.Exists(userFileSystemPath)) { await SyncronizeFolderAsync(userFileSystemPath); } } catch (Exception ex) { LogError("Folder sync failed:", userFileSystemPath, null, ex); } } }
/// <summary> /// Called when a file or folder is created in the user file system. /// </summary> /// <remarks> /// This method is also called when a file is being moved in user file system, after the IFileSystem.MoveToAsync() call. /// </remarks> private async void CreatedAsync(object sender, FileSystemEventArgs e) { //LogMessage($"{e.ChangeType}", e.FullPath); string userFileSystemPath = e.FullPath; try { // When a file/folder is moved this method is also called. The file/folder move is already processed in IFileSystemItem.MoveToAsync(). if (FsPath.Exists(userFileSystemPath) && !PlaceholderItem.IsPlaceholder(userFileSystemPath)) { LogMessage("Creating new item", userFileSystemPath); // When a new file or folder is created under sync root it is // created as a regular file or folder. Converting to placeholder. PlaceholderItem.ConvertToPlaceholder(userFileSystemPath, false); LogMessage("Converted to placeholder", userFileSystemPath); // Do not create temp MS Office, temp and hidden files in remote storage. if (!FsPath.AvoidSync(userFileSystemPath)) { // Create the file/folder in the remote storage. FileSystemItemTypeEnum itemType = FsPath.GetItemType(userFileSystemPath); try { await virtualDrive.GetRemoteStorageRawItem(userFileSystemPath, itemType, this).CreateAsync(); } catch (IOException ex) { LogError("Creation in remote storage failed. Possibly in use by an application", userFileSystemPath, null, ex); } } } } catch (Exception ex) { LogError($"{e.ChangeType} failed", userFileSystemPath, null, ex); } }
/// <summary> /// Recursively synchronizes all files and folders moved in user file system with the remote storage. /// Restores Original Path and 'locked' icon that are lost during MS Office transactional save. /// Synchronizes only folders already loaded into the user file system. /// </summary> /// <param name="userFileSystemFolderPath">Folder path in user file system.</param> internal async Task SyncronizeMovedAsync(string userFileSystemFolderPath) { // In case of on-demand loading the user file system contains only a subset of the server files and folders. // Here we sync folder only if its content already loaded into user file system (folder is not offline). // The folder content is loaded inside IFolder.GetChildrenAsync() method. if (new DirectoryInfo(userFileSystemFolderPath).Attributes.HasFlag(System.IO.FileAttributes.Offline)) { //LogMessage("Folder offline, skipping:", userFileSystemFolderPath); return; } IEnumerable <string> userFileSystemChildren = Directory.EnumerateFileSystemEntries(userFileSystemFolderPath, "*"); //LogMessage("Synchronizing:", userFileSystemFolderPath); foreach (string userFileSystemPath in userFileSystemChildren) { string userFileSystemOldPath = null; try { if (!PlaceholderItem.IsPlaceholder(userFileSystemPath)) { // Convert regular file/folder to placeholder. // The file/folder was created or overwritten. PlaceholderItem.ConvertToPlaceholder(userFileSystemPath, false); LogMessage("Converted to placeholder", userFileSystemPath); } if (!FsPath.AvoidSync(userFileSystemPath)) { PlaceholderItem userFileSystemItem = PlaceholderItem.GetItem(userFileSystemPath); if (userFileSystemItem.IsMoved()) { // Process items moved in user file system. userFileSystemOldPath = userFileSystemItem.GetOriginalPath(); FileSystemItemTypeEnum itemType = FsPath.GetItemType(userFileSystemPath); await virtualDrive.GetRemoteStorageRawItem(userFileSystemOldPath, itemType, this).MoveToAsync(userFileSystemPath); } else { // Restore Original Path and 'locked' icon that are lost during MS Office transactional save. // We keep Original Path to process moved files when app was not running. userFileSystemOldPath = userFileSystemItem.GetOriginalPath(); if (!userFileSystemItem.IsNew(virtualDrive) && string.IsNullOrEmpty(userFileSystemOldPath)) { // Restore Original Path. LogMessage("Setting Original Path", userFileSystemItem.Path); userFileSystemItem.SetOriginalPath(userFileSystemItem.Path); // Restore the 'locked' icon. ServerLockInfo existingLock = await virtualDrive.LockManager(userFileSystemPath, this).GetLockInfoAsync(); await virtualDrive.GetUserFileSystemRawItem(userFileSystemPath, this).SetLockInfoAsync(existingLock); } } } } catch (Exception ex) { LogError("Move in remote storage failed", userFileSystemOldPath, userFileSystemPath, ex); } // Synchronize subfolders. try { if (FsPath.IsFolder(userFileSystemPath)) { await SyncronizeMovedAsync(userFileSystemPath); } } catch (Exception ex) { LogError("Folder move sync failed", userFileSystemPath, null, ex); } } }