public override IAsyncAction RenameAsync(string desiredName, NameCollisionOption option) { return(AsyncInfo.Run(async(cancellationToken) => { string destination = IO.Path.Combine(IO.Path.GetDirectoryName(Path), desiredName); var destFile = new NativeStorageFile(destination, desiredName, DateTime.Now); if (!IsAlternateStream) { if (!await Task.Run(() => NativeFileOperationsHelper.MoveFileFromApp(Path, destination))) { 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(); } await DeleteAsync(); } })); }
public override IAsyncAction MoveAsync(IStorageFolder destinationFolder, string desiredNewName, NameCollisionOption option) { return(AsyncInfo.Run(async(cancellationToken) => { if (string.IsNullOrEmpty(destinationFolder.Path)) { throw new NotSupportedException(); } var destination = IO.Path.Combine(destinationFolder.Path, desiredNewName); if (!IsAlternateStream) { if (!await Task.Run(() => NativeFileOperationsHelper.MoveFileFromApp(Path, destination))) { throw new Win32Exception(Marshal.GetLastWin32Error()); } } else { await CopyAsync(destinationFolder, desiredNewName, option); await DeleteAsync(); } })); }
public async Task <IStorageHistory> RestoreFromTrashAsync(IStorageItemWithPath source, string destination, IProgress <float> progress, IProgress <FilesystemErrorCode> errorCode, CancellationToken cancellationToken) { FilesystemResult fsResult = FilesystemErrorCode.ERROR_INPROGRESS; errorCode?.Report(fsResult); if (source.ItemType == FilesystemItemType.Directory) { FilesystemResult <StorageFolder> sourceFolder = await associatedInstance.FilesystemViewModel.GetFolderFromPathAsync(source.Path); FilesystemResult <StorageFolder> destinationFolder = await associatedInstance.FilesystemViewModel.GetFolderFromPathAsync(Path.GetDirectoryName(destination)); fsResult = sourceFolder.ErrorCode | destinationFolder.ErrorCode; errorCode?.Report(fsResult); if (fsResult) { fsResult = await FilesystemTasks.Wrap(() => { return(MoveDirectoryAsync(sourceFolder.Result, destinationFolder.Result, Path.GetFileName(destination), CreationCollisionOption.FailIfExists)); }).OnSuccess(t => sourceFolder.Result.DeleteAsync(StorageDeleteOption.PermanentDelete).AsTask()); // TODO: we could use here FilesystemHelpers with registerHistory false? } errorCode?.Report(fsResult); } else { FilesystemResult <StorageFile> sourceFile = await associatedInstance.FilesystemViewModel.GetFileFromPathAsync(source.Path); FilesystemResult <StorageFolder> destinationFolder = await associatedInstance.FilesystemViewModel.GetFolderFromPathAsync(Path.GetDirectoryName(destination)); fsResult = sourceFile.ErrorCode | destinationFolder.ErrorCode; errorCode?.Report(fsResult); if (fsResult) { fsResult = await FilesystemTasks.Wrap(() => { return(sourceFile.Result.MoveAsync(destinationFolder.Result, Path.GetFileName(destination), NameCollisionOption.GenerateUniqueName).AsTask()); }); } else if (fsResult == FilesystemErrorCode.ERROR_UNAUTHORIZED) { // Try again with MoveFileFromApp fsResult = (FilesystemResult)NativeFileOperationsHelper.MoveFileFromApp(source.Path, destination); } errorCode?.Report(fsResult); } if (fsResult) { // Recycle bin also stores a file starting with $I for each item string iFilePath = Path.Combine(Path.GetDirectoryName(source.Path), Path.GetFileName(source.Path).Replace("$R", "$I")); await associatedInstance.FilesystemViewModel.GetFileFromPathAsync(iFilePath) .OnSuccess(iFile => iFile.DeleteAsync().AsTask()); } errorCode?.Report(fsResult); if (fsResult != FilesystemErrorCode.ERROR_SUCCESS) { if (((FilesystemErrorCode)fsResult).HasFlag(FilesystemErrorCode.ERROR_UNAUTHORIZED)) { await DialogDisplayHelper.ShowDialogAsync("AccessDeniedDeleteDialog/Title".GetLocalized(), "AccessDeniedDeleteDialog/Text".GetLocalized()); } else if (((FilesystemErrorCode)fsResult).HasFlag(FilesystemErrorCode.ERROR_UNAUTHORIZED)) { await DialogDisplayHelper.ShowDialogAsync("FileNotFoundDialog/Title".GetLocalized(), "FileNotFoundDialog/Text".GetLocalized()); } else if (((FilesystemErrorCode)fsResult).HasFlag(FilesystemErrorCode.ERROR_ALREADYEXIST)) { await DialogDisplayHelper.ShowDialogAsync("ItemAlreadyExistsDialogTitle".GetLocalized(), "ItemAlreadyExistsDialogContent".GetLocalized()); } } return(new StorageHistory(FileOperationType.Restore, source, StorageItemHelpers.FromPathAndType(destination, source.ItemType))); }
public async Task <IStorageHistory> RenameAsync(IStorageItemWithPath source, string newName, NameCollisionOption collision, IProgress <FilesystemErrorCode> errorCode, CancellationToken cancellationToken) { if (Path.GetFileName(source.Path) == newName && collision == NameCollisionOption.FailIfExists) { errorCode?.Report(FilesystemErrorCode.ERROR_ALREADYEXIST); return(null); } if (!string.IsNullOrWhiteSpace(newName) && !FilesystemHelpers.ContainsRestrictedCharacters(newName) && !FilesystemHelpers.ContainsRestrictedFileName(newName)) { var renamed = await source.ToStorageItemResult(associatedInstance) .OnSuccess(async(t) => { await t.RenameAsync(newName, collision); return(t); }); if (renamed) { errorCode?.Report(FilesystemErrorCode.ERROR_SUCCESS); return(new StorageHistory(FileOperationType.Rename, source, renamed.Result.FromStorageItem())); } else if (renamed == FilesystemErrorCode.ERROR_UNAUTHORIZED) { // Try again with MoveFileFromApp var destination = Path.Combine(Path.GetDirectoryName(source.Path), newName); if (NativeFileOperationsHelper.MoveFileFromApp(source.Path, destination)) { errorCode?.Report(FilesystemErrorCode.ERROR_SUCCESS); return(new StorageHistory(FileOperationType.Rename, source, StorageItemHelpers.FromPathAndType(destination, source.ItemType))); } else { Debug.WriteLine(System.Runtime.InteropServices.Marshal.GetLastWin32Error()); } } else if (renamed == FilesystemErrorCode.ERROR_NOTAFILE || renamed == FilesystemErrorCode.ERROR_NOTAFOLDER) { await DialogDisplayHelper.ShowDialogAsync("RenameError/NameInvalid/Title".GetLocalized(), "RenameError/NameInvalid/Text".GetLocalized()); } else if (renamed == FilesystemErrorCode.ERROR_NAMETOOLONG) { await DialogDisplayHelper.ShowDialogAsync("RenameError/TooLong/Title".GetLocalized(), "RenameError/TooLong/Text".GetLocalized()); } else if (renamed == FilesystemErrorCode.ERROR_INUSE) { // TODO: proper dialog, retry await DialogDisplayHelper.ShowDialogAsync("FileInUseDeleteDialog/Title".GetLocalized(), ""); } else if (renamed == FilesystemErrorCode.ERROR_NOTFOUND) { await DialogDisplayHelper.ShowDialogAsync("RenameError/ItemDeleted/Title".GetLocalized(), "RenameError/ItemDeleted/Text".GetLocalized()); } else if (renamed == 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) { return(await RenameAsync(source, newName, NameCollisionOption.GenerateUniqueName, errorCode, cancellationToken)); } else if (result == ContentDialogResult.Secondary) { return(await RenameAsync(source, newName, NameCollisionOption.ReplaceExisting, errorCode, cancellationToken)); } } errorCode?.Report(renamed); } return(null); }
public async Task <IStorageHistory> RestoreFromTrashAsync(IStorageItemWithPath source, string destination, IProgress <float> progress, IProgress <FileSystemStatusCode> errorCode, CancellationToken cancellationToken) { FilesystemResult fsResult = FileSystemStatusCode.InProgress; errorCode?.Report(fsResult); fsResult = (FilesystemResult)await Task.Run(() => NativeFileOperationsHelper.MoveFileFromApp(source.Path, destination)); if (!fsResult) { if (source.ItemType == FilesystemItemType.Directory) { FilesystemResult <StorageFolder> sourceFolder = await associatedInstance.FilesystemViewModel.GetFolderFromPathAsync(source.Path); FilesystemResult <StorageFolder> destinationFolder = await associatedInstance.FilesystemViewModel.GetFolderFromPathAsync(Path.GetDirectoryName(destination)); fsResult = sourceFolder.ErrorCode | destinationFolder.ErrorCode; errorCode?.Report(fsResult); if (fsResult) { fsResult = await FilesystemTasks.Wrap(() => MoveDirectoryAsync(sourceFolder.Result, destinationFolder.Result, Path.GetFileName(destination), CreationCollisionOption.FailIfExists, true)); // TODO: we could use here FilesystemHelpers with registerHistory false? } errorCode?.Report(fsResult); } else { FilesystemResult <StorageFile> sourceFile = await associatedInstance.FilesystemViewModel.GetFileFromPathAsync(source.Path); FilesystemResult <StorageFolder> destinationFolder = await associatedInstance.FilesystemViewModel.GetFolderFromPathAsync(Path.GetDirectoryName(destination)); fsResult = sourceFile.ErrorCode | destinationFolder.ErrorCode; errorCode?.Report(fsResult); if (fsResult) { fsResult = await FilesystemTasks.Wrap(() => sourceFile.Result.MoveAsync(destinationFolder.Result, Path.GetFileName(destination), NameCollisionOption.GenerateUniqueName).AsTask()); } errorCode?.Report(fsResult); } if (fsResult == FileSystemStatusCode.Unauthorized || fsResult == FileSystemStatusCode.ReadOnly) { fsResult = await PerformAdminOperation(new ValueSet() { { "Arguments", "FileOperation" }, { "fileop", "MoveItem" }, { "filepath", source.Path }, { "destpath", destination }, { "overwrite", false } }); } } if (fsResult) { // Recycle bin also stores a file starting with $I for each item string iFilePath = Path.Combine(Path.GetDirectoryName(source.Path), Path.GetFileName(source.Path).Replace("$R", "$I")); await associatedInstance.FilesystemViewModel.GetFileFromPathAsync(iFilePath) .OnSuccess(iFile => iFile.DeleteAsync().AsTask()); } errorCode?.Report(fsResult); if (fsResult != FileSystemStatusCode.Success) { if (((FileSystemStatusCode)fsResult).HasFlag(FileSystemStatusCode.Unauthorized)) { await DialogDisplayHelper.ShowDialogAsync("AccessDeniedDeleteDialog/Title".GetLocalized(), "AccessDeniedDeleteDialog/Text".GetLocalized()); } else if (((FileSystemStatusCode)fsResult).HasFlag(FileSystemStatusCode.Unauthorized)) { await DialogDisplayHelper.ShowDialogAsync("FileNotFoundDialog/Title".GetLocalized(), "FileNotFoundDialog/Text".GetLocalized()); } else if (((FileSystemStatusCode)fsResult).HasFlag(FileSystemStatusCode.AlreadyExists)) { await DialogDisplayHelper.ShowDialogAsync("ItemAlreadyExistsDialogTitle".GetLocalized(), "ItemAlreadyExistsDialogContent".GetLocalized()); } } return(new StorageHistory(FileOperationType.Restore, source, StorageItemHelpers.FromPathAndType(destination, source.ItemType))); }
public async Task <IStorageHistory> RenameAsync(IStorageItemWithPath source, string newName, NameCollisionOption collision, IProgress <FileSystemStatusCode> errorCode, CancellationToken cancellationToken) { if (Path.GetFileName(source.Path) == newName && collision == NameCollisionOption.FailIfExists) { errorCode?.Report(FileSystemStatusCode.AlreadyExists); return(null); } if (!string.IsNullOrWhiteSpace(newName) && !FilesystemHelpers.ContainsRestrictedCharacters(newName) && !FilesystemHelpers.ContainsRestrictedFileName(newName)) { var renamed = await source.ToStorageItemResult(associatedInstance) .OnSuccess(async(t) => { if (t.Name.Equals(newName, StringComparison.CurrentCultureIgnoreCase)) { await t.RenameAsync(newName, NameCollisionOption.ReplaceExisting); } else { await t.RenameAsync(newName, collision); } return(t); }); if (renamed) { errorCode?.Report(FileSystemStatusCode.Success); return(new StorageHistory(FileOperationType.Rename, source, renamed.Result.FromStorageItem())); } else if (renamed == FileSystemStatusCode.Unauthorized) { // Try again with MoveFileFromApp var destination = Path.Combine(Path.GetDirectoryName(source.Path), newName); if (NativeFileOperationsHelper.MoveFileFromApp(source.Path, destination)) { errorCode?.Report(FileSystemStatusCode.Success); return(new StorageHistory(FileOperationType.Rename, source, StorageItemHelpers.FromPathAndType(destination, source.ItemType))); } else { var fsResult = await PerformAdminOperation(new ValueSet() { { "Arguments", "FileOperation" }, { "fileop", "RenameItem" }, { "filepath", source.Path }, { "newName", newName }, { "overwrite", collision == NameCollisionOption.ReplaceExisting } }); if (fsResult) { errorCode?.Report(FileSystemStatusCode.Success); return(new StorageHistory(FileOperationType.Rename, source, StorageItemHelpers.FromPathAndType(destination, source.ItemType))); } } } else if (renamed == FileSystemStatusCode.NotAFile || renamed == FileSystemStatusCode.NotAFolder) { await DialogDisplayHelper.ShowDialogAsync("RenameError/NameInvalid/Title".GetLocalized(), "RenameError/NameInvalid/Text".GetLocalized()); } else if (renamed == FileSystemStatusCode.NameTooLong) { await DialogDisplayHelper.ShowDialogAsync("RenameError/TooLong/Title".GetLocalized(), "RenameError/TooLong/Text".GetLocalized()); } else if (renamed == FileSystemStatusCode.InUse) { // TODO: proper dialog, retry await DialogDisplayHelper.ShowDialogAsync("FileInUseDeleteDialog/Title".GetLocalized(), ""); } else if (renamed == FileSystemStatusCode.NotFound) { await DialogDisplayHelper.ShowDialogAsync("RenameError/ItemDeleted/Title".GetLocalized(), "RenameError/ItemDeleted/Text".GetLocalized()); } else if (renamed == FileSystemStatusCode.AlreadyExists) { var ItemAlreadyExistsDialog = new ContentDialog() { Title = "ItemAlreadyExistsDialogTitle".GetLocalized(), Content = "ItemAlreadyExistsDialogContent".GetLocalized(), PrimaryButtonText = "ItemAlreadyExistsDialogPrimaryButtonText".GetLocalized(), SecondaryButtonText = "ItemAlreadyExistsDialogSecondaryButtonText".GetLocalized(), CloseButtonText = "ItemAlreadyExistsDialogCloseButtonText".GetLocalized() }; if (UIHelpers.IsAnyContentDialogOpen()) { // Only a single ContentDialog can be open at any time. return(null); } ContentDialogResult result = await ItemAlreadyExistsDialog.ShowAsync(); if (result == ContentDialogResult.Primary) { return(await RenameAsync(source, newName, NameCollisionOption.GenerateUniqueName, errorCode, cancellationToken)); } else if (result == ContentDialogResult.Secondary) { return(await RenameAsync(source, newName, NameCollisionOption.ReplaceExisting, errorCode, cancellationToken)); } } errorCode?.Report(renamed); } return(null); }
public async Task <IStorageHistory> MoveAsync(IStorageItemWithPath source, string destination, NameCollisionOption collision, IProgress <float> progress, IProgress <FileSystemStatusCode> errorCode, CancellationToken cancellationToken) { if (source.Path == destination) { progress?.Report(100.0f); errorCode?.Report(FileSystemStatusCode.Success); return(null); } if (string.IsNullOrWhiteSpace(source.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 return(await CopyAsync(source, destination, collision, progress, errorCode, 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 movedItem = 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 move 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 { var fsResult = (FilesystemResult)await Task.Run(() => NativeFileOperationsHelper.MoveFileFromApp(source.Path, destination)); if (!fsResult) { Debug.WriteLine(System.Runtime.InteropServices.Marshal.GetLastWin32Error()); var fsSourceFolder = await source.ToStorageItemResult(associatedInstance); var fsDestinationFolder = await associatedInstance.FilesystemViewModel.GetFolderFromPathAsync(Path.GetDirectoryName(destination)); fsResult = fsSourceFolder.ErrorCode | fsDestinationFolder.ErrorCode; if (fsResult) { var fsResultMove = await FilesystemTasks.Wrap(() => MoveDirectoryAsync((StorageFolder)fsSourceFolder, (StorageFolder)fsDestinationFolder, fsSourceFolder.Result.Name, collision.Convert(), true)); if (fsResultMove == FileSystemStatusCode.AlreadyExists) { progress?.Report(100.0f); errorCode?.Report(FileSystemStatusCode.AlreadyExists); return(null); } if (fsResultMove) { if (FolderHelpers.CheckFolderForHiddenAttribute(source.Path)) { // The source folder was hidden, apply hidden attribute to destination NativeFileOperationsHelper.SetFileAttribute(fsResultMove.Result.Path, FileAttributes.Hidden); } movedItem = (StorageFolder)fsResultMove; } fsResult = fsResultMove; } if (fsResult == FileSystemStatusCode.Unauthorized || fsResult == FileSystemStatusCode.ReadOnly) { fsResult = await PerformAdminOperation(new ValueSet() { { "Arguments", "FileOperation" }, { "fileop", "MoveItem" }, { "filepath", source.Path }, { "destpath", destination }, { "overwrite", collision == NameCollisionOption.ReplaceExisting } }); } } errorCode?.Report(fsResult.ErrorCode); } } else if (source.ItemType == FilesystemItemType.File) { var fsResult = (FilesystemResult)await Task.Run(() => NativeFileOperationsHelper.MoveFileFromApp(source.Path, destination)); 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 fsResultMove = await FilesystemTasks.Wrap(() => file.MoveAsync(destinationResult.Result, Path.GetFileName(file.Name), collision).AsTask()); if (fsResultMove == FileSystemStatusCode.AlreadyExists) { progress?.Report(100.0f); errorCode?.Report(FileSystemStatusCode.AlreadyExists); return(null); } if (fsResultMove) { movedItem = file; } fsResult = fsResultMove; } if (fsResult == FileSystemStatusCode.Unauthorized || fsResult == FileSystemStatusCode.ReadOnly) { fsResult = await PerformAdminOperation(new ValueSet() { { "Arguments", "FileOperation" }, { "fileop", "MoveItem" }, { "filepath", source.Path }, { "destpath", destination }, { "overwrite", collision == NameCollisionOption.ReplaceExisting } }); } } errorCode?.Report(fsResult.ErrorCode); } 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> movedListedItems = associatedInstance.FilesystemViewModel.FilesAndFolders .Where(listedItem => destination.Contains(listedItem.ItemPath)).ToList(); if (movedListedItems.Count > 0) { itemManipulationModel.AddSelectedItems(movedListedItems); itemManipulationModel.FocusSelectedItems(); } }, Windows.System.DispatcherQueuePriority.Low); } progress?.Report(100.0f); if (collision == NameCollisionOption.ReplaceExisting) { return(null); // Cannot undo overwrite operation } var pathWithType = movedItem.FromStorageItem(destination, source.ItemType); return(new StorageHistory(FileOperationType.Move, source, pathWithType)); }