private void ViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { switch (e.PropertyName) { case "IsReadOnly": if (ViewModel.IsReadOnly) { List.ForEach(x => NativeFileOperationsHelper.SetFileAttribute( x.ItemPath, System.IO.FileAttributes.ReadOnly)); } else { List.ForEach(x => NativeFileOperationsHelper.UnsetFileAttribute( x.ItemPath, System.IO.FileAttributes.ReadOnly)); } break; case "IsHidden": if (ViewModel.IsHidden) { List.ForEach(x => NativeFileOperationsHelper.SetFileAttribute( x.ItemPath, System.IO.FileAttributes.Hidden)); } else { List.ForEach(x => NativeFileOperationsHelper.UnsetFileAttribute( x.ItemPath, System.IO.FileAttributes.Hidden)); } break; } }
private async void ViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { switch (e.PropertyName) { case "IsReadOnly": if (ViewModel.IsReadOnly) { NativeFileOperationsHelper.SetFileAttribute( Item.ItemPath, System.IO.FileAttributes.ReadOnly); } else { NativeFileOperationsHelper.UnsetFileAttribute( Item.ItemPath, System.IO.FileAttributes.ReadOnly); } break; case "IsHidden": if (ViewModel.IsHidden) { NativeFileOperationsHelper.SetFileAttribute( Item.ItemPath, System.IO.FileAttributes.Hidden); } else { NativeFileOperationsHelper.UnsetFileAttribute( Item.ItemPath, System.IO.FileAttributes.Hidden); } break; case "ShortcutItemPath": case "ShortcutItemWorkingDir": case "ShortcutItemArguments": var tmpItem = (ShortcutItem)Item; if (string.IsNullOrWhiteSpace(ViewModel.ShortcutItemPath)) { return; } var connection = await AppServiceConnectionHelper.Instance; if (connection != null) { var value = new ValueSet() { { "Arguments", "FileOperation" }, { "fileop", "UpdateLink" }, { "filepath", Item.ItemPath }, { "targetpath", ViewModel.ShortcutItemPath }, { "arguments", ViewModel.ShortcutItemArguments }, { "workingdir", ViewModel.ShortcutItemWorkingDir }, { "runasadmin", tmpItem.RunAsAdmin }, }; await connection.SendMessageAsync(value); } break; } }
public static void WriteFileTag(string filePath, string tag) { var isReadOnly = NativeFileOperationsHelper.HasFileAttribute(filePath, System.IO.FileAttributes.ReadOnly); if (isReadOnly) // Unset read-only attribute (#7534) { NativeFileOperationsHelper.UnsetFileAttribute(filePath, System.IO.FileAttributes.ReadOnly); } if (tag == null) { NativeFileOperationsHelper.DeleteFileFromApp($"{filePath}:files"); } else if (ReadFileTag(filePath) != tag) { NativeFileOperationsHelper.WriteStringToFile($"{filePath}:files", tag); } if (isReadOnly) // Restore read-only attribute (#7534) { NativeFileOperationsHelper.SetFileAttribute(filePath, System.IO.FileAttributes.ReadOnly); } }
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> 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)); }
public async Task <IStorageHistory> CopyAsync(IStorageItemWithPath source, string destination, 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, CreationCollisionOption.FailIfExists)); if (fsCopyResult == FileSystemStatusCode.AlreadyExists) { var ItemAlreadyExistsDialog = new ContentDialog() { Title = "ItemAlreadyExistsDialogTitle".GetLocalized(), Content = "ItemAlreadyExistsDialogContent".GetLocalized(), PrimaryButtonText = "ItemAlreadyExistsDialogPrimaryButtonText".GetLocalized(), SecondaryButtonText = "ItemAlreadyExistsDialogSecondaryButtonText".GetLocalized(), CloseButtonText = "ItemAlreadyExistsDialogCloseButtonText".GetLocalized() }; if (Interacts.Interaction.IsAnyContentDialogOpen()) { // Only a single ContentDialog can be open at any time. return(null); } 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 (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; } 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), NameCollisionOption.FailIfExists).AsTask()); if (fsResultCopy == FileSystemStatusCode.AlreadyExists) { var ItemAlreadyExistsDialog = new ContentDialog() { Title = "ItemAlreadyExistsDialogTitle".GetLocalized(), Content = "ItemAlreadyExistsDialogContent".GetLocalized(), PrimaryButtonText = "ItemAlreadyExistsDialogPrimaryButtonText".GetLocalized(), SecondaryButtonText = "ItemAlreadyExistsDialogSecondaryButtonText".GetLocalized(), CloseButtonText = "ItemAlreadyExistsDialogCloseButtonText".GetLocalized() }; if (Interacts.Interaction.IsAnyContentDialogOpen()) { // Only a single ContentDialog can be open at any time. return(null); } 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; } } errorCode?.Report(fsResult.ErrorCode); if (!fsResult) { return(null); } } if (Path.GetDirectoryName(destination) == associatedInstance.FilesystemViewModel.WorkingDirectory) { _ = Windows.ApplicationModel.Core.CoreApplication.MainView.ExecuteOnUIThreadAsync(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) { associatedInstance.ContentPage.AddSelectedItemsOnUi(copiedListedItems); associatedInstance.ContentPage.FocusSelectedItems(); } }, Windows.UI.Core.CoreDispatcherPriority.Low); } progress?.Report(100.0f); var pathWithType = copiedItem.FromStorageItem(destination, source.ItemType); return(new StorageHistory(FileOperationType.Copy, source, pathWithType)); }
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 => { if (AppInstance.FilesystemViewModel.CheckFolderForHiddenAttribute(item.Path)) { // The source folder was hidden, apply hidden attribute to destination NativeFileOperationsHelper.SetFileAttribute(t.Path, FileAttributes.Hidden); } 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 fulltrust process if (AppInstance.FilesystemViewModel.Connection != null) { var response = await AppInstance.FilesystemViewModel.Connection.SendMessageAsync(new ValueSet() { { "Arguments", "FileOperation" }, { "fileop", "DeleteItem" }, { "filepath", item.Path }, { "permanently", true } }); deleted = (FilesystemResult)(response.Status == Windows.ApplicationModel.AppService.AppServiceResponseStatus.Success); } } 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); }
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)); }