RecycleFile (Windows)
-
- PureBasic Guru
- Posts: 16777133
- Joined: Tue Apr 22, 2003 7:42 pm
RecycleFile (Windows)
Restored from previous forum. Originally posted by PB.
UPDATE: See corrected code further down (dated Mon Feb 11, 2008).
The example in this first particular post is faulty and not 100% reliable.
This procedure lets you "delete" files by sending them to the Recycle Bin (also
known as the Trash Can) instead of permanently deleting them as DeleteFile does.
Note that there is a bit of a delay after calling this procedure to the time the
file(s) is recycled... I don't know if this can be sped up, but I doubt it. You
can use this with wildcards (*?) too, just like DeleteFile does. Enjoy!
; RecycleFile by PB -- do what you want with it.
; Usage: RecycleFile(file$)
; Same as DeleteFile() except files go to the bin.
;
Procedure RecycleFile(file$)
SHFileOp.SHFILEOPSTRUCT
SHFileOp\pFrom=@file$
SHFileOp\wFunc=#FO_DELETE
SHFileOp\fFlags=#FOF_ALLOWUNDO
SHFileOperation_(SHFileOp)
EndProcedure
PB - Registered PureBasic Coder
Edited by - PB on 17 August 2002 07:01:53
UPDATE: See corrected code further down (dated Mon Feb 11, 2008).
The example in this first particular post is faulty and not 100% reliable.
This procedure lets you "delete" files by sending them to the Recycle Bin (also
known as the Trash Can) instead of permanently deleting them as DeleteFile does.
Note that there is a bit of a delay after calling this procedure to the time the
file(s) is recycled... I don't know if this can be sped up, but I doubt it. You
can use this with wildcards (*?) too, just like DeleteFile does. Enjoy!
; RecycleFile by PB -- do what you want with it.
; Usage: RecycleFile(file$)
; Same as DeleteFile() except files go to the bin.
;
Procedure RecycleFile(file$)
SHFileOp.SHFILEOPSTRUCT
SHFileOp\pFrom=@file$
SHFileOp\wFunc=#FO_DELETE
SHFileOp\fFlags=#FOF_ALLOWUNDO
SHFileOperation_(SHFileOp)
EndProcedure
PB - Registered PureBasic Coder
Edited by - PB on 17 August 2002 07:01:53
Addendum: RecycleFile (Windows)
One little thing I think should be corrected here - Microsoft write for the pFrom-value:
An additional NULL character must be appended to the end of the final name to indicate the end of pFrom.
So we need two NULLs at the end of the string. I have do this so (not so elegant, could be possibly more efficient - but it works ):
Andy
12.5.04 Edit: Some little corrections...
An additional NULL character must be appended to the end of the final name to indicate the end of pFrom.
So we need two NULLs at the end of the string. I have do this so (not so elegant, could be possibly more efficient - but it works ):
Code: Select all
Procedure _RecycleFile(file$)
; RecycleFile by PB -- do what you want with it.
; Usage: RecycleFile(file$)
; Same as DeleteFile() except files go to the bin.
; Modified by Andy (PB 3.91)
s=Len(file$)+3
MemoryID=AllocateMemory(s)
For i=s-3 To s-1
PokeB(MemoryID+i,0)
Next
PokeS(MemoryID,file$)
SHFileOp.SHFILEOPSTRUCT
SHFileOp\pFrom=MemoryID
SHFileOp\wFunc=#FO_DELETE
SHFileOp\fFlags=#FOF_ALLOWUNDO | #FOF_SILENT
result = SHFileOperation_(@SHFileOp)
FreeMemory(MemoryID)
ProcedureReturn result
EndProcedure
12.5.04 Edit: Some little corrections...
Re: Addendum: RecycleFile (Windows)
A belated thanks to Andy for fixing my tip: I needed this fix today.
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
"PureBasic won't be object oriented, period" - Fred.
How about -
I've been using this for years, is there something I've missed?
Code: Select all
Procedure RecycleFile(file$)
SHFileOp.SHFILEOPSTRUCT
SHFileOp\pFrom=@file$
SHFileOp\wFunc=#FO_DELETE
SHFileOp\fFlags=#FOF_ALLOWUNDO | #FOF_NOCONFIRMATION ; without #FOF_NOCONFIRMATION you get a messagerequester asking to confirm sending to recycle bin
SHFileOperation_(SHFileOp)
EndProcedure
Mike.
(I'm never going to catch up with the improvements to this program)
(I'm never going to catch up with the improvements to this program)
@MikeB: What you posted is basically the same code as my tip at the top of
this thread. It doesn't always work, even though I too thought it did. This is
because the filename MUST end with 2 x Chr(0) to work 100% correctly,
because Windows uses Chr(0) to separate multiple filenames. So an extra
Chr(0) is needed to signify the end of the file list.
In other words, you can recycle 2 files with one string:
file$ = "Name1"+Chr(0)+"Name2"+Chr(0)+Chr(0)
The last Chr(0) is needed, even if you only use one filename. I suffered this
problem yesterday, where the tip I gave (and you gave above) just wouldn't
recycle the files I was giving it. When I used Andy's tip, which adds the extra
required Chr(0), it all worked perfectly. I highly recommend you use it too.
In my own twisted coding way I modified Andy's addition to look like the
following, because a return value of 0 for SHFileOperation means success,
not failure. So the code below returns 0 for failure, and 1 for success.
this thread. It doesn't always work, even though I too thought it did. This is
because the filename MUST end with 2 x Chr(0) to work 100% correctly,
because Windows uses Chr(0) to separate multiple filenames. So an extra
Chr(0) is needed to signify the end of the file list.
In other words, you can recycle 2 files with one string:
file$ = "Name1"+Chr(0)+"Name2"+Chr(0)+Chr(0)
The last Chr(0) is needed, even if you only use one filename. I suffered this
problem yesterday, where the tip I gave (and you gave above) just wouldn't
recycle the files I was giving it. When I used Andy's tip, which adds the extra
required Chr(0), it all worked perfectly. I highly recommend you use it too.
In my own twisted coding way I modified Andy's addition to look like the
following, because a return value of 0 for SHFileOperation means success,
not failure. So the code below returns 0 for failure, and 1 for success.
Code: Select all
Procedure RecycleFile(file$)
#FOF_NOERRORUI=$400 ; PureBasic doesn't recognise this constant (as of v4.20 Beta 2).
s=Len(file$)+3 : m=AllocateMemory(s) : For p=s-3 To s-1 : PokeB(m+p,0) : Next : PokeS(m,file$)
SHFileOp.SHFILEOPSTRUCT : SHFileOp\pFrom=m : SHFileOp\wFunc=#FO_DELETE
SHFileOp\fFlags=#FOF_ALLOWUNDO|#FOF_NOERRORUI : ok=SHFileOperation_(SHFileOp)
If ok=0 : ok=1 : Else : ok=0 : EndIf : FreeMemory(m)
ProcedureReturn ok
EndProcedure
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
"PureBasic won't be object oriented, period" - Fred.
Surely the code:is redundant as the documentation for AllocateMemory() states that the memory area will be initialised with nulls.
Code: Select all
For p=s-3 To s-1 : PokeB(m+p,0) : Next
Anthony Jordan
> Surely [For/Next] is redundant as the documentation for AllocateMemory()
> states that the memory area will be initialised with nulls
Correct! Here is the amended code, now also with error-checking in case
AllocateMemory couldn't be done. Works 100% perfectly on all files I tested.
> states that the memory area will be initialised with nulls
Correct! Here is the amended code, now also with error-checking in case
AllocateMemory couldn't be done. Works 100% perfectly on all files I tested.
Code: Select all
Procedure RecycleFile(file$)
#FOF_NOERRORUI=$400
m=AllocateMemory(Len(file$)+2)
If m
PokeS(m,file$) : SHFileOp.SHFILEOPSTRUCT : SHFileOp\pFrom=m : SHFileOp\wFunc=#FO_DELETE
SHFileOp\fFlags=#FOF_ALLOWUNDO|#FOF_NOERRORUI : ok=SHFileOperation_(SHFileOp) : FreeMemory(m)
If ok=0 : ok=1 : Else : ok=0 : EndIf
EndIf
ProcedureReturn ok
EndProcedure
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
"PureBasic won't be object oriented, period" - Fred.
Thanks for the explanation, I understand what is going on now, although as far as I know it has worked in the past. However since I normally replace the file with a longer version, hence overwriting the original, it would not be obvious if it had not finished in the trashcan unless I wanted to recover it and so far I haven't. So I have been assuming it was working because it did a few years ago when I tested it!
Mike.
(I'm never going to catch up with the improvements to this program)
(I'm never going to catch up with the improvements to this program)
> I have been assuming it was working because it did a few years ago when
> I tested it!
Same here. It did work for me in the past, too. You're not alone. But like I said,
the other day when I used it in an app, it didn't, so I don't know if PureBasic is
now doing something "correctly" or what.
> I tested it!
Same here. It did work for me in the past, too. You're not alone. But like I said,
the other day when I used it in an app, it didn't, so I don't know if PureBasic is
now doing something "correctly" or what.
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
"PureBasic won't be object oriented, period" - Fred.
Re:
For this to work in Unicode, I think StringByteLength(file$) MUST replace Len(file$) in the 2nd line of the Procedure :PB wrote:> [...]
AllocateMemory couldn't be done. Works 100% perfectly on all files I tested.
Code: Select all
Procedure RecycleFile(file$) #FOF_NOERRORUI=$400 m=AllocateMemory(Len(file$)+2) If m PokeS(m,file$) : SHFileOp.SHFILEOPSTRUCT : SHFileOp\pFrom=m : SHFileOp\wFunc=#FO_DELETE SHFileOp\fFlags=#FOF_ALLOWUNDO|#FOF_NOERRORUI : ok=SHFileOperation_(SHFileOp) : FreeMemory(m) If ok=0 : ok=1 : Else : ok=0 : EndIf EndIf ProcedureReturn ok EndProcedure
Code: Select all
m=AllocateMemory(StringByteLength(file$)+4)
"That's not a bug..." said the programmer. "it's a feature! "
"Oh! I see..." replied the blind man.
"Oh! I see..." replied the blind man.
Re: RecycleFile (Windows)
Yes, or you use sizeof() combined with Len():
Code: Select all
Procedure RecycleFile(file$)
Protected m, result, SHFileOp.SHFILEOPSTRUCT
m = AllocateMemory( ( Len(file$)+2 ) * SizeOf(Character) )
If m
PokeS(m,file$)
SHFileOp\pFrom = m
SHFileOp\wFunc = #FO_DELETE
SHFileOp\fFlags = #FOF_ALLOWUNDO|#FOF_NOERRORUI
result = SHFileOperation_(SHFileOp)
FreeMemory(m)
ProcedureReturn Bool(result = 0)
EndIf
EndProcedure
Re: RecycleFile (Windows)
Great ! I never could think of anything really useful to do with the SizeOf() instruction.Danilo wrote:Yes, or you use sizeof() combined with Len():Code: Select all
Procedure RecycleFile(file$) [...] m = AllocateMemory( ( Len(file$)+2 ) * SizeOf(Character) ) [...] EndProcedure
But I see now that it can be cleverly used.
Thank you, Danilo.
This is turning out to be a good day : I learned something new !
"That's not a bug..." said the programmer. "it's a feature! "
"Oh! I see..." replied the blind man.
"Oh! I see..." replied the blind man.