Page 2 of 2 FirstFirst 12
Results 41 to 56 of 56

Thread: [VB6] Basic unzip without 3rd party DLL or shell32- IStorage-based

  1. #41
    Fanatic Member HackerVlad's Avatar
    Join Date
    Nov 2023
    Posts
    681

    Re: [VB6] Basic unzip without 3rd party DLL or shell32- IStorage-based

    Quote Originally Posted by fafalone View Post
    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.

  2. #42
    PowerPoster Arnoutdv's Avatar
    Join Date
    Oct 2013
    Posts
    6,734

    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??

  3. #43
    Fanatic Member HackerVlad's Avatar
    Join Date
    Nov 2023
    Posts
    681

    Re: [VB6] Basic unzip without 3rd party DLL or shell32- IStorage-based

    Quote Originally Posted by Arnoutdv View Post
    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.

  4. #44

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    7,653

    Re: [VB6] Basic unzip without 3rd party DLL or shell32- IStorage-based

    Quote Originally Posted by HackerVlad View Post
    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.

  5. #45

  6. #46
    Fanatic Member HackerVlad's Avatar
    Join Date
    Nov 2023
    Posts
    681

    Re: [VB6] Basic unzip without 3rd party DLL or shell32- IStorage-based

    Quote Originally Posted by fafalone View Post
    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.

  7. #47

  8. #48
    Fanatic Member HackerVlad's Avatar
    Join Date
    Nov 2023
    Posts
    681

    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.

  9. #49

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    7,653

    Re: [VB6] Basic unzip without 3rd party DLL or shell32- IStorage-based

    Quote Originally Posted by HackerVlad View Post
    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.

  10. #50
    Fanatic Member HackerVlad's Avatar
    Join Date
    Nov 2023
    Posts
    681

    Re: [VB6] Basic unzip without 3rd party DLL or shell32- IStorage-based

    Quote Originally Posted by fafalone View Post
    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.

  11. #51

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    7,653

    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.

  12. #52

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    7,653

    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.

  13. #53
    Fanatic Member HackerVlad's Avatar
    Join Date
    Nov 2023
    Posts
    681

    Re: [VB6] Basic unzip without 3rd party DLL or shell32- IStorage-based

    Quote Originally Posted by fafalone View Post
    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.

  14. #54

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    7,653

    Re: [VB6] Basic unzip without 3rd party DLL or shell32- IStorage-based

    Quote Originally Posted by HackerVlad View Post
    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.

  15. #55

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    7,653

    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.

  16. #56
    Fanatic Member HackerVlad's Avatar
    Join Date
    Nov 2023
    Posts
    681

    Re: [VB6] Basic unzip without 3rd party DLL or shell32- IStorage-based

    Quote Originally Posted by fafalone View Post
    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...

Page 2 of 2 FirstFirst 12

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
  •  



Click Here to Expand Forum to Full Width