public override IAsyncAction DeleteAsync() { return(AsyncInfo.Run(async(cancellationToken) => { if (!NativeFileOperationsHelper.DeleteFileFromApp(Path)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } })); }
public static void WriteFileTag(string filePath, string tag) { if (tag == null) { NativeFileOperationsHelper.DeleteFileFromApp($"{filePath}:files"); } else if (ReadFileTag(filePath) != tag) { NativeFileOperationsHelper.WriteStringToFile($"{filePath}:files", tag); } }
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> DeleteAsync(IStorageItemWithPath source, IProgress <float> progress, IProgress <FileSystemStatusCode> errorCode, bool permanently, CancellationToken cancellationToken) { bool deleteFromRecycleBin = recycleBinHelpers.IsPathUnderRecycleBin(source.Path); FilesystemResult fsResult = FileSystemStatusCode.InProgress; errorCode?.Report(fsResult); progress?.Report(0.0f); if (permanently) { fsResult = (FilesystemResult)NativeFileOperationsHelper.DeleteFileFromApp(source.Path); } if (!fsResult) { if (source.ItemType == FilesystemItemType.File) { fsResult = await associatedInstance.FilesystemViewModel.GetFileFromPathAsync(source.Path) .OnSuccess((t) => t.DeleteAsync(permanently ? StorageDeleteOption.PermanentDelete : StorageDeleteOption.Default).AsTask()); } else if (source.ItemType == FilesystemItemType.Directory) { fsResult = await associatedInstance.FilesystemViewModel.GetFolderFromPathAsync(source.Path) .OnSuccess((t) => t.DeleteAsync(permanently ? StorageDeleteOption.PermanentDelete : StorageDeleteOption.Default).AsTask()); } } errorCode?.Report(fsResult); if (fsResult == FileSystemStatusCode.Unauthorized) { // Try again with fulltrust process (non admin: for shortcuts and hidden files) if (associatedInstance.ServiceConnection != null) { var(status, response) = await associatedInstance.ServiceConnection.SendMessageForResponseAsync(new ValueSet() { { "Arguments", "FileOperation" }, { "fileop", "DeleteItem" }, { "filepath", source.Path }, { "permanently", permanently } }); fsResult = (FilesystemResult)(status == AppServiceResponseStatus.Success && response.Get("Success", false)); } if (!fsResult) { fsResult = await PerformAdminOperation(new ValueSet() { { "Arguments", "FileOperation" }, { "fileop", "DeleteItem" }, { "filepath", source.Path }, { "permanently", permanently } }); } } else if (fsResult == FileSystemStatusCode.InUse) { // TODO: retry or show dialog await DialogDisplayHelper.ShowDialogAsync("FileInUseDeleteDialog/Title".GetLocalized(), "FileInUseDeleteDialog/Text".GetLocalized()); } if (deleteFromRecycleBin) { // 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(t => t.DeleteAsync(StorageDeleteOption.PermanentDelete).AsTask()); } errorCode?.Report(fsResult); progress?.Report(100.0f); if (fsResult) { await associatedInstance.FilesystemViewModel.RemoveFileOrFolderAsync(source.Path); if (!permanently) { // Enumerate Recycle Bin List <ShellFileItem> items = await recycleBinHelpers.EnumerateRecycleBin(); List <ShellFileItem> nameMatchItems = new List <ShellFileItem>(); // Get name matching files if (items != null) { if (Path.GetExtension(source.Path) == ".lnk" || Path.GetExtension(source.Path) == ".url") // We need to check if it is a shortcut file { nameMatchItems = items.Where((item) => item.FilePath == Path.Combine(Path.GetDirectoryName(source.Path), Path.GetFileNameWithoutExtension(source.Path))).ToList(); } else { nameMatchItems = items.Where((item) => item.FilePath == source.Path).ToList(); } } // Get newest file ShellFileItem item = nameMatchItems.Where((item) => item.RecycleDate != null).OrderBy((item) => item.RecycleDate).FirstOrDefault(); return(new StorageHistory(FileOperationType.Recycle, source, StorageItemHelpers.FromPathAndType(item?.RecyclePath, source.ItemType))); } return(new StorageHistory(FileOperationType.Delete, source, null)); } else { // Stop at first error return(null); } }
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); }
private async Task <FilesystemResult> DeleteItemAsync(StorageDeleteOption deleteOption, IShellPage AppInstance, IProgress <uint> progress) { var deleted = (FilesystemResult)false; var deleteFromRecycleBin = AppInstance.FilesystemViewModel.WorkingDirectory.StartsWith(App.AppSettings.RecycleBinPath); List <ListedItem> selectedItems = new List <ListedItem>(); foreach (ListedItem selectedItem in AppInstance.ContentPage.SelectedItems) { selectedItems.Add(selectedItem); } if (App.AppSettings.ShowConfirmDeleteDialog == true) //check if the setting to show a confirmation dialog is on { var dialog = new ConfirmDeleteDialog(deleteFromRecycleBin, deleteOption, AppInstance.ContentPage.SelectedItemsPropertiesViewModel); await dialog.ShowAsync(); if (dialog.Result != MyResult.Delete) //delete selected item(s) if the result is yes { return((FilesystemResult)true); //return if the result isn't delete } deleteOption = dialog.PermanentlyDelete; } int itemsDeleted = 0; foreach (ListedItem storItem in selectedItems) { uint progressValue = (uint)(itemsDeleted * 100.0 / selectedItems.Count); if (selectedItems.Count > 3) { progress.Report(progressValue); } if (storItem.PrimaryItemAttribute == StorageItemTypes.File) { deleted = await AppInstance.FilesystemViewModel.GetFileFromPathAsync(storItem.ItemPath) .OnSuccess(t => t.DeleteAsync(deleteOption).AsTask()); } else { deleted = await AppInstance.FilesystemViewModel.GetFolderFromPathAsync(storItem.ItemPath) .OnSuccess(t => t.DeleteAsync(deleteOption).AsTask()); } if (deleted.ErrorCode == FilesystemErrorCode.ERROR_UNAUTHORIZED) { if (deleteOption == StorageDeleteOption.Default) { // Try again with fulltrust process if (AppInstance.FilesystemViewModel.Connection != null) { var response = await AppInstance.FilesystemViewModel.Connection.SendMessageAsync(new ValueSet() { { "Arguments", "FileOperation" }, { "fileop", "MoveToBin" }, { "filepath", storItem.ItemPath } }); deleted = (FilesystemResult)(response.Status == Windows.ApplicationModel.AppService.AppServiceResponseStatus.Success); } } else { // Try again with DeleteFileFromApp if (!NativeFileOperationsHelper.DeleteFileFromApp(storItem.ItemPath)) { Debug.WriteLine(System.Runtime.InteropServices.Marshal.GetLastWin32Error()); } else { deleted = (FilesystemResult)true; } } } else if (deleted.ErrorCode == FilesystemErrorCode.ERROR_INUSE) { // TODO: retry or show dialog await DialogDisplayHelper.ShowDialogAsync("FileInUseDeleteDialog/Title".GetLocalized(), "FileInUseDeleteDialog/Text".GetLocalized()); } if (deleteFromRecycleBin) { // Recycle bin also stores a file starting with $I for each item var iFilePath = Path.Combine(Path.GetDirectoryName(storItem.ItemPath), Path.GetFileName(storItem.ItemPath).Replace("$R", "$I")); await AppInstance.FilesystemViewModel.GetFileFromPathAsync(iFilePath) .OnSuccess(t => t.DeleteAsync(StorageDeleteOption.PermanentDelete).AsTask()); } if (deleted) { await AppInstance.FilesystemViewModel.RemoveFileOrFolderAsync(storItem); itemsDeleted++; } else { // Stop at first error return(deleted); } } return((FilesystemResult)true); }