Moving files to Windows' Recycle Bin in LiveCode -- is it possible?

Deploying to Windows? Utilizing VB Script execution? This is the place to ask Windows-specific questions.

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

FourthWorld
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9207
Joined: Sat Apr 08, 2006 7:05 am
Location: Los Angeles
Contact:

Re: Moving files to Windows' Recycle Bin in LiveCode -- is it possible?

Post by FourthWorld » Thu May 12, 2022 10:46 pm

LCMark wrote:
Thu May 12, 2022 9:25 am
Serious question: why does Microsoft provide a path to the Recycle Bin if it can't be used?
macOS does too - its at ~/.Trash (I think there are also folders related to Trash on each read-write volume as well).

The files-which-you-might-want-to-recover have to be stored somewhere!
I'm familiar with file systems. The question is why Microsoft exposes a virtual file path that can't be used?

Linux is chock full o' virtual folders (eg /proc), and they work just like any other. Win's C:\$Recycle.Bin shows in some contexts but not others, and I haven't found a way to use it. All the examples I could find require using a dozen lines of VBScript like SparkOut's example.

I wonder if Microsoft has considered investing in usage data gathering that would allow them to know that putting things in the Recycle Bin is something people do. ;) If we can write a dozen lines of VBScript, I'll bet they can find the technology to make that a one-liner like other OSes do.

FWIW Mac and Linux work great by just using LC's rename command, e.g.:

Code: Select all

on mouseup
   -- Make trashable file:
   put specialFolderPath("Desktop")&"/_TRASH_THIS_EXAMPLE.txt" into tFile
   put "I'm a goner" into url ("file:"& tFile)
   --
   TrashFile tFile
end mouseup

on TrashFile pFile
   switch the platform
      case "Linux"
         put "~/.local/share/Trash/files" into tTrashPath -- good
         break
      case "macOS"
         put "~/.Trash" into tTrashPath -- good
         break
      case "Win32"
         put "C:/$Recycle.Bin" into tTrashPath -- error 5 (permissions)
         break
   end switch
   --
   -- Do the deed:
   set the itemdel to "/"
   put tTrashPath &"/"& last item of pFile into tTrashFile
   rename file pFile to tTrashFile 
   put the result &&"(" &sysError()&")"
end TrashFile
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn

LCMark
Livecode Staff Member
Livecode Staff Member
Posts: 1153
Joined: Thu Apr 11, 2013 11:27 am

Re: Moving files to Windows' Recycle Bin in LiveCode -- is it possible?

Post by LCMark » Fri May 13, 2022 5:37 am

I'm familiar with file systems. The question is why Microsoft exposes a virtual file path that can't be used?
They obviously decided to solve the problem in a slightly different way - and provide a different end-user experience: https://devblogs.microsoft.com/oldnewth ... 00/?p=9773

The key thing here is:
The Recycle Bin is somewhat strange in that it can have multiple items with the same name. Create a text file called TEST.TXT on your desktop, then delete it into the Recycle Bin. Create another text file called TEST.TXT on your desktop, then delete it into the Recycle Bin. Now open your Recycle Bin. Hey look, you have two TEST.TXT files with the same path!
So on macOS, the Finder renames things if there is a duplicate - presumably you have to write the same logic if you want to use the Trash in the way you are proposing on that platform (although, given my ~/.Trash has permissions which means I can't seem to prod it, it looks much the same as $Recycle.Bin on Windows to me!).

Cairoo
Posts: 46
Joined: Wed Dec 05, 2012 5:54 pm

Re: Moving files to Windows' Recycle Bin in LiveCode -- is it possible?

Post by Cairoo » Sun May 15, 2022 10:27 am

The Windows Shell API function named "SHFileOperation" in the DLL file named "shell32.dll" can delete files and folders to the Recycle Bin.

The SHFileOperation function is documented here: https://docs.microsoft.com/en-us/window ... operationw

LiveCode Builder lets you call Win32 API functions directly using the Foreign Function Interface (FFI). This way it is guaranteed to work even on systems where the Windows Scripting Host access is disabled.

The following LCB script can be saved to a .lcb file and be opened in the Extension Builder where it can be installed. After installing it, you can use the "DeleteToRecycleBin" function like you would use any other function in your LC script.

Code: Select all

/**
The Windows Recycle library enables deleting files and folders to Windows' Recycle Bin.

*/
library community.livecode.cairoo.windowsrecycle

metadata title is "Windows Recycle"
metadata author is "Gerrie van Tonder"
metadata version is "0.1.0"
metadata platforms is "desktop"
metadata os is "windows"

use com.livecode.foreign

// built-in foreign handlers used for converting a String to a sequence of bytes
foreign handler MCStringEncode(in pString as String, in pEncoding as CUInt, in pIsExternalRep as CBool, out rUTF8String as Data) returns CBool binds to "<builtin>"
foreign handler MCDataGetBytePtr(in pData as Data) returns optional Pointer binds to "<builtin>"

// Bind to the SHFILEOPSTRUCTW struct type used by the SHFileOperation Windows Shell API function
public foreign type SHFILEOPSTRUCTW binds to "MCAggregateTypeInfo:ljrrialr"

// Bind to the SHFileOperation Windows Shell API function in the shell32 DLL
foreign handler Shell32SHFileOperation (inout xFileOp as SHFILEOPSTRUCTW) returns CUInt binds to "c:shell32>SHFileOperation"

// Constant used with MCStringEncode
constant kMCStringEncodingUTF8 is 4

// Constants used with SHFileOperation
constant kFileOpFlags_ALLOWUNDO is 64
constant kFileOpFlags_SILENT is 4
constant kFileOpFlags_NOCONFIRMATION is 16
constant kFileOp_DELETE is 3

/**
Name: DeleteToRecycleBin
Type: function
Summary: Delete a return-delimited list of files and folders, placing them in the Recycle Bin.

Parameters:
pPaths (string): A return-delimited list of files and folders to be deleted, one fully qualified path per line. Wildcard characters are not supported.
pSilent (boolean): true or false. If true, responds "Yes to All" for any dialog boxes and no progress dialog box is displayed.

Returns (boolean): Returns true if the delete operation succeeded or false if an error has occurred.

Example:
   put DeleteToRecycleBin(tFilesToDelete, true) into tDeleteSuccess

Description:
Use the <b>DeleteToRecycleBin</b> function to delete files and folders from the user's computer and place them in the Recycle Bin.
The first argument is a return-delimited list of files and folders to be deleted, one fully qualified path per line.
The second argument is a boolean value that specifies whether to delete the files without displaying any progress or confirmation dialog boxes.

If the function returns false and multiple files or folders were specified, then none of the specified files are deleted.

<b>Note:</b> The <b>DeleteToRecycleBin</b> function is available for Windows only.
*/
public handler DeleteToRecycleBin(in pPaths as String, in pSilent as Boolean) returns Boolean
   -- returns true if successful, or false if failed
   variable tReturnValue as Boolean -- the value returned by this handler
   variable tPathsNullTerminated as String -- the null-terminated paths
   variable tFlags as CUShort -- SHFILEOPSTRUCTW.fFlags flag values
   variable tPathsData as Data -- the paths converted to a sequence of bytes
   variable tPathsDataPointer as optional Pointer -- pointer to the bytes contained in tPathsData
   variable tFileOp as SHFILEOPSTRUCTW -- information that the SHFileOperation API function uses to perform file operations
   variable tResult as CUInt -- the result returned by the Shell32SHFileOperation foreign handler

   put false into tReturnValue -- default return value of this handler

   -- replace "/" with "\" and null terminate the paths
   put pPaths into tPathsNullTerminated
   replace "/" with "\\" in tPathsNullTerminated
   replace newline with the char with code 0 in tPathsNullTerminated
   put the char with code 0 after tPathsNullTerminated -- double-null terminate the paths string
   --
   unsafe
      if MCStringEncode(tPathsNullTerminated, kMCStringEncodingUTF8, false, tPathsData) then
         put MCDataGetBytePtr(tPathsData) into tPathsDataPointer
         if tPathsDataPointer is not nothing then
            put kFileOpFlags_ALLOWUNDO into tFlags -- set the flag that tells Windows it should go to the Recycle Bin
            if pSilent is true then
               -- set the flags that prevent displaying a progress dialog box and respond with Yes to All for any dialog box
               add kFileOpFlags_SILENT + kFileOpFlags_NOCONFIRMATION to tFlags
            end if
            put [0,kFileOp_DELETE,tPathsDataPointer,nothing,tFlags,false,0,nothing] into tFileOp -- populate the SHFILEOPSTRUCTW structure
            put Shell32SHFileOperation(tFileOp) into tResult -- perform the delete operation
            put 0 is tResult into tReturnValue -- true if zero or false if nonzero
         end if
      end if
   end unsafe
   return tReturnValue
end handler

end library
Regards,

Gerrie
Last edited by Cairoo on Sun May 15, 2022 7:15 pm, edited 2 times in total.

FourthWorld
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9207
Joined: Sat Apr 08, 2006 7:05 am
Location: Los Angeles
Contact:

Re: Moving files to Windows' Recycle Bin in LiveCode -- is it possible?

Post by FourthWorld » Sun May 15, 2022 4:16 pm

Great work, Gerrie.

That'll tide us over well until Microsoft switches to the Linux kernel. :) Once they complete that the Unix philosophy of "everything is a file" will give us a path to the Recycle process that can be used with normal file I/O calls, like the Linux /proc folder provides. #DayDreams
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn

Zax
Posts: 251
Joined: Mon May 28, 2007 10:12 am
Location: France

Re: Moving files to Windows' Recycle Bin in LiveCode -- is it possible?

Post by Zax » Mon May 16, 2022 6:19 am

Impressive ! Thank you.

LCMark
Livecode Staff Member
Livecode Staff Member
Posts: 1153
Joined: Thu Apr 11, 2013 11:27 am

Re: Moving files to Windows' Recycle Bin in LiveCode -- is it possible?

Post by LCMark » Mon May 16, 2022 1:23 pm

FourthWorld wrote:
Sun May 15, 2022 4:16 pm
That'll tide us over well until Microsoft switches to the Linux kernel. :) Once they complete that the Unix philosophy of "everything is a file" will give us a path to the Recycle process that can be used with normal file I/O calls, like the Linux /proc folder provides. #DayDreams
I think this is missing the point here - on all three platforms (macOS, Linux and Windows) - the Trash folder is 'special' - in that there are high-level operations provided by the OS to manipulate it as it has very specific and special behavior.

Specifically, on all three platforms (from the file exploration UI), you can put things into the trash which have the same name (coming from different folders) - and on all three platforms, there is an option to restore an item back to where it was.

If you just use normal file operations to put things into the trash - e.g. `mv`, `rename file` or any other means - then these special features are lost. Given this, and given what the trash is for - I don't see that it makes any different whatsoever as to whether it is a real accessible folder, or a special virtual folder, or something else (thus meaning that there is no 'UNIX is better than others', or 'others are better than UNIX' argument to be had on this point).

[ I'd point out that the TrashFile handler suggested is actually wrong - and will not provide the end-user of an application using such a handler the experience they would expect with 'trashing' files on their requisite platform - indeed it will fail if there is already a file with the same name in the trash folder, and means you don't get the 'put back' / 'restore' options. On linux at least there is a shell command to trash a file - `gio trash` - irksomely neither Windows nor macOS seem to offer such a thing, meaning resorting to VBScript/AppleScript/calling the requisite OS API from LCB is necessary ].

Post Reply

Return to “Windows”