Re: [VB6] Use IFileOperation to replace SHFileOperation for modern Copy/Move box/prom
Hi fafalone, First - THANK YOU for this! :)
I am not actually using the class, but took out the necessary parts I needed to do a basic move operation and it works fine. However, both my code and also in the class invokes an interface function like so:
In MoveFile function for instance:
iFileOp.PerformOperations
Not:
retval = iFileOp.PerformOperations
which won't work. How do I get the return value from the PerformOperations function? Surely there's a way as that's important to know what the error return code is!??
In other words, all the "functions" seem to be declared as Subs in the tlb and thus not returning their hresult/long. Yet that hresult is key to knowing what went wrong. For example, if the move didn't succeed, that hresult tells you why.
What am I missing? Is there some other way I'm supposed to be getting the return value of those interface functions?
EDIT: I ran across your notes for the TLB and see this problem is a common one. I don't understand why you declared them as HRESULT in the TLB if VB treats those as Subs? I also am not clear at all how to use the SwapvTableEntry thing to get the return value. Is there another way? What do I need to do?
Re: [VB6] Use IFileOperation to replace SHFileOperation for modern Copy/Move box/prom
It's declared as an HRESULT because that's the default; it's not that HRESULT by definition is a Sub, that's something that VB forces behind the scenes. If you used it in another language, it would have a return value.
Changing it to a Long to get the return value has a consequence; any interface that has a return other than HRESULT cannot be implemented in VB (Implements)- that's why oleexmpimp.tlb exists, because it contains alternate versions of interfaces that do have non-HRESULT returns.
To get the return values, the TLB itself has to be changed. Swapping the v-table entry is only for when you're sending a return from your program, not receiving one, in an interface you're implementing yourself (e.g. IFileOperationProgressSink).
Since it's very uncommon to implement IFileOperation yourself, I'll go ahead and change it in the next version. I'll post the next version sometime in the next few days (as there's unrelated updates for a new version that I'm in the middle of), until then, there's two options:
1) Use IFileOperationProgressSink. In each 'Post' event, e.g. PostCopyItem, and after each series of operations, FinishOperations, the HRESULT of that particular operation is returned as one of the parameters. This has the added benefit of telling you precisely which operations failed if you were working with more than 1 file.
2) Modify the TLB yourself; IFileOperation is in exp_main.odl; change HRESULT to long, then recompile. Please do not distribute a modified TLB (a program compiled with it is fine though, as the TLB shouldn't be included with a compiled app).
Re: [VB6] Use IFileOperation to replace SHFileOperation for modern Copy/Move box/prom
Quote:
Originally Posted by
fafalone
Since it's very uncommon to implement IFileOperation yourself, I'll go ahead and change it in the next version. I'll post the next version sometime in the next few days
Thank you so much for the explanation! :) I don't have VC6 installed anymore so am not easily set up to create a TLB and I don't really need the callback function so I'll just wait for your version update - thank you! :)
Re: [VB6] Use IFileOperation to replace SHFileOperation for modern Copy/Move box/prom
The updated TLB has been posted in the main oleexp thread.
Re: [VB6] Use IFileOperation to replace SHFileOperation for modern Copy/Move box/prom
Thanks so much fafalone!! :) :)
Re: [VB6] Use IFileOperation to replace SHFileOperation for modern Copy/Move box/prom
I know this is a old thread, But thought I would let you know, started using your code and its working great, except one thing. The flag FOF_RENAMEONCOLLISION works when doing copy, but when doing a move the flag doesn't work.
Re: [VB6] Use IFileOperation to replace SHFileOperation for modern Copy/Move box/prom
Can he handle it? You copy both folders at the same time and then paste.
You can copy multiple folders directly in Explorer and paste them into other folders.
If the file you are copying has three large files and two folders.Can I cancel one of these five tasks.
I see that your initial instructions can only be all files, one file or multiple files.
Use the Explorer's method of adding compressed files to the extracted book. It can add a directory to it, but if there is an empty subdirectory inside, it will cause an error.
Can you test whether there is such a problem?Is there any parameter that can be avoided?
For example, do you want to write another piece of code to delete all the empty subdirectories under the directory first.
1 Attachment(s)
Re: [VB6] Use IFileOperation to replace SHFileOperation for modern Copy/Move box/prom
Quote:
Originally Posted by
freesix
Hi fafalone,
Your app was working perfectly until it crashes when trying to copy.
I even downloaded a new Zip folder to check maybe... but still behaving the same.
when I click on "Copy With Events" or "Copy" button, I got an error saying :
Code:
Runntime : '91'
Object Variable or Block Variable with undefined
The error is located in the below function.
Public Sub IFileOperationProgressSink_PreCopyItem(ByVal dwFlags As Long, ByVal psiItem As IShellItem, ByVal psiDestinationFolder As IShellItem, ByVal pszNewName As Long)
Dim lPtr As Long
psiDestinationFolder.GetDisplayName SIGDN_FILESYSPATH, lPtr
Debug.Print "cFileOperationProgressSink.IFileOperationProgressSink_PreCopyItem.destfolder=" & BStrFromLPWStr(lPtr, True)
DoEvents
End Sub
The debugger highlights the below line.
psiDestinationFolder.GetDisplayName SIGDN_FILESYSPATH, lPtr
-----------
I have the same problem with the current zip file.
Re: [VB6] Use IFileOperation to replace SHFileOperation for modern Copy/Move box/prom
It's mainly a demo so doesn't have robust error handling... You should check if psiDestinationFolder Is Nothing before trying to access it. Why it wouldn't be set in some circumstances would be a question for MS. Maybe if it has to be created it doesn't exist until post copy?
Re: [VB6] Use IFileOperation to replace SHFileOperation for modern Copy/Move box/prom
It turns out that you have already implemented this function. I have used this method to copy or delete files. As a result, the teacher will put forward a dialog box, and I have to close it manually. Think you have an excuse to trick him into not popping up the dialog box.
Re: [VB6] Use IFileOperation to replace SHFileOperation for modern Copy/Move box/prom
I'm using oleexp.tlb 6.7 with cFileOperation_v3.zip, I can not get the multiple files to work at all, any of them, copy, move and delete. Single file works fine.
It also shows successful but nothing happens. When I tried this with older versions of oleexp.tlb the multiple files worked. I just cant remember what version of oleexp.tlb it worked with.
After digging in more when doing the multiple files, when iFileOp.PerformOperations is called it returns -2147221019 which when I look up that it shows "No object for moniker".
When iFileOp.PerformOperations is called on a single file it returns 0.
Re: [VB6] Use IFileOperation to replace SHFileOperation for modern Copy/Move box/prom
I just tried multi-file copy and move and had no problem; is this happening with the demo app or your own code? If the former please show exactly the format string you're putting in the textbox; if the latter code for a minimal reproduction of the problem.
Re: [VB6] Use IFileOperation to replace SHFileOperation for modern Copy/Move box/prom
Both in the demo app and in my own program. Worked before and then just stopped.
In the demo app for the multiple files I have
C:\Users\User\Desktop\New Text Document (2).txt;C:\Users\User\Desktop\New Text Document (3).txt
Then for destination I have
C:\Users\User\Desktop\New folder (8)
For testing I just created two empty text files and then a folder. Single file at a time works no problem. Tested this with my Windows 7 in vmware that I use VB in and also windows 10 and 11 desktops.
Only thing I can think of that it would just stop working was when I updated to 6.7. Before that it was working fine.
Then some odd behavior, in my own program for my find duplicates tool, it was working and then started crashes the program when moving files to the recycle bin. I recompiled the code after putting back variables I removed that weren't being used and the box would come up, show all 7000 files and then it wouldn't actually move the files to the recycle bin, this was on Windows 11. When I would try running it again the box doesnt even bother coming up a 2nd time.
So I went back to my code to figure out what changed since it works a few months ago. Thats when I started using the demo app again to see if I missed something and then go the error I told you about and that it refused to work. Ironically if I put file names that dont exists it shows the error for it. I complied the demo, and ran it on my other systems and still didn't work. Im scratching my head on this one.
But the error is happening at the iFileOp.PerformOperations. Everything up to that is working when I dug into it.
Side note, I had found an old v4.7 that I still had, replaced the 6.7 with it and it still isnt working. Im not sure whats happening when the demo itself wont work.
Edit: Well Found the problem. Its the fact the files are zero bytes in size. I tried again with bigger files and multiple is working. Only problem is with my duplicates finder, if there is any zero byte files found then its going to fail.
Single file works fine with zero byte files, for some reason multiple files refuses to work with zero byte files.
Re: [VB6] Use IFileOperation to replace SHFileOperation for modern Copy/Move box/prom
Hm I'll have to look into this a bit more. Still can't reproduce, created two zero byte text files with the same names and moved them fine.
As for the box not coming up a second time, this is a known Windows bug starting in Windows 11 24H2. Numerous apps across different programming languages are currently being impacted by this with no solution so far found, not even in C++ where you have more precise control. The bug also impacts SHFileOperation, so you can't even step back to the previous API for this functionality.
Re: [VB6] Use IFileOperation to replace SHFileOperation for modern Copy/Move box/prom
Looks like I was wrong on the zero bytes issue. Changing the size of the two text files wasn't doing it. I then realized one of the txt files had an extra space in it names, so the demo technically was sending a file that didn't exist. I could put a ton of files in there and if a single one wasn't a valid file then none of them would work. Also there is no error with that extra space.
Also if New Text Document (3).txt is renamed to New Text Document (3) Test.txt and in the program its still looking for New Text Document (3).txt there is no error, same with adding an extra space to the file name. BUT if you rename it to New Text Document (30).txt the program will show an error saying something doesn't exist. This is why I didn't realize the extra space was keeping it from working. Not sure whats going on there.
I can easily handle that by adding a file exists command before sending the file list. Im curious how permissions might affect that. But if a single file doesn't exist then it completely fails. Will be a pain when trying to delete a ton of files if one of the files gets deleted before hand by something else.
So I thought ok so multiple files is working. On windows 7 I changed the delete button for multiple files and added cFO.Flags = FOF_ALLOWUNDO + FOF_WANTNUKEWARNING and it works, I get the warning popup and can cancel if I want.
So I tested on windows 10, while multiple files is working, neither the single file delete or multiple file delete will popup the box, it just deletes the files, no warning no popup. Yet on 7 it works. Haven't tried it on Windows 11 yet.
Re: [VB6] Use IFileOperation to replace SHFileOperation for modern Copy/Move box/prom
I see whats happening with multiple files and if the file doesn't exsist
When it is doing this
For i = 0 To UBound(m_Files)
apidl(i) = cfoGetPIDLFromPath(m_Files(i))
Next i
If the file doesn't exists then apidl(i) will equal 0. If that 0 is in there then it fails. Im going to see if I can adjust it to remove any that are 0 and only return a list with only the valid ones. That would save having to check it file if it exists or not.
Re: [VB6] Use IFileOperation to replace SHFileOperation for modern Copy/Move box/prom
OK I made this change, now any file that may not exist will no longer stop it from working as I remove any 0 ones that are found. This is just some quick code, might be a better way to do it.
After apply this new code to the demo and my own program the functions are working better. Still cant get the popups to work on 10 but they are 11. And the original 7000 files my find dups found and move to recycle bin wasnt working and is now working perfectly.
Replacing this in copyfiles, movefiles and deletefiles functions.
Code:
Dim i As Long
For i = 0 To UBound(m_Files)
apidl(i) = cfoGetPIDLFromPath(m_Files(i))
Next i
Dim hr As Long
hr = SHCreateShellItemArrayFromIDLists(cpidl, VarPtr(apidl(0)), isia)
With this
Code:
Dim i As Long
Dim apidl2() As Long
Dim lGoodCount As Long
lGoodCount = 0
For i = 0 To UBound(m_Files)
apidl(i) = cfoGetPIDLFromPath(m_Files(i))
If apidl(i) <> 0 Then lGoodCount = lGoodCount + 1
Next i
cpidl = lGoodCount
ReDim apidl2(lGoodCount - 1)
lGoodCount = 0
For i = 0 To UBound(apidl)
If apidl(i) <> 0 Then
apidl2(lGoodCount) = apidl(i)
lGoodCount = lGoodCount + 1
End If
Next i
Dim hr As Long
hr = SHCreateShellItemArrayFromIDLists(cpidl, VarPtr(apidl2(0)), isia)
Re: [VB6] Use IFileOperation to replace SHFileOperation for modern Copy/Move box/prom
Could do it more efficiently:
Code:
Dim i As Long, c As Long, tmp As Long
For i = 0 To UBound(m_Files)
tmp = cfoGetPIDLFromPath(m_Files(i))
If tmp Then
apidl(c) = tmp
tmp = 0: c = c + 1
End If
Next i
Dim hr As Long
hr = SHCreateShellItemArrayFromIDLists(c, VarPtr(apidl(0)), isia)
Re: [VB6] Use IFileOperation to replace SHFileOperation for modern Copy/Move box/prom
That is a lot better, I only did it that way because apidl was being redim to the size it needed, So I kept it like that and then counted to see what apidl2 should be redmin to.
Just cant figure out why the boxes are not showing up on 10 but are on 7 and 11.