CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 7 of 8 FirstFirst ... 45678 LastLast
Results 91 to 105 of 112
  1. #91
    Join Date
    Jan 2006
    Location
    Fox Lake, IL
    Posts
    15,007

    Re: Loop through folders with shell object.

    GUID, maybe?
    David

    CodeGuru Article: Bound Controls are Evil-VB6
    2013 Samples: MS CODE Samples

    CodeGuru Reviewer
    2006 Dell CSP
    2006, 2007 & 2008 MVP Visual Basic
    If your question has been answered satisfactorily, and it has been helpful, then, please, Rate this Post!

  2. #92
    Join Date
    Apr 2009
    Posts
    394

    Re: Loop through folders with shell object.

    Don't know, as I can get any string literal ("C:\z\") to work but cannot get (variable) to work... and I also tried a byte array both unicode and ansi...

  3. #93
    Join Date
    Apr 2009
    Posts
    394

    Re: Loop through folders with shell object.

    Wohohoho, Muhahaha!!! Okay, finally got it to work via the use of a variable but there is one caveat I just noticed of which I will get into a moment, but first the code that works...
    Code:
    Option Explicit
    
    Dim ShellObject As Object
    
    Private Sub Form_Load()
    
    Set ShellObject = CreateObject("shell.application")
    
    ScanDir "C:\a\"
    
    End Sub
    
    Public Sub ScanDir(DirToScan As String)
    
    Dim FolderCollection As Object
    Dim SingleFolder As Object
    
    Set FolderCollection = ShellObject.namespace(Trim(DirToScan)) 'go figure???
    
    For Each SingleFolder In FolderCollection.items
      If SingleFolder.isfolder Then
        'ScanDir SingleFolder.Name 'uncomment for recursive search
        Debug.Print "Found Folder: " & SingleFolder.Name
      Else
        Debug.Print "Found File: " & SingleFolder.Name
      End If
    Next
    
    End Sub
    Okay, the result of this are...

    Found File: acmsetup.exe
    Found File: acmsetup.hlp
    Found File: adc.h
    Found File: adoctint.h
    Found File: adoid.h
    Found File: adoint.h
    Found File: adojet.h
    Found File: adojet.idl
    Found File: adomd.h
    Found File: adomd.idl
    Found File: anchorwi.gif
    Found File: br.gif
    Found File: clientsc.gif
    Found File: cmdtree.h
    Found Folder: comct332.cab
    Found Folder: comctl32.cab
    Found Folder: ComDlg32.CAB
    Found File: comments.gif
    Found File: dispex.dll
    Found File: divbgn.gif
    Found File: divend.gif
    Found File: eula.txt
    Found File: formbgn.gif
    Found File: formend.gif
    Found File: icrsint.h
    Found File: intro.dll
    Found File: jetoledb.h
    Found File: jetoledb.idl
    Found File: jetoledb.lib
    Found File: jscript.dll
    Found Folder: Mci32.cab
    Found File: msado15.h
    Found File: msado15.idl
    Found Folder: MSAdoDc.CAB
    Found Folder: MSBind.CAB
    Found Folder: mscdrun.cab
    Found Folder: MSChrt20.CAB
    Found Folder: MSComCt2.CAB
    Found Folder: MSComCtl.CAB
    Found File: msdadc.h
    Found File: msdaguid.h
    Found File: msdaora.h
    Found File: msdaosp.h
    Found File: msdasc.h
    Found File: msdasc.lib
    Found File: msdasql.h
    Found Folder: MSDatGrd.CAB
    Found Folder: MSDatLst.CAB
    Found File: msdatsrc.h
    Found File: msdatsrc.tlb
    Found Folder: msdbrptr.cab
    Found Folder: MSDERUN.CAB
    Found File: msdshape.h
    Found Folder: MSFlxGrd.CAB
    Found Folder: MSHFlxGd.CAB
    Found Folder: msinet.cab
    Found File: msjetodb.h
    Found Folder: MSMask32.CAB
    Found Folder: Msrdc20.cab
    Found Folder: msrdo20.cab
    Found File: msremote.h
    Found File: msscript.ocx
    Found File: msse.dll
    Found File: mssetup.dll
    Found Folder: msstdfmt.cab
    Found Folder: Msvbvm60.cab
    Found File: msvbvm60.dbg
    Found File: msvcep.dll
    Found Folder: MSWcRun.CAB
    Found Folder: mswinsck.cab
    Found File: mswless.dep
    Found File: mswless.ocx
    Found File: ocdb.h
    Found File: odbc32.lib
    Found File: odbccp32.lib
    Found File: odbcinst.h
    Found Folder: Oleaut.cab
    Found File: oleaut32.dbg
    Found File: oledb.h
    Found File: oledb.lib
    Found File: oledbdep.h
    Found File: oledberr.h
    Found File: osptk.lib
    Found File: pbgn.gif
    Found File: pend.gif
    Found File: persist.h
    Found Folder: PicClp32.CAB
    Found File: readme.htm
    Found File: redist.txt
    Found Folder: RichTx32.CAB
    Found File: selfreg.dll
    Found File: setup.ini
    Found File: setup.tdf
    Found File: setupsp6.exe
    Found File: setupsp6.lst
    Found File: simpdata.h
    Found File: simpdata.tlb
    Found File: sp698ent.dll
    Found File: sp698ent.inf
    Found File: sp698ent.stf
    Found File: spanbgn.gif
    Found File: spanend.gif
    Found File: sql.h
    Found File: sqlext.h
    Found File: sqloledb.h
    Found File: sqltypes.h
    Found File: sqlucode.h
    Found File: style.gif
    Found Folder: TabCtl32.CAB
    Found File: toc.htm
    Found File: unknownt.gif
    Found Folder: vbrun60.cab
    Found File: vbscript.dll
    Found File: vcredist.exe
    Found Folder: VS6sp61.cab
    Found Folder: VS6sp62.cab
    Found Folder: VS6sp63.cab
    Found Folder: VS6sp64.cab

    Do you see the caveat I am talking about in the above list??? (It is reporting cab files as folders and this really depends upon your point of view...)

    Different folder...

    Found File: Borland_Delphi_8.rar
    Found Folder: Delphi_7.zip

    ...as you could consider cab's, zip's, rar's, and so on as folders because they hold other files like a folder but call me a traditionilst, I consider them to be files... (reason rar is reported as a file is because I don't have a rar file reader on this computer... err so I should say I don't have a commercial rar file reader but I do have a vb6 project that will extract rar's and/or convert them into zip's (that is still under very slow construction...))



    So finally, (since we have highjacked this thread), I believe we have the problem of late binding this portion of the shell object solved...

    Whew...!!!

    (okay WoF, whats the speed Just kidding!)

  4. #94
    Join Date
    Jul 2006
    Location
    Germany
    Posts
    3,725

    Re: Loop through folders with shell object.

    This Trim() of a variable to make it work is really strange...

    I agree that a zip or cab is a file rather than a folder.
    The clou is to get more information about an item before proceeding:
    The namespace() method returns a Folder or Folder3 object.
    To get more information, the .self property returns its FolderItem interface.
    The FolderItem provides a .Type property and allows to use the .GetDetails() method of the folder object like this.
    Watch that the Folder object contains a collection of FolderItem objects (not of Folder objects)
    Assume we get a Folder object from the Namespace method.
    Code:
      Dim fo As Folder3, i%
      Set fo = SHL.NameSpace("C:\test\test.zip") 'or other zip file you have
      Debug.Print TypeName(fo), fo.Self.IsBrowsable 'shows that fo is Folder3 object and that it is browsable
      Debug.Print fo.Self.Type 'type of the FolderItem of fo
      For i = 0 To 9
        Debug.Print "Detail" & i & ": "; fo.GetDetailsOf(fo.Self, i)
      Next
    Try the same with a normal folder and a normal file. The results of the GetDetailsOf() method are different for each type of object (file, folder, zip file). I have not found detailed information, but on folders and files you will find the filesize, the creation and modification dates and more.

    What really worries me is: the Type string and the Details info you get is literally in the local language of your operating system.

  5. #95
    Join Date
    Apr 2009
    Posts
    394

    Re: Loop through folders with shell object.

    Yes I agree that the need to use the Trim Function to get it to work is strange, very strange indeed.

    As for retrieving that information based upon local info, well that would/could make things easier/harder for one if they are making a international program. Harder because if you needed to know the return value you would have to include it in your resource file for the country for comparisons and build your logic around the resource file reference. Easier if you only needed it for display.

    What worries me is what would happen to the speed increase we are seeing using this code as we would now need to do some, as you called it, heavy error checking (ref my dir search code) to test for each of these types and what actions we would need to do based upon those types...

    I think it is time I stop trying to late bind these different things and go to early binding as you have so I can explore these objects (scribble, scribble, scribble, RrrriiiiPP, then the sound of paper fluttering as it spins to land on the round tuit pile that always seems to grow and never shrink...).

    As one comedian would say, time to Get-er-dun

  6. #96
    Join Date
    Jul 2006
    Location
    Germany
    Posts
    3,725

    Re: Loop through folders with shell object.

    Hehehe.
    Yes, I'd recommend the early binding, too. It's much more fun to get intellisense give you all the choice you need. It is also interesting to examine the objects in the object browser (F2).
    The FolderItem interface and the Folder3 object are the relevant objects.

    I will try to make this little expansion to my folder scanner benchmark:
    To stop the loop from scanning archives I will examine the .Type property, or compare name extension against a set of ".zip.cab.rar..." to treat them like a file.

  7. #97
    Join Date
    Apr 2009
    Posts
    394

    Re: Loop through folders with shell object.

    Just one more note on the late binding I have been playing with. I found, by accident, another thread doing some of what we are doing in this thread and in their call to the potential recursive function, they use As Variant. So no need for Trim() on the .Namespace(variablename) 'go figure???

    Also WoF, I know you will be interested in this..., the properties they use (GetDetailsOf) go from -1 to 34 where -1 equals the tooltop in windows explorer when you hover with the mouse. Comments are always 14 on XP with a disclaimer that it may be different with other OS's and a comment that the only items that are always available for a folder are -1 to 4.

    So, one would wonder that there should be a way to do a for each on this... (scribble...flutter...d a m n!!!)

  8. #98
    Join Date
    Jul 2006
    Location
    Germany
    Posts
    3,725

    Re: Loop through folders with shell object.

    This IS interesting. I know from experiments that the #3 is modification date and propert #4 is the modification date.

    Strange enough all literal answers like Type are given in the localized language. My german system says "ZIP komprimierter Ordner" for a zip file, but the dates are given in an english/american format.
    It would be interesting if there is a non-localized way of determining the item type...

    What is that with the Variant type? Where do I have to put the As Variant declaration?

  9. #99
    Join Date
    Jul 2008
    Location
    WV
    Posts
    5,362

    Re: Loop through folders with shell object.

    Quote Originally Posted by vb5prgrmr View Post
    Just one more note on the late binding I have been playing with. I found, by accident, another thread doing some of what we are doing in this thread and in their call to the potential recursive function, they use As Variant. So no need for Trim() on the .Namespace(variablename) 'go figure???
    Apparently the function wants a variant or a pointer as a parameter. If memory serves a variant datatype is in effect a pointer to the memory location of the given data.

    Trim() returns a variant where-as Trim$() returns a string This would explain the reason it worked with Trim() but not with a string.
    Always use [code][/code] tags when posting code.

  10. #100
    Join Date
    Apr 2009
    Posts
    394

    Re: Loop through folders with shell object.

    Using the last code example I gave, it would be changed to...
    Code:
    Option Explicit
    
    Dim ShellObject As Object
    
    Private Sub Form_Load()
    
    Set ShellObject = CreateObject("shell.application")
    
    ScanDir "C:\a\"
    
    End Sub
    
    Public Sub ScanDir(DirToScan As Variant)
    
    Dim FolderCollection As Object
    Dim SingleFolder As Object
    
    Set FolderCollection = ShellObject.namespace(DirToScan)
    For Each SingleFolder In FolderCollection.items
      If SingleFolder.isfolder Then
        'ScanDir SingleFolder.Name 'uncomment for recursive search
        Debug.Print "Found Folder: " & SingleFolder.Name
      Else
        Debug.Print "Found File: " & SingleFolder.Name
      End If
    Next
    
    End Sub
    and datamiser, (hits self on head), well duh, that makes sense now that you remind me of it... and come to think of it, being that this portion was designed for scripting and in scripting you cannot type variables...

  11. #101
    Join Date
    Jul 2006
    Location
    Germany
    Posts
    3,725

    Re: Loop through folders with shell object.

    I have made a little application which helps explore the shell automation and makes use of the shell32.FolderItem and shell32.Folder objects.
    A TreeView is filled starting from the Desktop, like an explorer tree would be, although I put in all the non-folders (files/items), too.
    Clicking on a node in the tree will display infos in the left TextBox.
    It will display all interesting info including those obtained by GetDetailsOf() method of the (parent) folder. A Detail is only displayed, if the returned string is not "".

    It appears that some objects like a local drive may return up to 40 DetailsOf.

    It is a bit bewildering what comes back from this method.
    If the object is a diskdrive, Detail #0 will be literally "Name", Detail #1 will be literally "Size" whereas when you go into the drive and click a file, #0 will be the real name of the file and #1 will be its real size.

    I'm still a little confused about using the shell objects, because of the localized DetailOf strings, but it seems they are a rather good alternative to the FSO.

    Look how the tree is able to browse all Desktop Namespaces, including Nethood, Control Panel, etc. You cannot do this with FSO.

    If you look at the code, a few simple changes can make the tree only display folders like a real explorer tree, so as you could implement a ListView to display the files in that folder.

    Well it is just a start-off to play a little with shell32 stuff.
    Attached Files Attached Files

  12. #102
    Join Date
    May 2010
    Posts
    12

    Re: Loop through folders with shell object.

    Quote Originally Posted by DataMiser View Post
    Apparently the function wants a variant or a pointer as a parameter. If memory serves a variant datatype is in effect a pointer to the memory location of the given data.

    Trim() returns a variant where-as Trim$() returns a string This would explain the reason it worked with Trim() but not with a string.
    If the function wants a pointer, why dont give it what it wants? Try VarPtr() with a String variable. This way there would be no need of using the Variant DataType.

  13. #103
    Join Date
    Apr 2009
    Posts
    394

    Re: Loop through folders with shell object.

    Dagnarus,

    If you had read my posts on the subject, you would have seen that I tried both varptr and strptr and both did not work... and it was also I who found that the trim and the variant solutions...

  14. #104
    Join Date
    Aug 2010
    Posts
    9

    Re: Loop through folders with shell object.

    I don't know if you guys got any further with the shell method, or even care but after a lot of trial and error I just had to share:

    The FolderItems3 collection has a filter property: Filter(grfFlags As Long, bstrFileSpec As String)
    The FileSpec is the familiar *.??? stuff and you can use multiple specs separated by a ; .
    The grfFlags is a combo of the values in the SHCONTF enumeration.

    So: if clItems is a FolderItems3
    Code:
      clItems.Filter SHCONTF_FOLDERS Or SHCONTF_INCLUDEHIDDEN, "*"
      For Each oFolderItem In clItems
        If oFolderItem.IsFileSystem Then
              colFolders.Add oFolderItem.GetFolder
              numDirs = numDirs + 1
        End If
      Next oFolderItem
    
      clItems.Filter SHCONTF_NONFOLDERS Or SHCONTF_INCLUDEHIDDEN, "*"
      For Each oFolderItem In clItems
            numFiles = numFiles + 1
      Next oFolderItem
    I am using this in a non-recursive procedure, I am also scanning the entire drive. For some reason the folderitem isfolder test calls zips and cabs folders. The filter function seems to weed those out when done this way. The snippet I posted gives me the same number of files and folders that I get when I select everything in the C:\ folder and choose properties, so I think these are the proper results.

    In order to use this method you need to run through folders and files separately. It's not a speed hit though, because each item is still only done once. It also gives you the chance to use the FileSpec argument.

    Hope someone finds this helpful.

    By the way: SHCONTF_INCLUDEHIDDEN = &H80, SHCONTF_NONFOLDERS = &H40 , SHCONTF_FOLDERS = &H20

  15. #105
    Join Date
    Jul 2006
    Location
    Germany
    Posts
    3,725

    Re: Loop through folders with shell object.

    Helpful it is. I was already wondering about how to implement pattern matching.

    You could possibly do it in one pass:
    Code:
      clItems.Filter SHCONTF_FOLDERS Or SHCONTF_NONFOLDERS Or SHCONTF_INCLUDEHIDDEN, "*"
      For Each oFolderItem In clItems
        If oFolderItem.IsFileSystem Then
           If oFolderItem.IsFolder Then
              colFolders.Add oFolderItem.GetFolder
              numDirs = numDirs + 1
           Else
              numFiles=NumFiles+1
           End If
        End If
      Next oFolderItem

Page 7 of 8 FirstFirst ... 45678 LastLast

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

Featured