public async Task <IStorageHistory> CopyAsync(IStorageItemWithPath source, string destination, IProgress <float> progress, IProgress <FilesystemErrorCode> errorCode, CancellationToken cancellationToken) { if (associatedInstance.FilesystemViewModel.WorkingDirectory.StartsWith(App.AppSettings.RecycleBinPath)) { errorCode?.Report(FilesystemErrorCode.ERROR_UNAUTHORIZED); progress?.Report(100.0f); // Do not paste files and folders inside the recycle bin await DialogDisplayHelper.ShowDialogAsync( "ErrorDialogThisActionCannotBeDone".GetLocalized(), "ErrorDialogUnsupportedOperation".GetLocalized()); return(null); } IStorageItem copiedItem = null; long itemSize = await FilesystemHelpers.GetItemSize(await source.ToStorageItem(associatedInstance)); bool reportProgress = false; // TODO: The default value is false if (source.ItemType == FilesystemItemType.Directory) { if (!string.IsNullOrWhiteSpace(source.Path) && Path.GetDirectoryName(destination).IsSubPathOf(source.Path)) // We check if user tried to copy anything above the source.ItemPath { ImpossibleActionResponseTypes responseType = ImpossibleActionResponseTypes.Abort; /*if (false) * { * var destinationName = destination.Split(Path.DirectorySeparatorChar, StringSplitOptions.RemoveEmptyEntries).Last(); * var sourceName = source.Path.Split(Path.DirectorySeparatorChar, StringSplitOptions.RemoveEmptyEntries).Last(); * ContentDialog dialog = new ContentDialog() * { * Title = "ErrorDialogThisActionCannotBeDone".GetLocalized(), * Content = "ErrorDialogTheDestinationFolder".GetLocalized() + " (" + destinationName + ") " + "ErrorDialogIsASubfolder".GetLocalized() + " (" + sourceName + ")", * PrimaryButtonText = "ErrorDialogSkip".GetLocalized(), * CloseButtonText = "ErrorDialogCancel".GetLocalized() * }; * ContentDialogResult result = await dialog.ShowAsync(); * if (result == ContentDialogResult.Primary) * { * responseType = ImpossibleActionResponseTypes.Skip; * } * else if (result == ContentDialogResult.Primary) * { * responseType = ImpossibleActionResponseTypes.Abort; * } * }*/ if (responseType == ImpossibleActionResponseTypes.Skip) { progress?.Report(100.0f); errorCode?.Report(FilesystemErrorCode.ERROR_INPROGRESS | FilesystemErrorCode.ERROR_SUCCESS); } else if (responseType == ImpossibleActionResponseTypes.Abort) { progress?.Report(100.0f); errorCode?.Report(FilesystemErrorCode.ERROR_INPROGRESS | FilesystemErrorCode.ERROR_GENERIC); } return(null); } else { if (reportProgress) { progress?.Report((float)(itemSize * 100.0f / itemSize)); } StorageFolder fsSourceFolder = (StorageFolder)await source.ToStorageItem(associatedInstance); StorageFolder fsDestinationFolder = (StorageFolder)await associatedInstance.FilesystemViewModel.GetFolderFromPathAsync(Path.GetDirectoryName(destination)); if (fsSourceFolder != null && fsDestinationFolder != null) { FilesystemResult fsCopyResult = await FilesystemTasks.Wrap(async() => { return(await FilesystemHelpers.CloneDirectoryAsync(fsSourceFolder, fsDestinationFolder, fsSourceFolder.Name)); }) .OnSuccess(t => { if (associatedInstance.FilesystemViewModel.CheckFolderForHiddenAttribute(source.Path)) { // The source folder was hidden, apply hidden attribute to destination NativeFileOperationsHelper.SetFileAttribute(t.Path, FileAttributes.Hidden); } copiedItem = t; }); } } } else if (source.ItemType == FilesystemItemType.File) { if (reportProgress) { progress?.Report((float)(itemSize * 100.0f / itemSize)); } FilesystemResult <StorageFolder> destinationResult = await associatedInstance.FilesystemViewModel.GetFolderFromPathAsync(Path.GetDirectoryName(destination)); var sourceResult = await source.ToStorageItemResult(associatedInstance); var fsResult = (FilesystemResult)(sourceResult.ErrorCode | destinationResult.ErrorCode); if (fsResult) { var file = (StorageFile)sourceResult; var fsResultCopy = await FilesystemTasks.Wrap(() => file.CopyAsync(destinationResult.Result, Path.GetFileName(file.Name), NameCollisionOption.GenerateUniqueName).AsTask()); if (fsResultCopy) { copiedItem = fsResultCopy.Result; } fsResult = fsResultCopy; } if (fsResult == FilesystemErrorCode.ERROR_UNAUTHORIZED || fsResult == FilesystemErrorCode.ERROR_GENERIC) { // Try again with CopyFileFromApp if (NativeFileOperationsHelper.CopyFileFromApp(source.Path, destination, true)) { fsResult = (FilesystemResult)true; } else { Debug.WriteLine(System.Runtime.InteropServices.Marshal.GetLastWin32Error()); } } errorCode?.Report(fsResult.ErrorCode); } if (Path.GetDirectoryName(destination) == associatedInstance.FilesystemViewModel.WorkingDirectory) { if (copiedItem != null) { List <ListedItem> copiedListedItems = associatedInstance.FilesystemViewModel.FilesAndFolders .Where(listedItem => copiedItem.Path.Contains(listedItem.ItemPath)).ToList(); if (copiedListedItems.Count > 0) { associatedInstance.ContentPage.AddSelectedItemsOnUi(copiedListedItems); associatedInstance.ContentPage.FocusSelectedItems(); } } } progress?.Report(100.0f); var pathWithType = copiedItem.FromStorageItem(destination, source.ItemType); return(new StorageHistory(FileOperationType.Copy, source, pathWithType)); }
public async Task <IStorageHistory> CopyAsync(PathWithType source, string destination, IProgress <float> progress, IProgress <FilesystemErrorCode> errorCode, CancellationToken cancellationToken) { if (associatedInstance.FilesystemViewModel.WorkingDirectory.StartsWith(App.AppSettings.RecycleBinPath)) { errorCode?.Report(FilesystemErrorCode.ERROR_UNAUTHORIZED); progress?.Report(100.0f); // Do not paste files and folders inside the recycle bin await DialogDisplayHelper.ShowDialogAsync( "ErrorDialogThisActionCannotBeDone".GetLocalized(), "ErrorDialogUnsupportedOperation".GetLocalized()); return(null); } IStorageItem copiedItem = null; long itemSize = await FilesystemHelpers.GetItemSize(await source.Path.ToStorageItem()); bool reportProgress = false; // TODO: The default value is false if (source.ItemType == FilesystemItemType.Directory) { if (string.IsNullOrWhiteSpace(source.Path) || Path.GetDirectoryName(destination).IsSubPathOf(source.Path)) // We check if user tried to copy anything above the source.ItemPath { ImpossibleActionResponseTypes responseType = ImpossibleActionResponseTypes.Abort; /*if (ShowDialog) * { * /// Currently following implementation throws exception until it is resolved keep it disabled * Binding themeBind = new Binding(); * themeBind.Source = ThemeHelper.RootTheme; * ContentDialog dialog = new ContentDialog() * { * Title = ResourceController.GetTranslation("ErrorDialogThisActionCannotBeDone"), * Content = ResourceController.GetTranslation("ErrorDialogTheDestinationFolder") + " (" + destinationPath.Split(Path.DirectorySeparatorChar, StringSplitOptions.RemoveEmptyEntries).Last() + ") " + ResourceController.GetTranslation("ErrorDialogIsASubfolder") + " (" + item.Name + ")", * PrimaryButtonText = ResourceController.GetTranslation("ErrorDialogSkip"), * CloseButtonText = ResourceController.GetTranslation("ErrorDialogCancel"), * PrimaryButtonCommand = new RelayCommand(() => { responseType = ImpossibleActionResponseTypes.Skip; }), * CloseButtonCommand = new RelayCommand(() => { responseType = ImpossibleActionResponseTypes.Abort; }), * }; * BindingOperations.SetBinding(dialog, FrameworkElement.RequestedThemeProperty, themeBind); * await dialog.ShowAsync(); * }*/ if (responseType == ImpossibleActionResponseTypes.Skip) { progress?.Report(100.0f); errorCode?.Report(FilesystemErrorCode.ERROR_SUCCESS | FilesystemErrorCode.ERROR_INPROGRESS); } else if (responseType == ImpossibleActionResponseTypes.Abort) { progress?.Report(100.0f); errorCode?.Report(FilesystemErrorCode.ERROR_INPROGRESS | FilesystemErrorCode.ERROR_GENERIC); } return(null); } else { if (reportProgress) { progress?.Report((float)(itemSize * 100.0f / itemSize)); } FilesystemResult <StorageFolder> fsSourceFolderResult = await associatedInstance.FilesystemViewModel.GetFolderFromPathAsync(Path.GetDirectoryName(source.Path)); FilesystemResult <StorageFolder> fsDestinationFolderResult = await associatedInstance.FilesystemViewModel.GetFolderFromPathAsync(Path.GetDirectoryName(destination)); if (fsSourceFolderResult && fsDestinationFolderResult) { FilesystemResult fsCopyResult = await FilesystemTasks.Wrap(async() => { return(await FilesystemHelpers.CloneDirectoryAsync(fsSourceFolderResult.Result, fsDestinationFolderResult.Result, Path.GetFileName(source.Path))); }) .OnSuccess(t => { if (associatedInstance.FilesystemViewModel.CheckFolderForHiddenAttribute(source.Path)) { // The source folder was hidden, apply hidden attribute to destination NativeFileOperationsHelper.SetFileAttribute(t.Path, FileAttributes.Hidden); } copiedItem = t; }); } } } else if (source.ItemType == FilesystemItemType.File) { if (reportProgress) { progress?.Report((float)(itemSize * 100.0f / itemSize)); } FilesystemResult <StorageFolder> fsResult = await associatedInstance.FilesystemViewModel.GetFolderFromPathAsync(Path.GetDirectoryName(destination)); if (fsResult) { StorageFile file = (StorageFile)await source.Path.ToStorageItem(); FilesystemResult <StorageFile> fsResultCopy = new FilesystemResult <StorageFile>(null, FilesystemErrorCode.ERROR_GENERIC); if (file != null) { fsResultCopy = await FilesystemTasks.Wrap(() => { return(file.CopyAsync(fsResult.Result, Path.GetFileName(source.Path), NameCollisionOption.GenerateUniqueName).AsTask()); }); } if (fsResultCopy) { copiedItem = fsResultCopy.Result; } else if (fsResultCopy.ErrorCode == FilesystemErrorCode.ERROR_UNAUTHORIZED || fsResultCopy.ErrorCode == FilesystemErrorCode.ERROR_GENERIC) { // Try again with CopyFileFromApp if (NativeFileOperationsHelper.CopyFileFromApp(source.Path, destination, true)) { copiedItem = await source.Path.ToStorageItem(); // Dangerous - the provided item may be different than output result! } else { Debug.WriteLine(System.Runtime.InteropServices.Marshal.GetLastWin32Error()); } } else { errorCode?.Report(fsResultCopy.ErrorCode); } } } if (Path.GetDirectoryName(destination) == associatedInstance.FilesystemViewModel.WorkingDirectory) { if (copiedItem != null) { List <ListedItem> copiedListedItems = associatedInstance.FilesystemViewModel.FilesAndFolders .Where(listedItem => copiedItem.Path.Contains(listedItem.ItemPath)).ToList(); if (copiedListedItems.Count > 0) { associatedInstance.ContentPage.AddSelectedItemsOnUi(copiedListedItems); associatedInstance.ContentPage.FocusSelectedItems(); } } } progress?.Report(100.0f); var pathWithType = new PathWithType( copiedItem != null ? (!string.IsNullOrWhiteSpace(copiedItem.Path) ? copiedItem.Path : destination) : destination, source.ItemType); return(new StorageHistory(FileOperationType.Copy, source, pathWithType)); }