/// <summary>
        /// Deletes this file or folder in the remote storage.
        /// </summary>
        public async Task DeleteAsync()
        {
            FileSystemInfo remoteStorageItem = FsPath.GetFileSystemItem(RemoteStoragePath);

            if (remoteStorageItem != null)
            {
                try
                {
                    // Disable RemoteStorageMonitor to avoid circular calls.
                    // This is only required because of the specifics of the simplicity of this example.
                    Program.RemoteStorageMonitorInstance.Enabled = false;

                    if (remoteStorageItem is FileInfo)
                    {
                        remoteStorageItem.Delete();
                    }
                    else
                    {
                        (remoteStorageItem as DirectoryInfo).Delete(true);
                    }
                }
                finally
                {
                    Program.RemoteStorageMonitorInstance.Enabled = true;
                }
            }
        }
        /// <summary>
        /// Called when a file content changed or file/folder attributes changed in the remote storage.
        /// </summary>
        /// <remarks>
        /// In this method we update corresponding file/folder information in user file system.
        /// We also dehydrate the file if it is not blocked.
        /// </remarks>
        private async void ChangedAsync(object sender, FileSystemEventArgs e)
        {
            LogMessage(e.ChangeType.ToString(), e.FullPath);
            string remoteStoragePath = e.FullPath;

            try
            {
                // We do not want to sync MS Office temp files, etc. from remote storage.
                if (!FsPath.AvoidSync(remoteStoragePath))
                {
                    string userFileSystemPath = Mapping.ReverseMapPath(remoteStoragePath);

                    // Because of the on-demand population the file or folder placeholder may not exist in the user file system.
                    if (FsPath.Exists(userFileSystemPath))
                    {
                        FileSystemInfo remoteStorageItem = FsPath.GetFileSystemItem(remoteStoragePath);

                        // This check is only required because we can not prevent circular calls because of the simplicity of this example.
                        // In your real-life application you will not sent updates from server back to client that issued the update.
                        FileSystemItemMetadataExt itemInfo = Mapping.GetUserFileSysteItemMetadata(remoteStorageItem);
                        if (!await virtualDrive.GetETagManager(userFileSystemPath, this).ETagEqualsAsync(itemInfo))
                        {
                            await virtualDrive.ServerNotifications(userFileSystemPath, this).UpdateAsync(itemInfo);

                            LogMessage("Updated succesefully", userFileSystemPath);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                LogError($"{e.ChangeType} failed", remoteStoragePath, null, ex);
            }
        }
        /// <summary>
        /// Renames or moves file or folder to a new location in the remote storage.
        /// </summary>
        /// <param name="userFileSystemNewPath">Target path of this file of folder in the user file system.</param>
        public async Task MoveToAsync(string userFileSystemNewPath)
        {
            string remoteStorageOldPath = RemoteStoragePath;
            string remoteStorageNewPath = Mapping.MapPath(userFileSystemNewPath);

            FileSystemInfo remoteStorageOldItem = FsPath.GetFileSystemItem(remoteStorageOldPath);

            if (remoteStorageOldItem != null)
            {
                try
                {
                    // Disable RemoteStorageMonitor to avoid circular calls.
                    // This is only required because of the specifics of the simplicity of this example.
                    Program.RemoteStorageMonitorInstance.Enabled = false;

                    if (remoteStorageOldItem is FileInfo)
                    {
                        (remoteStorageOldItem as FileInfo).MoveTo(remoteStorageNewPath, true);
                    }
                    else
                    {
                        (remoteStorageOldItem as DirectoryInfo).MoveTo(remoteStorageNewPath);
                    }
                }
                finally
                {
                    Program.RemoteStorageMonitorInstance.Enabled = true;
                }
            }
        }
Пример #4
0
        /// <summary>
        /// Called when a file or folder is created in the remote storage.
        /// </summary>
        /// <remarks>In this method we create a new file/folder in the user file system.</remarks>
        private async void CreatedAsync(object sender, FileSystemEventArgs e)
        {
            LogMessage(e.ChangeType.ToString(), e.FullPath);
            string remoteStoragePath = e.FullPath;

            try
            {
                string userFileSystemPath = Mapping.ReverseMapPath(remoteStoragePath);

                // This check is only required because we can not prevent circular calls because of the simplicity of this example.
                // In your real-life application you will not sent updates from server back to client that issued the update.
                if (!FsPath.Exists(userFileSystemPath))
                {
                    string userFileSystemParentPath = Path.GetDirectoryName(userFileSystemPath);

                    FileSystemInfo remoteStorageItem = FsPath.GetFileSystemItem(remoteStoragePath);
                    if (remoteStorageItem != null)
                    {
                        IFileSystemItemMetadata newItemInfo = Mapping.GetUserFileSysteItemMetadata(remoteStorageItem);
                        if (await engine.ServerNotifications(userFileSystemParentPath).CreateAsync(new[] { newItemInfo }) > 0)
                        {
                            // Because of the on-demand population, the parent folder placeholder may not exist in the user file system
                            // or the folder may be offline. In this case the IServerNotifications.CreateAsync() call is ignored.
                            LogMessage($"Created succesefully", userFileSystemPath);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                LogError($"{e.ChangeType} failed", remoteStoragePath, null, ex);
            }
        }
        /// <summary>
        /// Called when a file or folder is created in the remote storage.
        /// </summary>
        /// <remarks>In this method we create a new file/folder in user file system.</remarks>
        private async void CreatedAsync(object sender, FileSystemEventArgs e)
        {
            LogMessage(e.ChangeType.ToString(), e.FullPath);
            string remoteStoragePath = e.FullPath;

            try
            {
                // We do not want to sync MS Office temp files from remote storage.
                if (!FsPath.AvoidSync(remoteStoragePath))
                {
                    string userFileSystemPath       = Mapping.ReverseMapPath(remoteStoragePath);
                    string userFileSystemParentPath = Path.GetDirectoryName(userFileSystemPath);

                    // Because of the on-demand population the file or folder placeholder may not exist in the user file system
                    // or the folder may be offline.
                    FileSystemInfo            remoteStorageItem = FsPath.GetFileSystemItem(remoteStoragePath);
                    FileSystemItemMetadataExt newItemInfo       = Mapping.GetUserFileSysteItemMetadata(remoteStorageItem);
                    if (await virtualDrive.ServerNotifications(userFileSystemParentPath, this).CreateAsync(new[] { newItemInfo }) > 0)
                    {
                        LogMessage($"Created succesefully", userFileSystemPath);
                    }
                }
            }
            catch (Exception ex)
            {
                LogError($"{e.ChangeType} failed", remoteStoragePath, null, ex);
            }
        }
Пример #6
0
        /// <summary>
        /// Called when a file content changed or file/folder attributes changed in the remote storage.
        /// </summary>
        /// <remarks>
        /// In this method we update corresponding file/folder information in user file system.
        /// We also dehydrate the file if it is not blocked.
        /// </remarks>
        private async void ChangedAsync(object sender, FileSystemEventArgs e)
        {
            LogMessage(e.ChangeType.ToString(), e.FullPath);
            string remoteStoragePath  = e.FullPath;
            string userFileSystemPath = null;

            try
            {
                userFileSystemPath = Mapping.ReverseMapPath(remoteStoragePath);

                // This check is only required because we can not prevent circular calls because of the simplicity of this example.
                // In your real-life application you will not sent updates from server back to client that issued the update.
                if (IsModified(userFileSystemPath, remoteStoragePath))
                {
                    FileSystemInfo          remoteStorageItem = FsPath.GetFileSystemItem(remoteStoragePath);
                    IFileSystemItemMetadata itemInfo          = Mapping.GetUserFileSysteItemMetadata(remoteStorageItem);

                    if (await engine.ServerNotifications(userFileSystemPath).UpdateAsync(itemInfo))
                    {
                        // Because of the on-demand population the file or folder placeholder may not exist in the user file system.
                        // In this case the IServerNotifications.UpdateAsync() call is ignored.
                        LogMessage("Updated succesefully", userFileSystemPath);
                    }
                }
            }
            catch (IOException ex)
            {
                // The file is blocked in the user file system. This is a normal behaviour.
                LogMessage(ex.Message);
            }
            catch (Exception ex)
            {
                LogError($"{e.ChangeType} failed", remoteStoragePath, null, ex);
            }
        }
        ///<inheritdoc>
        public async Task MoveToAsync(string userFileSystemNewPath, byte[] newParentItemId, IOperationContext operationContext, IConfirmationResultContext resultContext)
        {
            string userFileSystemOldPath = this.UserFileSystemPath;

            Logger.LogMessage($"{nameof(IFileSystemItem)}.{nameof(MoveToAsync)}()", userFileSystemOldPath, userFileSystemNewPath);

            string remoteStorageOldPath       = RemoteStoragePath;
            string remoteStorageNewParentPath = WindowsFileSystemItem.GetPathByItemId(newParentItemId);
            string remoteStorageNewPath       = Path.Combine(remoteStorageNewParentPath, Path.GetFileName(userFileSystemNewPath));

            FileSystemInfo remoteStorageOldItem = FsPath.GetFileSystemItem(remoteStorageOldPath);

            if (remoteStorageOldItem != null)
            {
                if (remoteStorageOldItem is FileInfo)
                {
                    (remoteStorageOldItem as FileInfo).MoveTo(remoteStorageNewPath, true);
                }
                else
                {
                    (remoteStorageOldItem as DirectoryInfo).MoveTo(remoteStorageNewPath);
                }
                Logger.LogMessage("Moved item in remote storage succesefully", userFileSystemOldPath, userFileSystemNewPath);
            }
        }
Пример #8
0
        ///<inheritdoc>
        public async Task MoveToAsync(string userFileSystemNewPath, IOperationContext operationContext, IConfirmationResultContext resultContext)
        {
            // Here we will simply move the file in remote storage and confirm the operation.
            // In your implementation you may implement a more complex scenario with offline operations support.

            LogMessage("IFileSystemItem.MoveToAsync()", this.FullPath, userFileSystemNewPath);

            string userFileSystemOldPath = this.FullPath;

            try
            {
                bool?inSync = null;
                try
                {
                    Program.RemoteStorageMonitorInstance.Enabled = false; // Disable RemoteStorageMonitor to avoid circular calls.

                    // When a file is deleted, it is moved to a Recycle Bin, that is why we check for recycle bin here.
                    if (FsPath.Exists(userFileSystemOldPath) && !FsPath.IsRecycleBin(userFileSystemNewPath) &&
                        !FsPath.AvoidSync(userFileSystemOldPath) && !FsPath.AvoidSync(userFileSystemNewPath))
                    {
                        inSync = PlaceholderItem.GetItem(userFileSystemOldPath).GetInSync();

                        string remoteStorageOldPath = Mapping.MapPath(userFileSystemOldPath);
                        string remoteStorageNewPath = Mapping.MapPath(userFileSystemNewPath);

                        FileSystemInfo remoteStorageOldItem = FsPath.GetFileSystemItem(remoteStorageOldPath);

                        if (remoteStorageOldItem is FileInfo)
                        {
                            (remoteStorageOldItem as FileInfo).MoveTo(remoteStorageNewPath);
                        }
                        else
                        {
                            (remoteStorageOldItem as DirectoryInfo).MoveTo(remoteStorageNewPath);
                        }
                        LogMessage("Moved succesefully:", remoteStorageOldPath, remoteStorageNewPath);
                    }
                }
                finally
                {
                    resultContext.ReturnConfirmationResult();

                    // If a file with content is deleted it is moved to a recycle bin and converted
                    // to a regular file, so placeholder features are not available on it.
                    if ((inSync != null) && PlaceholderItem.IsPlaceholder(userFileSystemNewPath))
                    {
                        PlaceholderItem.GetItem(userFileSystemNewPath).SetInSync(inSync.Value);
                    }
                }
            }
            catch (Exception ex)
            {
                // remove try-catch when error processing inside CloudProvider is fixed.
                LogError("Move failed:", $"From: {this.FullPath} to:{userFileSystemNewPath}", ex);
            }
            finally
            {
                Program.RemoteStorageMonitorInstance.Enabled = true;
            }
        }
Пример #9
0
        ///<inheritdoc>
        public async Task DeleteAsync(IOperationContext operationContext, IConfirmationResultContext resultContext)
        {
            // Here we will simply delete the file in remote storage and confirm the operation.
            // In your implementation you may implement a more complex scenario with offline operations support.

            LogMessage("IFileSystemItem.DeleteAsync()", this.FullPath);
            string userFileSystemPath = this.FullPath;
            string remoteStoragePath  = null;

            try
            {
                try
                {
                    Program.RemoteStorageMonitorInstance.Enabled = false; // Disable RemoteStorageMonitor to avoid circular calls.

                    remoteStoragePath = Mapping.MapPath(userFileSystemPath);
                    if (FsPath.Exists(remoteStoragePath) && !FsPath.AvoidSync(userFileSystemPath))
                    {
                        FileSystemInfo remoteStorageItem = FsPath.GetFileSystemItem(remoteStoragePath);
                        remoteStorageItem.Delete();
                        LogMessage("Deleted succesefully:", remoteStoragePath);
                    }
                }
                finally
                {
                    resultContext.ReturnConfirmationResult();
                }
            }
            catch (Exception ex)
            {
                // remove try-catch when error processing inside CloudProvider is fixed.
                LogError("Delete failed:", remoteStoragePath, ex);
            }
            finally
            {
                Program.RemoteStorageMonitorInstance.Enabled = true;
            }
        }
        /// <inheritdoc/>
        public async Task DeleteCompletionAsync(IOperationContext operationContext, IResultContext resultContext)
        {
            // On Windows, for move with overwrite to function properly for folders,
            // the deletion of the folder in the remote storage must be done in DeleteCompletionAsync()
            // Otherwise the folder will be deleted before files in it can be moved.

            Logger.LogMessage($"{nameof(IFileSystemItem)}.{nameof(DeleteCompletionAsync)}()", this.UserFileSystemPath);

            FileSystemInfo remoteStorageItem = FsPath.GetFileSystemItem(RemoteStoragePath);

            if (remoteStorageItem != null)
            {
                if (remoteStorageItem is FileInfo)
                {
                    remoteStorageItem.Delete();
                }
                else
                {
                    (remoteStorageItem as DirectoryInfo).Delete(true);
                }
                Logger.LogMessage("Deleted item in remote storage succesefully", UserFileSystemPath);
            }
        }