Author Topic: Maybe SpriggsySpriggs would know how to get Win API Recycle Bin in a QB64 prog?  (Read 5517 times)

0 Members and 1 Guest are viewing this topic.

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
I wrote a routine years ago that archives older files with the same name. It simple makes an "archives" folder in the local directory, and takes the file to be archived, adds a date and time recycled stamp to the name, and then moves it into the archive folder. What would be better is a way to get QB64 to call the Windows API to somehow get a named file placed into the recycle bin, without doing so manually. Anyone ever accomplish this and care to share?

Pete
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline Dav

  • Forum Resident
  • Posts: 792
    • View Profile
I posted one on the old forum. I'll see if I can dig it up. I have it on a CD somewhere.

- Dav

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Thanks for having a look, Dav. Funny, I was just mentioning to Bob, at QBF, the number of times members have asked questions here, only to find there was a program or code posted and lost at .net, which would have addressed the post.

Pete
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
That sounds quite a bit like what I did for my job. I had files that were dated and if my program detected that those files matched the date of today and were found when the program ran, it moved them to a folder called "EDI Archive". It didn't use any API, just simply SHELL with the command prompt commands to move files. I'll look into this, though
Shuwatch!

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Shuwatch!

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
@Pete Here is working code that sends a file to the recycle bin using the API I mentioned above! Cheers! You can use either the full path of the file or you can trash an entire directory. I put the flag for FOF_WANTNUKEWARNING which means that if it will delete the file permanently rather than trash it then it will give a confirmation dialog. The confirmation dialog does work which is quite nice.

Updated 10:52 PM I also added the other functions of SHFileOperationA since they also use confirmation dialogs when something is going to be overwritten or deleted permanently.

Code: QB64: [Select]
  1.  
  2. 'To - From, From - To Flags
  3. CONST FO_MOVE = &H1
  4. CONST FO_COPY = &H2
  5. CONST FO_DELETE = &H3
  6. CONST FO_RENAME = &H4
  7.  
  8. 'File Op Flags
  9. CONST FOF_MULTIDESTFILES = &H1
  10. CONST FOF_CONFIRMMOUSE = &H2
  11. CONST FOF_SILENT = &H4
  12. CONST FOF_RENAMEONCOLLISION = &H8
  13. CONST FOF_NOCONFIRMATION = &H10
  14. CONST FOF_WANTMAPPINGHANDLE = &H20
  15. CONST FOF_ALLOWUNDO = &H40
  16. CONST FOF_FILESONLY = &H80
  17. CONST FOF_SIMPLEPROGRESS = &H100
  18. CONST FOF_NOCONFIRMMKDIR = &H200
  19. CONST FOF_NOERRORUI = &H400
  20. CONST FOF_NOCOPYSECURITYATTRIBS = &H800
  21. CONST FOF_NORECURSION = &H1000
  22. CONST FOF_NO_CONNECTED_ELEMENTS = &H2000
  23. CONST FOF_WANTNUKEWARNING = &H4000
  24. CONST FOF_NORECURSEREPARSE = &H8000
  25. CONST FOF_NO_UI = FOF_SILENT
  26.  
  27. 'Return Values
  28. CONST DE_SAMEFILE = &H71
  29. CONST DE_MANYSRC1DEST = &H72
  30. CONST DE_DIFFDIR = &H73
  31. CONST DE_ROOTDIR = &H74
  32. CONST DE_OPCANCELLED = &H75
  33. CONST DE_DESTSUBTREE = &H76
  34. CONST DE_ACCESSDENIEDSRC = &H78
  35. CONST DE_PATHTOODEEP = &H79
  36. CONST DE_MANYDEST = &H7A
  37. CONST DE_INVALIDFILES = &H7C
  38. CONST DE_DESTSAMETREE = &H7D
  39. CONST DE_FLDDESTISFILE = &H7E
  40. CONST DE_FILEDESTISFLD = &H80
  41. CONST DE_FILENAMETOOLONG = &H81
  42. CONST DE_DEST_IS_CDROM = &H82
  43. CONST DE_DEST_IS_DVD = &H83
  44. CONST DE_DEST_IS_CDRECORD = &H84
  45. CONST DE_FILE_TOO_LARGE = &H85
  46. CONST DE_SRC_IS_CDROM = &H86
  47. CONST DE_SRC_IS_DVD = &H87
  48. CONST DE_SRC_IS_CDRECORD = &H88
  49. CONST DE_ERROR_MAX = &HB7
  50. CONST UNKNOWN = &H402
  51. CONST ERRORONDEST = &H10000
  52. CONST DE_ROOTDIR_ERRORONDEST = &H10074
  53.  
  54. TYPE SHFILEOPSTRUCTA
  55.     hwnd AS _OFFSET
  56.     $IF 64BIT THEN
  57.         wfunc AS _UNSIGNED _INTEGER64 'To - From, From - To Flags
  58.     $ELSE
  59.         wfunc AS _UNSIGNED LONG
  60.     $END IF
  61.     pFrom AS _OFFSET
  62.     pTo AS _OFFSET
  63.     fFlags AS LONG
  64.     fAnyOperationsAborted AS _BYTE
  65.     hNameMappings AS _OFFSET
  66.     lpszProgressTitle AS _OFFSET
  67.  
  68.     FUNCTION FileOperation% ALIAS SHFileOperationA (lpFileOp AS SHFILEOPSTRUCTA)
  69.  
  70. 'Test code
  71. IF _FILEEXISTS(_DIR$("desktop") + "this is a test.txt") = 0 THEN
  72.     OPEN _DIR$("desktop") + "this is a test.txt" FOR OUTPUT AS #1
  73.     CLOSE #1
  74. PRINT Copy(_DIR$("desktop") + "this is a test.txt", _DIR$("desktop") + "this is a test as well.txt")
  75. PRINT Rename(_DIR$("desktop") + "this is a test as well.txt", _DIR$("desktop") + "this is a test also.txt")
  76. PRINT Recycle(_DIR$("desktop") + "this is a test also.txt")
  77.  
  78. FUNCTION Recycle% (file AS STRING)
  79.     DIM lpFileOp AS SHFILEOPSTRUCTA
  80.     DIM doublenull AS STRING
  81.     doublenull = CHR$(0) + CHR$(0)
  82.     file = file + doublenull
  83.     lpFileOp.hwnd = _WINDOWHANDLE
  84.     lpFileOp.wfunc = FO_DELETE
  85.     lpFileOp.pFrom = _OFFSET(file)
  86.     lpFileOp.fFlags = FOF_ALLOWUNDO + FOF_WANTNUKEWARNING
  87.     Recycle = FileOperation(lpFileOp)
  88.  
  89. FUNCTION Copy% (file AS STRING, dest AS STRING)
  90.     DIM lpFileOp AS SHFILEOPSTRUCTA
  91.     DIM doublenull AS STRING
  92.     doublenull = CHR$(0) + CHR$(0)
  93.     file = file + doublenull
  94.     dest = dest + doublenull
  95.     lpFileOp.hwnd = _WINDOWHANDLE
  96.     lpFileOp.wfunc = FO_COPY
  97.     lpFileOp.pFrom = _OFFSET(file)
  98.     lpFileOp.pTo = _OFFSET(dest)
  99.     lpFileOp.fFlags = FOF_ALLOWUNDO
  100.     Copy = FileOperation(lpFileOp)
  101.  
  102. FUNCTION Move% (file AS STRING, dest AS STRING)
  103.     DIM lpFileOp AS SHFILEOPSTRUCTA
  104.     DIM doublenull AS STRING
  105.     doublenull = CHR$(0) + CHR$(0)
  106.     file = file + doublenull
  107.     dest = dest + doublenull
  108.     lpFileOp.hwnd = _WINDOWHANDLE
  109.     lpFileOp.wfunc = FO_MOVE
  110.     lpFileOp.pFrom = _OFFSET(file)
  111.     lpFileOp.pTo = _OFFSET(dest)
  112.     lpFileOp.fFlags = FOF_ALLOWUNDO
  113.     Move = FileOperation(lpFileOp)
  114.  
  115. FUNCTION Rename% (file AS STRING, newname AS STRING)
  116.     DIM lpFileOp AS SHFILEOPSTRUCTA
  117.     DIM doublenull AS STRING
  118.     doublenull = CHR$(0) + CHR$(0)
  119.     file = file + doublenull
  120.     newname = newname + doublenull
  121.     lpFileOp.hwnd = _WINDOWHANDLE
  122.     lpFileOp.wfunc = FO_RENAME
  123.     lpFileOp.pFrom = _OFFSET(file)
  124.     lpFileOp.pTo = _OFFSET(newname)
  125.     lpFileOp.fFlags = FOF_ALLOWUNDO
  126.     Rename = FileOperation(lpFileOp)
« Last Edit: September 22, 2020, 10:57:46 pm by SpriggsySpriggs »
Shuwatch!

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
@Pete , Here is my latest source which allows for Rename, Copy, Move, Recycle and even Empty Recycle bin all using WinAPI (Edit 1:31 AM 09/23/2020 It now also has the ability to show how many bytes the recycle bin is currently occupying on disk and how many files are contained. It's also inside my API Collection zip but I've attached it here for you. I hope this is what you are looking for.
« Last Edit: September 23, 2020, 01:37:35 am by SpriggsySpriggs »
Shuwatch!

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Nice! I had a look, and I'll give the recycle bin a try, tomorrow. I simply need to edit out the empty recycle bin part, as I want to retain the contents in the bin. I also need to download some of Clippy's files, so I have somethings to trash!

I'm glad this appears to be a nice addition to your collection of Win api functions, as it looks like it was a fair amount of work to do for a request. I certainly appreciate it!

Pete
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
This was actually my first WinAPI addition to my collection! All the others were online REST and HTTP APIs. I had always had very little luck with WinAPI (in this capacity) and had stayed far away but you really got me a good one to work on so that's great! Got me to branch out a bit!
« Last Edit: September 23, 2020, 01:43:39 am by SpriggsySpriggs »
Shuwatch!

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
They can be a pain. I think Dav inspierd me to make two or three, but the only one I can recall I posted here: https://www.qb64.org/forum/index.php?topic=1365.msg105588#msg105588

I miss the days when I could remember my entire genetic sequence. Now, on a good day, I'm lucky if I can remember my name.

John
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
@Pete , Here is my latest source which allows for Rename, Copy, Move, Recycle and even Empty Recycle bin all using WinAPI (Edit 1:31 AM 09/23/2020 It now also has the ability to show how many bytes the recycle bin is currently occupying on disk and how many files are contained. It's also inside my API Collection zip but I've attached it here for you. I hope this is what you are looking for.

I am curious have you tested these with .ogg files?

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
I am curious have you tested these with .ogg files?
@bplus I have a couple ogg files handy. How do you want me to test them?
I tested Copy, Rename, Move, Recycle, and Empty Recycle Bin on them with no issues whatsoever. Handled them like anything else.

Code: QB64: [Select]
  1. PRINT Copy(_DIR$("desktop") + "distant.ogg", _DIR$("desktop") + "distant2.ogg")
  2. PRINT Rename(_DIR$("desktop") + "distant2.ogg", _DIR$("desktop") + "distant3.ogg")
  3. PRINT Recycle(_DIR$("desktop") + "distant3.ogg")
  4. PRINT GetRecycleInfo
  5. PRINT Move(_DIR$("desktop") + "distant.ogg", _DIR$("desktop") + "QB64 x64\distant.ogg")
  6. PRINT EmptyBin
« Last Edit: September 23, 2020, 12:51:28 pm by SpriggsySpriggs »
Shuwatch!

Offline Dav

  • Forum Resident
  • Posts: 792
    • View Profile
@SpriggsySpriggs, looks like a good job there. I've found Win APIs to often be a challenge getting them to work in QB64, but a fun challenge.

@Pete, I've looked through a bunch of my cd's  haven't found my version yet. I think it was called SOFTKILL.BAS (wish it was in my recycle bin) but Spriggsy versions looks like a better one than I remember mine being.

- Dav

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
@bplus I have a couple ogg files handy. How do you want me to test them?
I tested Copy, Rename, Move, Recycle, and Empty Recycle Bin on them with no issues whatsoever. Handled them like anything else.

Code: QB64: [Select]
  1. PRINT Copy(_DIR$("desktop") + "distant.ogg", _DIR$("desktop") + "distant2.ogg")
  2. PRINT Rename(_DIR$("desktop") + "distant2.ogg", _DIR$("desktop") + "distant3.ogg")
  3. PRINT Recycle(_DIR$("desktop") + "distant3.ogg")
  4. PRINT GetRecycleInfo
  5. PRINT Move(_DIR$("desktop") + "distant.ogg", _DIR$("desktop") + "QB64 x64\distant.ogg")
  6. PRINT EmptyBin

I know copying them is no problem but removing them can be or removing a folder that contains them might be the test. Yes removing a folder loaded up with them is the best test.

Now if you are up to date with .ogg files then you have the special extension patch so they may work in File Explorer, and testing would be mute point. But I am curious if File Explorer is using API calls (which is where I'd place my bet) or working under it's own code power.
« Last Edit: September 23, 2020, 02:05:32 pm by bplus »

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
I know copying them is no problem but removing them can be or removing a folder that contains them might be the test. Yes removing a folder loaded up with them is the best test.
Now if you are up to date with .ogg files then you have the special extension patch so they may work in File Explorer, and testing would be mute point. But I am curious if File Explorer is using API calls (which is where I'd place my bet) or working under it's own code power.

@bplus Ok I'll test it next with a folder containing .ogg files to see how it does. The confirmation dialogs that appear (if any) are the same ones you see when doing file operations in File Explorer so I reckon this is just invoking the same methods that are used in deleting, copying, etc in File Explorer. My computer is running Windows 10 64 Bit build 2004.
Shuwatch!