Exemplo n.º 1
0
        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));
        }
Exemplo n.º 2
0
        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));
        }