示例#1
0
 public override IAsyncOperation <BaseStorageFile> CopyAsync(IStorageFolder destinationFolder, string desiredNewName, NameCollisionOption option)
 {
     return(AsyncInfo.Run <BaseStorageFile>(async(cancellationToken) =>
     {
         if (string.IsNullOrEmpty(destinationFolder.Path))
         {
             throw new NotSupportedException();
         }
         var destination = IO.Path.Combine(destinationFolder.Path, desiredNewName);
         var destFile = new NativeStorageFile(destination, desiredNewName, DateTime.Now);
         if (!IsAlternateStream)
         {
             if (!await Task.Run(() => NativeFileOperationsHelper.CopyFileFromApp(Path, destination, option != NameCollisionOption.ReplaceExisting)))
             {
                 throw new Win32Exception(Marshal.GetLastWin32Error());
             }
         }
         else
         {
             destFile.CreateFile();
             using (var inStream = await this.OpenStreamForReadAsync())
                 using (var outStream = await destFile.OpenStreamForWriteAsync())
                 {
                     await inStream.CopyToAsync(outStream);
                     await outStream.FlushAsync();
                 }
         }
         return destFile;
     }));
 }
示例#2
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));

            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
                {
                    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)
                    {
                        progress?.Report(100.0f);
                        errorCode?.Report(FilesystemErrorCode.ERROR_INPROGRESS | FilesystemErrorCode.ERROR_SUCCESS);
                    }
                    else
                    {
                        progress?.Report(100.0f);
                        errorCode?.Report(FilesystemErrorCode.ERROR_INPROGRESS | FilesystemErrorCode.ERROR_GENERIC);
                    }
                    return(null);
                }
                else
                {
                    var fsSourceFolder = await source.ToStorageItemResult(associatedInstance);

                    var fsDestinationFolder = await associatedInstance.FilesystemViewModel.GetFolderFromPathAsync(Path.GetDirectoryName(destination));

                    var fsResult = (FilesystemResult)(fsSourceFolder.ErrorCode | fsDestinationFolder.ErrorCode);

                    if (fsResult)
                    {
                        var fsCopyResult = await FilesystemTasks.Wrap(() => CloneDirectoryAsync((StorageFolder)fsSourceFolder, (StorageFolder)fsDestinationFolder, fsSourceFolder.Result.Name, CreationCollisionOption.FailIfExists));

                        if (fsCopyResult == FilesystemErrorCode.ERROR_ALREADYEXIST)
                        {
                            var ItemAlreadyExistsDialog = new ContentDialog()
                            {
                                Title               = "ItemAlreadyExistsDialogTitle".GetLocalized(),
                                Content             = "ItemAlreadyExistsDialogContent".GetLocalized(),
                                PrimaryButtonText   = "ItemAlreadyExistsDialogPrimaryButtonText".GetLocalized(),
                                SecondaryButtonText = "ItemAlreadyExistsDialogSecondaryButtonText".GetLocalized(),
                                CloseButtonText     = "ItemAlreadyExistsDialogCloseButtonText".GetLocalized()
                            };

                            ContentDialogResult result = await ItemAlreadyExistsDialog.ShowAsync();

                            if (result == ContentDialogResult.Primary)
                            {
                                fsCopyResult = await FilesystemTasks.Wrap(() => CloneDirectoryAsync((StorageFolder)fsSourceFolder, (StorageFolder)fsDestinationFolder, fsSourceFolder.Result.Name, CreationCollisionOption.GenerateUniqueName));
                            }
                            else if (result == ContentDialogResult.Secondary)
                            {
                                fsCopyResult = await FilesystemTasks.Wrap(() => CloneDirectoryAsync((StorageFolder)fsSourceFolder, (StorageFolder)fsDestinationFolder, fsSourceFolder.Result.Name, CreationCollisionOption.ReplaceExisting));

                                return(null); // Cannot undo overwrite operation
                            }
                            else
                            {
                                return(null);
                            }
                        }
                        if (fsCopyResult)
                        {
                            if (associatedInstance.FilesystemViewModel.CheckFolderForHiddenAttribute(source.Path))
                            {
                                // The source folder was hidden, apply hidden attribute to destination
                                NativeFileOperationsHelper.SetFileAttribute(fsCopyResult.Result.Path, FileAttributes.Hidden);
                            }
                            copiedItem = (StorageFolder)fsCopyResult;
                        }
                        fsResult = fsCopyResult;
                    }
                    errorCode?.Report(fsResult.ErrorCode);
                    if (!fsResult)
                    {
                        return(null);
                    }
                }
            }
            else if (source.ItemType == FilesystemItemType.File)
            {
                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.FailIfExists).AsTask());

                    if (fsResultCopy == FilesystemErrorCode.ERROR_ALREADYEXIST)
                    {
                        var ItemAlreadyExistsDialog = new ContentDialog()
                        {
                            Title               = "ItemAlreadyExistsDialogTitle".GetLocalized(),
                            Content             = "ItemAlreadyExistsDialogContent".GetLocalized(),
                            PrimaryButtonText   = "ItemAlreadyExistsDialogPrimaryButtonText".GetLocalized(),
                            SecondaryButtonText = "ItemAlreadyExistsDialogSecondaryButtonText".GetLocalized(),
                            CloseButtonText     = "ItemAlreadyExistsDialogCloseButtonText".GetLocalized()
                        };

                        ContentDialogResult result = await ItemAlreadyExistsDialog.ShowAsync();

                        if (result == ContentDialogResult.Primary)
                        {
                            fsResultCopy = await FilesystemTasks.Wrap(() => file.CopyAsync(destinationResult.Result, Path.GetFileName(file.Name), NameCollisionOption.GenerateUniqueName).AsTask());
                        }
                        else if (result == ContentDialogResult.Secondary)
                        {
                            fsResultCopy = await FilesystemTasks.Wrap(() => file.CopyAsync(destinationResult.Result, Path.GetFileName(file.Name), NameCollisionOption.ReplaceExisting).AsTask());

                            return(null); // Cannot undo overwrite operation
                        }
                        else
                        {
                            return(null);
                        }
                    }
                    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 (!fsResult)
                {
                    return(null);
                }
            }

            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(IStorageItemWithPath source,
                                                      string destination,
                                                      NameCollisionOption collision,
                                                      IProgress <float> progress,
                                                      IProgress <FileSystemStatusCode> errorCode,
                                                      CancellationToken cancellationToken)
        {
            if (associatedInstance.FilesystemViewModel.WorkingDirectory.StartsWith(App.AppSettings.RecycleBinPath))
            {
                errorCode?.Report(FileSystemStatusCode.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));

            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
                {
                    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)
                    {
                        progress?.Report(100.0f);
                        errorCode?.Report(FileSystemStatusCode.InProgress | FileSystemStatusCode.Success);
                    }
                    else
                    {
                        progress?.Report(100.0f);
                        errorCode?.Report(FileSystemStatusCode.InProgress | FileSystemStatusCode.Generic);
                    }
                    return(null);
                }
                else
                {
                    // CopyFileFromApp only works on file not directories
                    var fsSourceFolder = await source.ToStorageItemResult(associatedInstance);

                    var fsDestinationFolder = await associatedInstance.FilesystemViewModel.GetFolderFromPathAsync(Path.GetDirectoryName(destination));

                    var fsResult = (FilesystemResult)(fsSourceFolder.ErrorCode | fsDestinationFolder.ErrorCode);

                    if (fsResult)
                    {
                        var fsCopyResult = await FilesystemTasks.Wrap(() => CloneDirectoryAsync((StorageFolder)fsSourceFolder, (StorageFolder)fsDestinationFolder, fsSourceFolder.Result.Name, collision.Convert()));

                        if (fsCopyResult == FileSystemStatusCode.AlreadyExists)
                        {
                            errorCode?.Report(FileSystemStatusCode.AlreadyExists);
                            progress?.Report(100.0f);
                            return(null);
                        }

                        if (fsCopyResult)
                        {
                            if (FolderHelpers.CheckFolderForHiddenAttribute(source.Path))
                            {
                                // The source folder was hidden, apply hidden attribute to destination
                                NativeFileOperationsHelper.SetFileAttribute(fsCopyResult.Result.Path, FileAttributes.Hidden);
                            }
                            copiedItem = (StorageFolder)fsCopyResult;
                        }
                        fsResult = fsCopyResult;
                    }
                    if (fsResult == FileSystemStatusCode.Unauthorized)
                    {
                        fsResult = await PerformAdminOperation(new ValueSet()
                        {
                            { "Arguments", "FileOperation" },
                            { "fileop", "CopyItem" },
                            { "filepath", source.Path },
                            { "destpath", destination },
                            { "overwrite", collision == NameCollisionOption.ReplaceExisting }
                        });
                    }
                    errorCode?.Report(fsResult.ErrorCode);
                    if (!fsResult)
                    {
                        return(null);
                    }
                }
            }
            else if (source.ItemType == FilesystemItemType.File)
            {
                var fsResult = (FilesystemResult)await Task.Run(() => NativeFileOperationsHelper.CopyFileFromApp(source.Path, destination, true));

                if (!fsResult)
                {
                    Debug.WriteLine(System.Runtime.InteropServices.Marshal.GetLastWin32Error());

                    FilesystemResult <StorageFolder> destinationResult = await associatedInstance.FilesystemViewModel.GetFolderFromPathAsync(Path.GetDirectoryName(destination));

                    var sourceResult = await source.ToStorageItemResult(associatedInstance);

                    fsResult = sourceResult.ErrorCode | destinationResult.ErrorCode;

                    if (fsResult)
                    {
                        var file         = (StorageFile)sourceResult;
                        var fsResultCopy = await FilesystemTasks.Wrap(() => file.CopyAsync(destinationResult.Result, Path.GetFileName(file.Name), collision).AsTask());

                        if (fsResultCopy == FileSystemStatusCode.AlreadyExists)
                        {
                            errorCode?.Report(FileSystemStatusCode.AlreadyExists);
                            progress?.Report(100.0f);
                            return(null);
                        }

                        if (fsResultCopy)
                        {
                            copiedItem = fsResultCopy.Result;
                        }
                        fsResult = fsResultCopy;
                    }
                    if (fsResult == FileSystemStatusCode.Unauthorized)
                    {
                        fsResult = await PerformAdminOperation(new ValueSet()
                        {
                            { "Arguments", "FileOperation" },
                            { "fileop", "CopyItem" },
                            { "filepath", source.Path },
                            { "destpath", destination },
                            { "overwrite", collision == NameCollisionOption.ReplaceExisting }
                        });
                    }
                }
                errorCode?.Report(fsResult.ErrorCode);
                if (!fsResult)
                {
                    return(null);
                }
            }

            if (Path.GetDirectoryName(destination) == associatedInstance.FilesystemViewModel.WorkingDirectory)
            {
                await Windows.ApplicationModel.Core.CoreApplication.MainView.DispatcherQueue.EnqueueAsync(async() =>
                {
                    await Task.Delay(50); // Small delay for the item to appear in the file list
                    List <ListedItem> copiedListedItems = associatedInstance.FilesystemViewModel.FilesAndFolders
                                                          .Where(listedItem => destination.Contains(listedItem.ItemPath)).ToList();

                    if (copiedListedItems.Count > 0)
                    {
                        itemManipulationModel.AddSelectedItems(copiedListedItems);
                        itemManipulationModel.FocusSelectedItems();
                    }
                }, Windows.System.DispatcherQueuePriority.Low);
            }

            progress?.Report(100.0f);

            if (collision == NameCollisionOption.ReplaceExisting)
            {
                errorCode?.Report(FileSystemStatusCode.Success);

                return(null); // Cannot undo overwrite operation
            }

            var pathWithType = copiedItem.FromStorageItem(destination, source.ItemType);

            return(new StorageHistory(FileOperationType.Copy, source, pathWithType));
        }
示例#4
0
文件: Paste.cs 项目: mokeyjay/Files
        private async Task PasteItemAsync(DataPackageView packageView, string destinationPath, DataPackageOperation acceptedOperation, IShellPage AppInstance, IProgress <uint> progress)
        {
            if (!packageView.Contains(StandardDataFormats.StorageItems))
            {
                // Happens if you copy some text and then you Ctrl+V in FilesUWP
                // Should this be done in ModernShellPage?
                return;
            }

            IReadOnlyList <IStorageItem> itemsToPaste = await packageView.GetStorageItemsAsync();

            if (AppInstance.FilesystemViewModel.WorkingDirectory.StartsWith(App.AppSettings.RecycleBinPath))
            {
                // Do not paste files and folders inside the recycle bin
                await DialogDisplayHelper.ShowDialogAsync("ErrorDialogThisActionCannotBeDone".GetLocalized(), "ErrorDialogUnsupportedOperation".GetLocalized());

                return;
            }

            List <IStorageItem>    pastedSourceItems = new List <IStorageItem>();
            HashSet <IStorageItem> pastedItems       = new HashSet <IStorageItem>();
            var  totalItemsSize       = CalculateTotalItemsSize(itemsToPaste);
            bool isItemSizeUnreported = totalItemsSize <= 0;

            foreach (IStorageItem item in itemsToPaste)
            {
                if (item.IsOfType(StorageItemTypes.Folder))
                {
                    if (!string.IsNullOrEmpty(item.Path) && destinationPath.IsSubPathOf(item.Path))
                    {
                        ImpossibleActionResponseTypes responseType = ImpossibleActionResponseTypes.Abort;

                        /// 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)
                        {
                            continue;
                        }
                        else if (responseType == ImpossibleActionResponseTypes.Abort)
                        {
                            return;
                        }
                    }
                    else
                    {
                        if (!isItemSizeUnreported)
                        {
                            var pastedItemSize = await Task.Run(() => CalculateTotalItemsSize(pastedSourceItems));

                            uint progressValue = (uint)(pastedItemSize * 100 / totalItemsSize);
                            progress.Report(progressValue);
                        }

                        await AppInstance.FilesystemViewModel.GetFolderFromPathAsync(destinationPath)
                        .OnSuccess(t => CloneDirectoryAsync((StorageFolder)item, t, item.Name))
                        .OnSuccess(t =>
                        {
                            pastedSourceItems.Add(item);
                            pastedItems.Add(t);
                        });
                    }
                }
                else if (item.IsOfType(StorageItemTypes.File))
                {
                    if (!isItemSizeUnreported)
                    {
                        var pastedItemSize = await Task.Run(() => CalculateTotalItemsSize(pastedSourceItems));

                        uint progressValue = (uint)(pastedItemSize * 100 / totalItemsSize);
                        progress.Report(progressValue);
                    }

                    var res = await AppInstance.FilesystemViewModel.GetFolderFromPathAsync(destinationPath);

                    if (res)
                    {
                        StorageFile clipboardFile = (StorageFile)item;
                        var         pasted        = await FilesystemTasks.Wrap(() => clipboardFile.CopyAsync(res.Result, item.Name, NameCollisionOption.GenerateUniqueName).AsTask());

                        if (pasted)
                        {
                            pastedSourceItems.Add(item);
                            pastedItems.Add(pasted.Result);
                        }
                        else if (pasted.ErrorCode == FilesystemErrorCode.ERROR_UNAUTHORIZED)
                        {
                            // Try again with CopyFileFromApp
                            if (NativeFileOperationsHelper.CopyFileFromApp(item.Path, Path.Combine(destinationPath, item.Name), true))
                            {
                                pastedSourceItems.Add(item);
                            }
                            else
                            {
                                Debug.WriteLine(System.Runtime.InteropServices.Marshal.GetLastWin32Error());
                            }
                        }
                        else if (pasted.ErrorCode == FilesystemErrorCode.ERROR_NOTFOUND)
                        {
                            // File was moved/deleted in the meantime
                            continue;
                        }
                    }
                }
            }
            if (!isItemSizeUnreported)
            {
                var finalPastedItemSize = await Task.Run(() => CalculateTotalItemsSize(pastedSourceItems));

                uint finalProgressValue = (uint)(finalPastedItemSize * 100 / totalItemsSize);
                progress.Report(finalProgressValue);
            }
            else
            {
                progress.Report(100);
            }

            if (acceptedOperation == DataPackageOperation.Move)
            {
                foreach (IStorageItem item in pastedSourceItems)
                {
                    var deleted = (FilesystemResult)false;
                    if (string.IsNullOrEmpty(item.Path))
                    {
                        // Can't move (only copy) files from MTP devices because:
                        // StorageItems returned in DataPackageView are read-only
                        // The item.Path property will be empty and there's no way of retrieving a new StorageItem with R/W access
                        continue;
                    }
                    if (item.IsOfType(StorageItemTypes.File))
                    {
                        // If we reached this we are not in an MTP device, using StorageFile.* is ok here
                        deleted = await AppInstance.FilesystemViewModel.GetFileFromPathAsync(item.Path)
                                  .OnSuccess(t => t.DeleteAsync(StorageDeleteOption.PermanentDelete).AsTask());
                    }
                    else if (item.IsOfType(StorageItemTypes.Folder))
                    {
                        // If we reached this we are not in an MTP device, using StorageFolder.* is ok here
                        deleted = await AppInstance.FilesystemViewModel.GetFolderFromPathAsync(item.Path)
                                  .OnSuccess(t => t.DeleteAsync(StorageDeleteOption.PermanentDelete).AsTask());
                    }

                    if (deleted == FilesystemErrorCode.ERROR_UNAUTHORIZED)
                    {
                        // Try again with DeleteFileFromApp
                        if (!NativeFileOperationsHelper.DeleteFileFromApp(item.Path))
                        {
                            Debug.WriteLine(System.Runtime.InteropServices.Marshal.GetLastWin32Error());
                        }
                    }
                    else if (deleted == FilesystemErrorCode.ERROR_NOTFOUND)
                    {
                        // File or Folder was moved/deleted in the meantime
                        continue;
                    }
                }
            }

            if (destinationPath == AppInstance.FilesystemViewModel.WorkingDirectory)
            {
                List <string>     pastedItemPaths = pastedItems.Select(item => item.Path).ToList();
                List <ListedItem> copiedItems     = AppInstance.FilesystemViewModel.FilesAndFolders.Where(listedItem => pastedItemPaths.Contains(listedItem.ItemPath)).ToList();
                if (copiedItems.Any())
                {
                    AppInstance.ContentPage.SetSelectedItemsOnUi(copiedItems);
                    AppInstance.ContentPage.FocusSelectedItems();
                }
            }
            packageView.ReportOperationCompleted(acceptedOperation);
        }
示例#5
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));
        }