Folder shortcuts could not be restored from Recycle Bin - #18785
Conversation
| using var reader = new BinaryReader(stream, Encoding.Unicode); | ||
|
|
||
| // From the 24th to the 28th, contains the number of characters for the originalPath. | ||
| reader.BaseStream.Seek(24, SeekOrigin.Begin); |
There was a problem hiding this comment.
This is not preferable. Read System.Recycle.DeletedFrom prop on the deleted item to get the path to the original folder.
There was a problem hiding this comment.
Noted. I was in a hurry and that day and forgot to mention.
System.Recycle.DeletedFrom was my first choice to solve this problem. It didn't work and had some issues:
- When you freshly delete a folder and file, the
System.Recycle.DeletedFromwill return empty. System.Recycle.DeletedFromis always returning empty for a shortcut of any kind.- AFTER updating the trash bin folder (F5), Folders and Files will have their correct original path. Other shortcuts will keep the original path as the recycle bin even after F5.
Will investigate it further to try to pin point why.
There was a problem hiding this comment.
I may have found a fix.
System.Recycle.DeletedFrom does not exist for Shortcuts. I haven't realized before but, the original path lies in the target path itself.
I thought this would not work because if you used the target path as the Original Path for links, it would change the Original Path as soon as you moved the File or Folder it's linking itself to (But after testing, it does not!).
Will use that and see if it works.
I'll update this soon.
There was a problem hiding this comment.
Here's what I found:
For the "Original Location" column in the Details view
There looks like a hidden item ID in an item's PIDL. An internal function uncovers that hidden item ID then restores the original path. This can be legally called via IShellFolder::GetDetailsOfEx.
For the "Restore the selected items" command
There's a dedicated internal class for that command.
If we just wanna execute the restore operation, we should do the latter (while both of them can be done in Files legally).
Here's the definition.
[GeneratedComInterface(StringMarshalling = StringMarshalling.Utf16), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("5869092d-8af9-4a6c-ae84-1f03be2246cc")]
public partial interface IRecycleBinManager
{
[PreserveSig] HRESULT Compact();
[PreserveSig] HRESULT GetFileData(string path, out DELETEDITEM deletedItem);
[PreserveSig] HRESULT GetItemCount(out ulong itemCount);
[PreserveSig] HRESULT GetUsedSpace(out ulong usedSpace);
[PreserveSig] HRESULT IsEmpty();
[PreserveSig] HRESULT PurgeAll(IFileOperation fileOperation);
[PreserveSig] HRESULT PurgeItems([MarshalAs(UnmanagedType.LPWStr)] string path, IFileOperation fileOperation);
[PreserveSig] HRESULT SuspendUpdating(int suspend);
[PreserveSig] HRESULT HandleMenuMsg2(uint message, nuint wParam, nint lParam, out nint result);
[PreserveSig] HRESULT RestoreItems(IShellItemArray items, IFileOperation fileOperation);
[PreserveSig] HRESULT RestoreItem(IShellItem item, IFileOperation fileOperation);
[PreserveSig] HRESULT IsRecycled([MarshalAs(UnmanagedType.LPWStr)] string path, out int isRecycled);
[PreserveSig] HRESULT EnumItems(uint flags, [MarshalAs(UnmanagedType.Interface)] out IEnumRecycleItems enumerator);
[PreserveSig] HRESULT WillRecycle([MarshalAs(UnmanagedType.LPWStr)] string path);
[PreserveSig] HRESULT DelayCompaction(int delay);
[PreserveSig] HRESULT GetRecycleBinCount(out int count);
[PreserveSig] HRESULT GetRecycleBinAt(int index, in Guid interfaceId, [MarshalAs(UnmanagedType.Interface)] out object result);
[PreserveSig] HRESULT GetRecycleBin([MarshalAs(UnmanagedType.LPWStr)] string path, in Guid interfaceId, [MarshalAs(UnmanagedType.Interface)] out object result);
[PreserveSig] HRESULT Refresh();
}
[Guid("4A04656D-52AA-49DE-8A09-0B178760E748")]
partial class RecycleBinManager {}Unfortunately the codebase in this area is not good enough to implement this easily but hope you find it useful.

Resolved / Related Issues
What i've found
After investigating the cascading functions used in order to perform a "Restore" action in the Recycle Bin, certain problems were found:
Why did they happen?:
Other problems found
What did i do exacly and why
Steps used to test these changes