Skip to content

Commit 87a2659

Browse files
committed
Revert some
1 parent 2672508 commit 87a2659

File tree

3 files changed

+57
-46
lines changed

3 files changed

+57
-46
lines changed

src/Files.App/Actions/FileSystem/EmptyRecycleBinAction.cs

+5-3
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,18 @@ public async Task ExecuteAsync(object? parameter = null)
4242
Content = Strings.ConfirmEmptyBinDialogContent.GetLocalizedResource(),
4343
PrimaryButtonText = Strings.Yes.GetLocalizedResource(),
4444
SecondaryButtonText = Strings.Cancel.GetLocalizedResource(),
45-
DefaultButton = ContentDialogButton.Primary,
46-
XamlRoot = MainWindow.Instance.Content.XamlRoot
45+
DefaultButton = ContentDialogButton.Primary
4746
};
4847

48+
if (ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 8))
49+
confirmationDialog.XamlRoot = MainWindow.Instance.Content.XamlRoot;
50+
4951
if (UserSettingsService.FoldersSettingsService.DeleteConfirmationPolicy is DeleteConfirmationPolicies.Never ||
5052
await confirmationDialog.TryShowAsync() is ContentDialogResult.Primary)
5153
{
5254
var banner = StatusCenterHelper.AddCard_EmptyRecycleBin(ReturnResult.InProgress);
5355

54-
bool result = await StorageTrashBinService.EmptyTrashBin();
56+
bool result = await Task.Run(StorageTrashBinService.EmptyTrashBin);
5557

5658
StatusCenterViewModel.RemoveItem(banner);
5759

src/Files.App/Data/Contracts/IStorageTrashBinService.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public interface IStorageTrashBinService
5656
/// Deletes files and folders in Recycle Bin permanently.
5757
/// </summary>
5858
/// <returns>True if succeeded; otherwise, false</returns>
59-
Task<bool> EmptyTrashBin();
59+
bool EmptyTrashBin();
6060

6161
/// <summary>
6262
/// Restores files and folders in Recycle Bin to original paths.

src/Files.App/Services/Storage/StorageTrashBinService.cs

+51-42
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using Windows.Win32;
77
using Windows.Win32.Foundation;
88
using Windows.Win32.UI.Shell;
9+
using static Vanara.PInvoke.Ole32;
910

1011
namespace Files.App.Services
1112
{
@@ -68,68 +69,76 @@ public async Task<bool> CanGoTrashBin(string? path)
6869
}
6970

7071
/// <inheritdoc/>
71-
public async Task<bool> EmptyTrashBin()
72+
public bool EmptyTrashBin()
7273
{
73-
return await Win32Helper.StartSTATask(async () =>
74+
// TODO: Use IFileOperation instead of its wrapper for the operation status to be reported.
75+
var fRes = PInvoke.SHEmptyRecycleBin(
76+
new(),
77+
string.Empty,
78+
0x00000001 | 0x00000002 /* SHERB_NOCONFIRMATION | SHERB_NOPROGRESSUI */)
79+
.Succeeded;
80+
81+
return fRes;
82+
}
83+
84+
/// <inheritdoc/>
85+
public async Task<bool> RestoreAllTrashesAsync()
86+
{
87+
return await Win32Helper.StartSTATask(() =>
7488
{
7589
try
7690
{
77-
HRESULT hr = default;
78-
IChildFolder recycleBinFolder = new WindowsFolder(PInvoke.FOLDERID_RecycleBinFolder);
79-
using var bulkOperations = new WindowsBulkOperations(new(MainWindow.Instance.WindowHandle), FILEOPERATION_FLAGS.FOF_NO_UI);
80-
81-
await foreach (WindowsStorable item in recycleBinFolder.GetItemsAsync())
82-
hr = bulkOperations.QueueDeleteOperation(item).ThrowIfFailedOnDebug();
83-
84-
// Perform the operations queued
85-
hr = bulkOperations.PerformAllOperations().ThrowIfFailedOnDebug();
86-
87-
// Update the RecycleBin folder icon
88-
PInvoke.SHUpdateRecycleBinIcon();
91+
RestoreAllTrashesInternal();
8992

9093
return true;
9194
}
92-
catch (COMException ex)
95+
catch
9396
{
94-
App.Logger.LogWarning(ex, ex.Message);
9597
return false;
9698
}
9799
});
98100
}
99101

100-
/// <inheritdoc/>
101-
public async Task<bool> RestoreAllTrashesAsync()
102+
private unsafe bool RestoreAllTrashesInternal()
102103
{
103-
return await Win32Helper.StartSTATask(async () =>
104+
// Get IShellItem for Recycle Bin folder
105+
using ComPtr<IShellItem> pRecycleBinFolderShellItem = default;
106+
HRESULT hr = PInvoke.SHGetKnownFolderItem(FOLDERID.FOLDERID_RecycleBinFolder, KNOWN_FOLDER_FLAG.KF_FLAG_DEFAULT, HANDLE.Null, IID.IID_IShellItem, (void**)pRecycleBinFolderShellItem.GetAddressOf());
107+
108+
// Get IEnumShellItems for Recycle Bin folder
109+
using ComPtr<IEnumShellItems> pEnumShellItems = default;
110+
hr = pRecycleBinFolderShellItem.Get()->BindToHandler(null, BHID.BHID_EnumItems, IID.IID_IEnumShellItems, (void**)pEnumShellItems.GetAddressOf());
111+
112+
// Initialize how to perform the operation
113+
using ComPtr<IFileOperation> pFileOperation = default;
114+
hr = PInvoke.CoCreateInstance(CLSID.CLSID_FileOperation, null, CLSCTX.CLSCTX_LOCAL_SERVER, IID.IID_IFileOperation, (void**)pFileOperation.GetAddressOf());
115+
hr = pFileOperation.Get()->SetOperationFlags(FILEOPERATION_FLAGS.FOF_NO_UI);
116+
hr = pFileOperation.Get()->SetOwnerWindow(new(MainWindow.Instance.WindowHandle));
117+
118+
using ComPtr<IShellItem> pShellItem = default;
119+
while (pEnumShellItems.Get()->Next(1, pShellItem.GetAddressOf()) == HRESULT.S_OK)
104120
{
105-
try
106-
{
107-
HRESULT hr = default;
108-
IChildFolder recycleBinFolder = new WindowsFolder(PInvoke.FOLDERID_RecycleBinFolder);
109-
using var bulkOperations = new WindowsBulkOperations(new(MainWindow.Instance.WindowHandle), FILEOPERATION_FLAGS.FOF_NO_UI);
121+
// Get the original path
122+
using ComPtr<IShellItem2> pShellItem2 = default;
123+
hr = pShellItem.Get()->QueryInterface(IID.IID_IShellItem2, (void**)pShellItem2.GetAddressOf());
124+
hr = PInvoke.PSGetPropertyKeyFromName("System.Recycle.DeletedFrom", out var originalPathPropertyKey);
125+
hr = pShellItem2.Get()->GetString(originalPathPropertyKey, out var szOriginalPath);
110126

111-
await foreach (WindowsStorable item in recycleBinFolder.GetItemsAsync())
112-
{
113-
item.GetPropertyValue("System.Recycle.DeletedFrom", out string originalLocationFolderPath);
127+
// Get IShellItem of the original path
128+
hr = PInvoke.SHCreateItemFromParsingName(szOriginalPath.ToString(), null, typeof(IShellItem).GUID, out var pOriginalPathShellItemPtr);
129+
var pOriginalPathShellItem = (IShellItem*)pOriginalPathShellItemPtr;
114130

115-
if (WindowsStorable.TryParse(originalLocationFolderPath) is WindowsFolder originalLocationFolder)
116-
hr = bulkOperations.QueueMoveOperation(item, originalLocationFolder, null).ThrowIfFailedOnDebug();
117-
}
131+
// Define the shell item to restore
132+
hr = pFileOperation.Get()->MoveItem(pShellItem.Get(), pOriginalPathShellItem, default(PCWSTR), null);
133+
}
118134

119-
// Perform the operations queued
120-
hr = bulkOperations.PerformAllOperations().ThrowIfFailedOnDebug();
135+
// Perform
136+
hr = pFileOperation.Get()->PerformOperations();
121137

122-
// Update the RecycleBin folder icon
123-
PInvoke.SHUpdateRecycleBinIcon();
138+
// Reset the icon
139+
Win32PInvoke.SHUpdateRecycleBinIcon();
124140

125-
return true;
126-
}
127-
catch (COMException ex)
128-
{
129-
App.Logger.LogWarning(ex, ex.Message);
130-
return false;
131-
}
132-
});
141+
return true;
133142
}
134143
}
135144
}

0 commit comments

Comments
 (0)