|
-
Feb 26th, 2025, 04:22 AM
#41
Fanatic Member
Re: [VB6] Basic unzip without 3rd party DLL or shell32- IStorage-based
 Originally Posted by fafalone
The stat type has the times, pass them to SetFileTimes if you want. Maybe I'll add it but it's a low priority... This is a proof of concept demonstration, not a full featured unzip app.
Another interesting feature: setting the date and time will not work in XP, only in Vista+
For some reason, in XP, the structure is not filled with the time value. All three time values in XP are zeros.
-
Feb 26th, 2025, 04:23 AM
#42
Re: [VB6] Basic unzip without 3rd party DLL or shell32- IStorage-based
Why insist of using this method if there are multiple other methods available??
-
Feb 26th, 2025, 04:35 AM
#43
Fanatic Member
Re: [VB6] Basic unzip without 3rd party DLL or shell32- IStorage-based
 Originally Posted by Arnoutdv
Why insist of using this method if there are multiple other methods available??
You will have to write a very lot of lines of code to get it using another method. Not to mention that it's an extra overhead. It will be slower in the end.
-
Feb 26th, 2025, 04:43 AM
#44
Re: [VB6] Basic unzip without 3rd party DLL or shell32- IStorage-based
 Originally Posted by HackerVlad
Thank you so much for watching. However, Windows Explorer itself extracts files from archives with the automatic setting of file attributes. Windows does it somehow... I wish we could do that...
After all, a real full-fledged file extraction procedure includes the mandatory setting of the date, time, and file attributes. Otherwise, it's not a full-fledged unpacking.
Yes you could use Windows to extract a zip archive and the attributes will be set, you just can't read them prior to extraction with that method.
Here's a proof of concept, it works with tB/WinDevLib, I'll leave the switch to VB6/oleexp to you, and note that it's Vista+. XP support would require a major rewrite (though same principle), before XP not possible.
Attributes and file times are set automatically.
Code:
Private Function ExtractByShell(pszZip As String, pszDest As String) As Long
If PathFileExistsW(StrPtr(pszZip)) = 0 Then
ExtractByShell = ERROR_FILE_NOT_FOUND
Exit Function
End If
If PathFileExistsW(StrPtr(pszZip)) = 0 Then
SHCreateDirectory 0, pszDest 'Note: For VB6 you'd change DeclareWide to Declare, String to LongPtr, and use StrPtr. I'll add an overload to next WDL version to avoid this.
End If
Dim siZip As IShellItem
Dim siDest As IShellItem
Dim siChild As IShellItem
Dim pEnum As IEnumShellItems
Dim pArray As IShellItemArray
Dim pCopy As New FileOperation
Dim pidl() As LongPtr
Dim cPidl As Long
Dim pPIDL As IPersistIDList
Dim lRet As Long
lRet = SHCreateItemFromParsingName(StrPtr(pszZip), Nothing, IID_IShellItem, siZip)
lRet = SHCreateItemFromParsingName(StrPtr(pszDest), Nothing, IID_IShellItem, siDest)
If (siZip Is Nothing) Or (siDest Is Nothing) Then
ExtractByShell = ERROR_FILE_NOT_FOUND
Exit Function
End If
lRet = siZip.BindToHandler(0, BHID_EnumItems, IID_IEnumShellItems, pEnum)
If (pEnum Is Nothing) = False Then
Do While pEnum.Next(1, siChild) = S_OK
Set pPIDL = siChild
ReDim Preserve pidl(cPidl)
pPIDL.GetIDList pidl(cPidl)
cPidl = cPidl + 1
Loop
If cPidl Then
SHCreateShellItemArrayFromIDLists cPidl, VarPtr(pidl(0)), pArray
If (pArray Is Nothing) = False Then
pCopy.CopyItems pArray, siDest
pCopy.PerformOperations
pCopy.GetAnyOperationsAborted lRet
End If
FreeIDListArray pidl, cPidl
End If
End If
ExtractByShell = lRet
End Function
(In 2015 when this thread was started, I was fresh off a 6 year break from programming and forgot most of the shell stuff, a lot of which wasn't even around in my original time, Vista didn't come out until 2007 and I didn't even install it before breaking in 2009-2014).
Last edited by fafalone; Feb 26th, 2025 at 02:12 PM.
-
Feb 26th, 2025, 06:26 AM
#45
Fanatic Member
Re: [VB6] Basic unzip without 3rd party DLL or shell32- IStorage-based
Thank you so much for your help. But will this code be able to unpack the docx file, or will there be problems with this?
-
Feb 26th, 2025, 08:14 AM
#46
Fanatic Member
Re: [VB6] Basic unzip without 3rd party DLL or shell32- IStorage-based
 Originally Posted by fafalone
it works with tB/WinDevLib, I'll leave the switch to VB6/oleexp to you
You gave me incomplete code, which is why I've wasted several hours and still haven't been able to run this code. Even with all libraries connected in Twin Basic, there is still an unknown variable BHID_EnumItems, IID_IEnumShellItems. I really need your help to get these values.
-
Feb 26th, 2025, 09:24 AM
#47
Re: [VB6] Basic unzip without 3rd party DLL or shell32- IStorage-based
Use MagnumDB for any constants you need:
BHID_EnumItems
IID_IEnumShellItems
-
Feb 26th, 2025, 09:46 AM
#48
Fanatic Member
Re: [VB6] Basic unzip without 3rd party DLL or shell32- IStorage-based
Thanks you very muth
You've helped me a lot, as the function I found doesn't work for some reason!
Code:
Private Function BHID__EnumItems() As UUID
Dim lpIID As UUID
lpIID.Data1 = &H70629033
lpIID.Data2 = &HE363
lpIID.Data3 = &H4A28
lpIID.Data4(0) = &HA5
lpIID.Data4(1) = &H67
lpIID.Data4(2) = &HD
lpIID.Data4(3) = &HB7
lpIID.Data4(4) = &H80
lpIID.Data4(5) = &H6
lpIID.Data4(6) = &HE6
lpIID.Data4(7) = &HD7
BHID__EnumItems = lpIID
End Function
Of course, it's best to use the CLSIDFromString function, it's more reliable this way! And I just needed such a convenient database where I could find the CLSID by class name.
-
Feb 26th, 2025, 11:43 AM
#49
Re: [VB6] Basic unzip without 3rd party DLL or shell32- IStorage-based
 Originally Posted by HackerVlad
You gave me incomplete code, which is why I've wasted several hours and still haven't been able to run this code. Even with all libraries connected in Twin Basic, there is still an unknown variable BHID_EnumItems, IID_IEnumShellItems. I really need your help to get these values.
First of all, for twinBASIC, the code is complete. As noted (" it works with tB/WinDevLib"), you need to enable the WinDevLib package ("Windows Development Library for twinBASIC") and that's it. It includes all interfaces, APIs, constants, and GUIDs, including the two you mentioned. If you've never added a package manager package to tB before, here's an illustrated guide of how to add WinDevLib. You open settings, go to references, then the packages tab, and check a box; it's no huge burden. The *whole point* of WinDevLib is you can just write code like I did without having to manually define everything, you just tick a box and 99.99% of common Windows API stuff is available.
Second, for VB6, you could have either copied them from WDL or used mIID.bas, which comes with oleexp, in the same zip.
Last edited by fafalone; Feb 26th, 2025 at 12:04 PM.
-
Feb 26th, 2025, 12:20 PM
#50
Fanatic Member
Re: [VB6] Basic unzip without 3rd party DLL or shell32- IStorage-based
 Originally Posted by fafalone
First of all, for twinBASIC, the code is complete. As noted (" it works with tB /WinDevLib"), you need to enable the WinDevLib package ("Windows Development Library for twinBASIC") and that's it. It includes all interfaces, APIs, constants, and GUIDs, including the two you mentioned. If you've never added a package manager package to tB before, here's an illustrated guide of how to add WinDevLib. You open settings, go to references, then the packages tab, and check a box; it's no huge burden. The *whole point* of WinDevLib is you can just write code like I did without having to manually define everything, you just tick a box and 99.99% of common Windows API stuff is available.
Second, for VB6, you could have either copied them from WDL or used mIID.bas, which comes with oleexp, in the same zip.
Yes, I've already figured it out and run this code. He works.
However, I am not deceiving you when I say that for some reason the Twin Basic does not find these two variables, even with all your library connected (I did as per the instructions), I swear to you that the twin basic does not see me.
-
Feb 26th, 2025, 01:50 PM
#51
Re: [VB6] Basic unzip without 3rd party DLL or shell32- IStorage-based
You must have changed something; like added local copies defined as String when you were trying to use CLSIDFromString. Or forgot to change it back from two underscores to one after removing the local copies you made with that difference like in your post of BHID_EnumItems where you changed the name: In post 48 you posted it as B H I D _ _ E n u m I t e m s when in my original code and my package it's B H I D _ E n u m I t e m s. If you changed my code to use your function, then removed your function, you need to change my code back to the original, a single _ in the name.
There's no way just those two could be missing. They're in the same module as IID_IShellItem; wdIID.twin, on lines 5961 and 2693. I've used them in dozens of projects.
Here's the exact project file I wrote to make and test the code. You'll see there's nothing but that function, Command1_Click that has ExtractByShell Text1.Text, Text2.Text, a Form with those two text boxes, and WinDevLib as an added package. There's no errors.
Last edited by fafalone; Feb 26th, 2025 at 02:06 PM.
-
Feb 26th, 2025, 04:36 PM
#52
Re: [VB6] Basic unzip without 3rd party DLL or shell32- IStorage-based
Simpler:
Code:
Private Function ExtractByShell(pszZip As String, pszDest As String) As Long
If PathFileExistsW(StrPtr(pszZip)) = 0 Then
ExtractByShell = ERROR_FILE_NOT_FOUND
Exit Function
End If
If PathFileExistsW(StrPtr(pszZip)) = 0 Then
SHCreateDirectory 0, pszDest 'Note: For VB6 you'd change DeclareWide to Declare, String to LongPtr, and use StrPtr. I'll add an overload to next WDL version to avoid this.
End If
Dim siZip As IShellItem
Dim siDest As IShellItem
Dim pEnum As IEnumShellItems
Dim pCopy As New FileOperation
Dim lRet As Long
lRet = SHCreateItemFromParsingName(StrPtr(pszZip), Nothing, IID_IShellItem, siZip)
lRet = SHCreateItemFromParsingName(StrPtr(pszDest), Nothing, IID_IShellItem, siDest)
If (siZip Is Nothing) Or (siDest Is Nothing) Then
ExtractByShell = ERROR_FILE_NOT_FOUND
Exit Function
End If
lRet = siZip.BindToHandler(0, BHID_EnumItems, IID_IEnumShellItems, pEnum)
If (pEnum Is Nothing) = False Then
pCopy.CopyItems pEnum, siDest
pCopy.PerformOperations
pCopy.GetAnyOperationsAborted lRet
End If
ExtractByShell = lRet
End Function
Last edited by fafalone; Feb 26th, 2025 at 05:01 PM.
-
Feb 26th, 2025, 04:42 PM
#53
Fanatic Member
Re: [VB6] Basic unzip without 3rd party DLL or shell32- IStorage-based
 Originally Posted by fafalone
You must have changed something; like added local copies defined as String when you were trying to use CLSIDFromString. Or forgot to change it back from two underscores to one after removing the local copies you made with that difference like in your post of BHID_EnumItems where you changed the name: In post 48 you posted it as B H I D _ _ E n u m I t e m s when in my original code and my package it's B H I D _ E n u m I t e m s. If you changed my code to use your function, then removed your function, you need to change my code back to the original, a single _ in the name.
There's no way just those two could be missing. They're in the same module as IID_IShellItem; wdIID.twin, on lines 5961 and 2693. I've used them in dozens of projects.
Here's the exact project file I wrote to make and test the code. You'll see there's nothing but that function, Command1_Click that has ExtractByShell Text1.Text, Text2.Text, a Form with those two text boxes, and WinDevLib as an added package. There's no errors.
Yes, apparently there was a conflict with another connected library, especially if you check TWO boxes and connect your two WinDevLib libraries, then this code will no longer work. Well, it looks like I've already figured out what the problem was. There should be only one library.
Your example is good, thank you.
-
Feb 26th, 2025, 04:45 PM
#54
Re: [VB6] Basic unzip without 3rd party DLL or shell32- IStorage-based
 Originally Posted by HackerVlad
Yes, apparently there was a conflict with another connected library, especially if you check TWO boxes and connect your two WinDevLib libraries, then this code will no longer work. Well, it looks like I've already figured out what the problem was. There should be only one library.
Your example is good, thank you.
There shouldn't be a conflict; they're meant to work together in the event you need the special versions of interfaces for use with Implements... Only problem would be if put the wrong one higher you'd get some different arguments in some interfaces but I'll look into it.
-
Feb 26th, 2025, 07:32 PM
#55
Re: [VB6] Basic unzip without 3rd party DLL or shell32- IStorage-based
Do While pEnum.Next(1, siChild) = S_OK has its 3rd argument as not optional if you put WinDevLibImpl ahead of WinDevLib in the priority list, but I can't reproduce it finding IID_IShellItem but not those other two under any scenario.
-
Feb 27th, 2025, 06:19 AM
#56
Fanatic Member
Re: [VB6] Basic unzip without 3rd party DLL or shell32- IStorage-based
 Originally Posted by fafalone
Do While pEnum.Next(1, siChild) = S_OK has its 3rd argument as not optional if you put WinDevLibImpl ahead of WinDevLib in the priority list, but I can't reproduce it finding IID_IShellItem but not those other two under any scenario.
By the way, I immediately noticed about the third parameter. So much for the library conflict.
P.S. Forget about IID_IShellItem, apparently I just had a glitch in the Twin Basic at that time...
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|