@@ -70,6 +70,7 @@ public async Task<bool> CanGoTrashBin(string? path)
7070 /// <inheritdoc/>
7171 public bool EmptyTrashBin ( )
7272 {
73+ // TODO: Use IFileOperation instead of its wrapper for the operation status to be reported.
7374 var fRes = PInvoke . SHEmptyRecycleBin (
7475 new ( ) ,
7576 string . Empty ,
@@ -80,66 +81,70 @@ public bool EmptyTrashBin()
8081 }
8182
8283 /// <inheritdoc/>
83- public unsafe bool RestoreAllTrashes ( )
84+ public async Task < bool > RestoreAllTrashesAsync ( )
8485 {
85- IShellItem * recycleBinFolderShellItem = default ;
86- IEnumShellItems * enumShellItems = default ;
87- IFileOperation * pFileOperation = default ;
88- IShellItem * pShellItem = default ;
89-
90- try
86+ return await Win32Helper . StartSTATask ( ( ) =>
9187 {
92- // Get IShellItem for Recycle Bin
93- var recycleBinFolderId = FOLDERID . FOLDERID_RecycleBinFolder ;
94- var shellItemGuid = typeof ( IShellItem ) . GUID ;
95- PInvoke . SHGetKnownFolderItem ( & recycleBinFolderId , KNOWN_FOLDER_FLAG . KF_FLAG_DEFAULT , HANDLE . Null , & shellItemGuid , ( void * * ) & recycleBinFolderShellItem ) ;
96-
97- // Get IEnumShellItems for Recycle Bin
98- Guid enumShellItemGuid = typeof ( IEnumShellItems ) . GUID ;
99- var enumItemsBHID = BHID . BHID_EnumItems ;
100- recycleBinFolderShellItem ->BindToHandler ( null , & enumItemsBHID , & enumShellItemGuid , ( void * * ) & enumShellItems ) ;
101-
102- // Initialize how to perform the operation
103- PInvoke . CoCreateInstance ( typeof ( FileOperation ) . GUID , null , CLSCTX . CLSCTX_LOCAL_SERVER , out pFileOperation ) ;
104- pFileOperation ->SetOperationFlags ( FILEOPERATION_FLAGS . FOF_NO_UI ) ;
105- pFileOperation ->SetOwnerWindow ( new ( MainWindow . Instance . WindowHandle ) ) ;
106-
107- while ( enumShellItems ->Next ( 1 , & pShellItem ) == HRESULT . S_OK )
88+ try
10889 {
109- // Get original path
110- pShellItem ->QueryInterface ( typeof ( IShellItem2 ) . GUID , out var pShellItem2Ptr ) ;
111- var pShellItem2 = ( IShellItem2 * ) pShellItem2Ptr ;
112- PInvoke . PSGetPropertyKeyFromName ( "System.Recycle.DeletedFrom" , out var originalPathPropertyKey ) ;
113- pShellItem2 ->GetString ( originalPathPropertyKey , out var szOriginalPath ) ;
114- pShellItem2 ->Release ( ) ;
115-
116- // Get IShellItem of the original path
117- PInvoke . SHCreateItemFromParsingName ( szOriginalPath . ToString ( ) , null , typeof ( IShellItem ) . GUID , out var pOriginalPathShellItemPtr ) ;
118- var pOriginalPathShellItem = ( IShellItem * ) pOriginalPathShellItemPtr ;
119-
120- // Define to move the shell item
121- pFileOperation ->MoveItem ( pShellItem , pOriginalPathShellItem , new PCWSTR ( ) , null ) ;
122- }
90+ RestoreAllTrashesInternal ( ) ;
12391
124- // Perform
125- pFileOperation ->PerformOperations ( ) ;
126-
127- // Reset the icon
128- Win32PInvoke . SHUpdateRecycleBinIcon ( ) ;
92+ return true ;
93+ }
94+ catch
95+ {
96+ return false ;
97+ }
98+ } ) ;
99+ }
129100
130- return true ;
131- }
132- catch
133- {
134- return false ;
135- }
136- finally
101+ private unsafe bool RestoreAllTrashesInternal ( )
102+ {
103+ // Get IShellItem for Recycle Bin folder
104+ using ComPtr < IShellItem > pRecycleBinFolderShellItem = default ;
105+ var recycleBinFolderId = FOLDERID . FOLDERID_RecycleBinFolder ;
106+ var shellItemGuid = typeof ( IShellItem ) . GUID ;
107+ HRESULT hr = PInvoke . SHGetKnownFolderItem ( & recycleBinFolderId , KNOWN_FOLDER_FLAG . KF_FLAG_DEFAULT , HANDLE . Null , & shellItemGuid , ( void * * ) pRecycleBinFolderShellItem . GetAddressOf ( ) ) ;
108+
109+ // Get IEnumShellItems for Recycle Bin folder
110+ using ComPtr < IEnumShellItems > pEnumShellItems = default ;
111+ Guid enumShellItemGuid = typeof ( IEnumShellItems ) . GUID ;
112+ var enumItemsBHID = BHID . BHID_EnumItems ;
113+ hr = pRecycleBinFolderShellItem . Get ( ) ->BindToHandler ( null , & enumItemsBHID , & enumShellItemGuid , ( void * * ) pEnumShellItems . GetAddressOf ( ) ) ;
114+
115+ // Initialize how to perform the operation
116+ using ComPtr < IFileOperation > pFileOperation = default ;
117+ var fileOperationIid = typeof ( IFileOperation ) . GUID ;
118+ var fileOperationInstanceIid = typeof ( FileOperation ) . GUID ;
119+ hr = PInvoke . CoCreateInstance ( & fileOperationInstanceIid , null , CLSCTX . CLSCTX_LOCAL_SERVER , & fileOperationIid , ( void * * ) pFileOperation . GetAddressOf ( ) ) ;
120+ hr = pFileOperation . Get ( ) ->SetOperationFlags ( FILEOPERATION_FLAGS . FOF_NO_UI ) ;
121+ hr = pFileOperation . Get ( ) ->SetOwnerWindow ( new ( MainWindow . Instance . WindowHandle ) ) ;
122+
123+ using ComPtr < IShellItem > pShellItem = default ;
124+ while ( pEnumShellItems . Get ( ) ->Next ( 1 , pShellItem . GetAddressOf ( ) ) == HRESULT . S_OK )
137125 {
138- recycleBinFolderShellItem ->Release ( ) ;
139- enumShellItems ->Release ( ) ;
140- pFileOperation ->Release ( ) ;
141- pShellItem ->Release ( ) ;
126+ // Get the original path
127+ using ComPtr < IShellItem2 > pShellItem2 = default ;
128+ var shellItem2Iid = typeof ( IShellItem2 ) . GUID ;
129+ hr = pShellItem . Get ( ) ->QueryInterface ( & shellItem2Iid , ( void * * ) pShellItem2 . GetAddressOf ( ) ) ;
130+ hr = PInvoke . PSGetPropertyKeyFromName ( "System.Recycle.DeletedFrom" , out var originalPathPropertyKey ) ;
131+ hr = pShellItem2 . Get ( ) ->GetString ( originalPathPropertyKey , out var szOriginalPath ) ;
132+
133+ // Get IShellItem of the original path
134+ hr = PInvoke . SHCreateItemFromParsingName ( szOriginalPath . ToString ( ) , null , typeof ( IShellItem ) . GUID , out var pOriginalPathShellItemPtr ) ;
135+ var pOriginalPathShellItem = ( IShellItem * ) pOriginalPathShellItemPtr ;
136+
137+ // Define the shell item to restore
138+ hr = pFileOperation . Get ( ) ->MoveItem ( pShellItem . Get ( ) , pOriginalPathShellItem , default ( PCWSTR ) , null ) ;
142139 }
140+
141+ // Perform
142+ hr = pFileOperation . Get ( ) ->PerformOperations ( ) ;
143+
144+ // Reset the icon
145+ Win32PInvoke . SHUpdateRecycleBinIcon ( ) ;
146+
147+ return true ;
143148 }
144149 }
145150}
0 commit comments