locked
List directories in treeview RRS feed

  • Question

  • The following statement returns ALL directories in DirPath

    "For Each Dir In My.Computer.FileSystem.GetDirectories(DirPath)"

    How can I identify those directories that should be excluded from general use, such as $Recycle.bin, System Volume Information

    In other words, dulicate the function of Windows Explorer.

     

    Monday, April 19, 2010 12:14 PM

Answers

  • Gday again from Fred.

    Thanks for the comments and suggestions.

    And appologies for starting the second thread. That was a slip up at the time I posted it. Sorry.

    Need to say again, the question is not about how to code Treeview stuff.  Its about how to select the directories that need to be loaded in a Treeview when used as a folder browser. More to the point, NOT select directories such as $Recycle.bin. 

    My need is to browse for a folder and before I select it, see if a particular file exists in it. That can be done with a file list in a Explorer Form but all I want to check is one particlular file and dont want to have to scan all the files in the folder to see if the one I am looking for is there.

    The code below will do just that.  I found it on http://www.dreamincode.net/code/snippet2052.htm

    I have modified the code to -

            1 use a Treeview named tv1 already on the form.

            2 Show the selected directory in a label named lblMessage already on the form

            3 Excude certain directies by the use of a Function named fncAddThisDir

    It may or may not be "good" code. But it for me it does three things -

           1 Its easy to understand.

           2 It does what I want it to do.

           3 It works !

     

        Private Sub FormLoad(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load

            tv1.Nodes.Clear()

            For Each drv As DriveInfo In My.Computer.FileSystem.Drives

                If drv.IsReady Then Call LoadFolderTree(drv.Name)

            Next

            tv1.Nodes(0).Expand()

            On Error Resume Next

            tv1.Nodes(1).Expand()

     

     

        End Sub

     

     

     

        Private Sub tv1_AfterSelect(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles tv1.AfterSelect

            lblMessage.Text = tv1.SelectedNode.Tag

        End Sub

     

     

        Private Sub tv1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles tv1.KeyDown

            If e.KeyCode = Keys.Enter Then

                Dim snd As TreeNode = tv1.SelectedNode

                On Error Resume Next

                tv1.CollapseAll()

                snd.Expand()

                tv1.SelectedNode = snd

            End If

        End Sub

     

     

     

        Public Sub LoadFolderTree(ByVal path As String)

            Dim basenode As System.Windows.Forms.TreeNode, volbl As String, drvltr As String = path

            If IO.Directory.Exists(path) Then

                If path.Length <= 3 Then

                    volbl = My.Computer.FileSystem.GetDriveInfo(path).VolumeLabel

                    If Len(drvltr) = 3 Then drvltr = Mid(drvltr, 1, 2)

                    basenode = tv1.Nodes.Add(volbl & " (" & drvltr & ")")

                Else

                    basenode = tv1.Nodes.Add(My.Computer.FileSystem.GetName(path))

                End If

                basenode.Tag = path

                LoadDir(path, basenode)

            Else

                Throw New System.IO.DirectoryNotFoundException()

            End If

        End Sub

     

        Private Sub tv1_AfterExpand(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles tv1.AfterExpand

            Dim n As System.Windows.Forms.TreeNode

            For Each n In e.Node.Nodes

                LoadDir(n.Tag, n)

            Next

        End Sub

     

        Public Sub LoadDir(ByVal DirPath As String, ByVal Node As Windows.Forms.TreeNode)

            On Error Resume Next

            Dim Dir As String, DirName As String, Index As Integer

            If Node.Nodes.Count = 0 Then

                For Each Dir In My.Computer.FileSystem.GetDirectories(DirPath)

                    Index = Dir.LastIndexOf("\") : DirName = Dir.Substring(Index + 1, Dir.Length - Index - 1)

                    If fncAddThisDir(DirName) Then Node.Nodes.Add(DirName) : Node.LastNode.Tag = Dir : Node.LastNode.ImageIndex = 0

                Next

            End If

        End Sub

     

        Function fncAddThisDir(ByVal dirname As String) As Boolean

            If Mid(LCase(dirname), 1, 7) = "program" Then dirname = "Program"

            Select Case LCase(dirname)

                Case ""

                Case "$avg", "$recycle.bin"

                Case "documents and settings", "windows", "system volume information"

                Case "config.msi", "boot", "msocache", "perflogs"

                Case "hp", "recovery", "swsetup", "program"

                Case "recycler", ".wd_tv"

                Case Else : fncAddThisDir = True

            End Select

        End Function

     

     

     

     

    Fred.

     

     

     

     

    Index = Dir.LastIndexOf(

     

    LoadDir(n.Tag, n)

     

     

     

     

     

     

    basenode = tv1.Nodes.Add(volbl &

     

     

     

     

     

     

     

     

    lblMessage.Text = tv1.SelectedNode.Tag

     

     

     

     

     

    tv1.Nodes.Clear()

     

    Thanks again.
    • Marked as answer by Fred Zmith Tuesday, April 20, 2010 6:25 AM
    Tuesday, April 20, 2010 6:17 AM

All replies

  • See if this helps you:

    Imports System.Windows.Forms
    Imports System.IO
    
    
    Module Module1
    
     Sub Main()
      Application.Run(New Form1)
     End Sub
    
    End Module
    
    
    
    
    Public Class Form1
     Inherits System.Windows.Forms.Form
    
    #Region " Windows Form Designer generated code "
    
     Public Sub New()
      MyBase.New()
    
      'This call is required by the Windows Form Designer.
      InitializeComponent()
    
      'Add any initialization after the InitializeComponent() call
    
     End Sub
    
     'Form overrides dispose to clean up the component list.
     Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
      If disposing Then
       If Not (components Is Nothing) Then
        components.Dispose()
       End If
      End If
      MyBase.Dispose(disposing)
     End Sub
    
     'Required by the Windows Form Designer
     Private components As System.ComponentModel.IContainer
    
     'NOTE: The following procedure is required by the Windows Form Designer
     'It can be modified using the Windows Form Designer. 
     'Do not modify it using the code editor.
     Friend WithEvents TreeView1 As System.Windows.Forms.TreeView
     Friend WithEvents Button1 As System.Windows.Forms.Button
     <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
      Me.TreeView1 = New System.Windows.Forms.TreeView()
      Me.Button1 = New System.Windows.Forms.Button()
      Me.SuspendLayout()
      '
      'TreeView1
      '
      Me.TreeView1.ImageIndex = -1
      Me.TreeView1.Location = New System.Drawing.Point(16, 16)
      Me.TreeView1.Name = "TreeView1"
      Me.TreeView1.SelectedImageIndex = -1
      Me.TreeView1.Size = New System.Drawing.Size(256, 184)
      Me.TreeView1.TabIndex = 0
      '
      'Button1
      '
      Me.Button1.Location = New System.Drawing.Point(96, 224)
      Me.Button1.Name = "Button1"
      Me.Button1.Size = New System.Drawing.Size(96, 23)
      Me.Button1.TabIndex = 1
      Me.Button1.Text = "View Directories"
      '
      'Form1
      '
      Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
      Me.ClientSize = New System.Drawing.Size(292, 273)
      Me.Controls.AddRange(New System.Windows.Forms.Control() {Me.Button1, Me.TreeView1})
      Me.Name = "Form1"
      Me.Text = "TreeViewDemo"
      Me.ResumeLayout(False)
    
     End Sub
    
    #End Region
     Sub ProcessTree(ByVal Dir As String)
    
      TreeView1.BeginUpdate()
      TreeView1.Nodes.Add(New TreeNode(Dir))
      TreeView1.EndUpdate()
      TreeView1.Refresh()
    
      Dim DirObj As New DirectoryInfo(Dir)
    
      Dim Dirs As DirectoryInfo() = DirObj.GetDirectories("*.*")
    
      Dim DirectoryName As DirectoryInfo
    
      For Each DirectoryName In Dirs
       Try
        ProcessTree(DirectoryName.FullName)
       Catch E As Exception
        MessageBox.Show("Error accessing " & DirectoryName.FullName)
       End Try
      Next
    
     End Sub
    
     Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
      ProcessTree("C:\")
     End Sub
    End Class

    Reference: http://www.java2s.com/Code/VB/GUI/UseTreeViewtodisplaydirectory.htm


    []s.

    Alan. Twitter

    • Proposed as answer by Alan Cossari Monday, April 19, 2010 12:41 PM
    Monday, April 19, 2010 12:28 PM
  • Allan.

    Boy !  You're quick off the mark !

    At my age things dont happen quite that fast.

    I'll be back !

    And many thanks. You are greatly appreciated.

    Fred.

    Monday, April 19, 2010 12:35 PM
  • Allan, thanks.

    But, the issue is not one of code structure or how to code.

    It's determining whether a directory should be included in the line Treeview.Node.Add(path)

    Also, when I tried the code, it got stuck on the $Recycle directory adding each entry in the bin !

    Note, Windows Explorer doesnt list  c:\$Recycle.bin.   Why ?  How ?

    This is my question.

    Have a great day.

    Fred.

    • Merged by Liliane Teng Tuesday, April 20, 2010 1:53 AM a question pertains this thread
    Monday, April 19, 2010 12:58 PM
  • You cannot see C:\$Recycle.bin because its a "Protected Operating System Files". If you want to see it you have to do following steps

    1. Select "Folder and Search Options" from Toolbar  or "Folder Options" in Tools  in  Windows Explorer Menu
    2. Select View Tab
    3. Select "Show Hidden files, folders, and drives" RadioButton
    4. Uncheck "Hide protected operating system files (Recommended)" checkbox.

    Gaurav Khanna
    Monday, April 19, 2010 1:31 PM
  • Gaurav Khanna,

    The question is about Visual Basic Language.

    Its   NOT   about using Windows Explorer.

    In my question I said  "Note, Windows Explorer doesnt list  c:\$Recycle.bin.   Why ?  How ?"

    Guess I should have said inVisual Basic Why ? How ?

    In a previous question I asked about adding directories to a TreeView in a Visual Basic Program.

    Allan answered with some code and it was in response to this answer that I asked this second qquestion.

    In the following code line, Dir returns all directories, including C:\$Recycle.bin. What I need to find is how to identify those directories that are not for general use.

    "For Each Dir In My.Computer.FileSystem.GetDirectories(DirPath)"

    Fred

    Tuesday, April 20, 2010 12:09 AM
  • Please don't start a new thread if this question pertains another thread.. it clutters up the forums and confuses everyone because we have no idea what your other thread was about.
    Thanks..
    Tuesday, April 20, 2010 1:33 AM
  • Hello Fred,
    Welcome to MSDN Forum.
    As what bjames says,
    if your question pertains another thread,please don't start a new thread;
    If your question is a new problem,there is no relationship with this thread,please start a new thread.
    In order to facilate the Forum, I have merged your two threads.
    Wish you good luck.
    Best regards,
    Liliane


    Please mark the replies as answers if they help and unmark them if they provide no help. Thanks
    Tuesday, April 20, 2010 2:03 AM
  • I've actually been messing around with this just this week, the way I was doing it was this....
    If Directory.Exists(HomeTree.SelectedNode.FullPath) Then
    e.Node.Nodes.Clear()
    For Each dir As String In Directory.GetDirectories(HomeTree.SelectedNode.FullPath)
    Dim ds As New DirectoryInfo(dir)
    If ds.Attributes <> FileAttributes.Hidden _
    And ds.Attributes <> FileAttributes.System Then
    Dim newNode As New TreeNode(dir.Substring(dir.LastIndexOf("\") + 1))
    If e.Node.Nodes.IndexOf(newNode) < 0 Then
    e.Node.Nodes.Add(newNode)
    End If
    End If
    Next
    end if
    Please note the lines:
    Dim ds As New DirectoryInfo(dir)
    If ds.Attributes <> FileAttributes.Hidden _
    And ds.Attributes <> FileAttributes.System Then

    I've found that playing around with that can provide some good results. Mind you, I've found that some stuff shows up in windows 7 that shouldn't be there. C:\Documents and Settings\  for example (which apparently shouldn't exist in Win 7 in favour of C:\Users\ ), so unless you're aiming at XP, this will still need some playing with. At least now you know the options exist to play with.

    Happy coding :)

    PS, this is my first question response on the forums, let me know what I could be doing better.

    Tuesday, April 20, 2010 4:01 AM
  • Gday again from Fred.

    Thanks for the comments and suggestions.

    And appologies for starting the second thread. That was a slip up at the time I posted it. Sorry.

    Need to say again, the question is not about how to code Treeview stuff.  Its about how to select the directories that need to be loaded in a Treeview when used as a folder browser. More to the point, NOT select directories such as $Recycle.bin. 

    My need is to browse for a folder and before I select it, see if a particular file exists in it. That can be done with a file list in a Explorer Form but all I want to check is one particlular file and dont want to have to scan all the files in the folder to see if the one I am looking for is there.

    The code below will do just that.  I found it on http://www.dreamincode.net/code/snippet2052.htm

    I have modified the code to -

            1 use a Treeview named tv1 already on the form.

            2 Show the selected directory in a label named lblMessage already on the form

            3 Excude certain directies by the use of a Function named fncAddThisDir

    It may or may not be "good" code. But it for me it does three things -

           1 Its easy to understand.

           2 It does what I want it to do.

           3 It works !

     

        Private Sub FormLoad(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load

            tv1.Nodes.Clear()

            For Each drv As DriveInfo In My.Computer.FileSystem.Drives

                If drv.IsReady Then Call LoadFolderTree(drv.Name)

            Next

            tv1.Nodes(0).Expand()

            On Error Resume Next

            tv1.Nodes(1).Expand()

     

     

        End Sub

     

     

     

        Private Sub tv1_AfterSelect(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles tv1.AfterSelect

            lblMessage.Text = tv1.SelectedNode.Tag

        End Sub

     

     

        Private Sub tv1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles tv1.KeyDown

            If e.KeyCode = Keys.Enter Then

                Dim snd As TreeNode = tv1.SelectedNode

                On Error Resume Next

                tv1.CollapseAll()

                snd.Expand()

                tv1.SelectedNode = snd

            End If

        End Sub

     

     

     

        Public Sub LoadFolderTree(ByVal path As String)

            Dim basenode As System.Windows.Forms.TreeNode, volbl As String, drvltr As String = path

            If IO.Directory.Exists(path) Then

                If path.Length <= 3 Then

                    volbl = My.Computer.FileSystem.GetDriveInfo(path).VolumeLabel

                    If Len(drvltr) = 3 Then drvltr = Mid(drvltr, 1, 2)

                    basenode = tv1.Nodes.Add(volbl & " (" & drvltr & ")")

                Else

                    basenode = tv1.Nodes.Add(My.Computer.FileSystem.GetName(path))

                End If

                basenode.Tag = path

                LoadDir(path, basenode)

            Else

                Throw New System.IO.DirectoryNotFoundException()

            End If

        End Sub

     

        Private Sub tv1_AfterExpand(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles tv1.AfterExpand

            Dim n As System.Windows.Forms.TreeNode

            For Each n In e.Node.Nodes

                LoadDir(n.Tag, n)

            Next

        End Sub

     

        Public Sub LoadDir(ByVal DirPath As String, ByVal Node As Windows.Forms.TreeNode)

            On Error Resume Next

            Dim Dir As String, DirName As String, Index As Integer

            If Node.Nodes.Count = 0 Then

                For Each Dir In My.Computer.FileSystem.GetDirectories(DirPath)

                    Index = Dir.LastIndexOf("\") : DirName = Dir.Substring(Index + 1, Dir.Length - Index - 1)

                    If fncAddThisDir(DirName) Then Node.Nodes.Add(DirName) : Node.LastNode.Tag = Dir : Node.LastNode.ImageIndex = 0

                Next

            End If

        End Sub

     

        Function fncAddThisDir(ByVal dirname As String) As Boolean

            If Mid(LCase(dirname), 1, 7) = "program" Then dirname = "Program"

            Select Case LCase(dirname)

                Case ""

                Case "$avg", "$recycle.bin"

                Case "documents and settings", "windows", "system volume information"

                Case "config.msi", "boot", "msocache", "perflogs"

                Case "hp", "recovery", "swsetup", "program"

                Case "recycler", ".wd_tv"

                Case Else : fncAddThisDir = True

            End Select

        End Function

     

     

     

     

    Fred.

     

     

     

     

    Index = Dir.LastIndexOf(

     

    LoadDir(n.Tag, n)

     

     

     

     

     

     

    basenode = tv1.Nodes.Add(volbl &

     

     

     

     

     

     

     

     

    lblMessage.Text = tv1.SelectedNode.Tag

     

     

     

     

     

    tv1.Nodes.Clear()

     

    Thanks again.
    • Marked as answer by Fred Zmith Tuesday, April 20, 2010 6:25 AM
    Tuesday, April 20, 2010 6:17 AM
  • DaveB.

    Tried the code you mentioned. It didnt pick up any directory.

    But !  There must be a way. I will use what I have as way around it until I find it.

    The bit that didnt work is nelow.

    Many thanks. Fred.

    Dim ds As New DirectoryInfo(Dir)

    If ds.Attributes = FileAttributes.Hidden Then Stop

    If ds.Attributes = FileAttributes.System Then Stop

     

    Tuesday, April 20, 2010 6:49 AM
  • That's very odd to hear seeing as I literally copy and pasted from my working code :S.

    I'm not familiar with the 'Stop' keyword, could it be that it's exiting the loop after finding just one hidden or system file? I will try stepping through with your modifications when I have some free time (Hopefully by the end of the week at the latest).

    Also, just for reference, i'm on XP coding for the .Net framework 2 in Visual Studio 2005.

     

    PS. i just read through your working code, IMO good code is all three things you've listed, even if it's a bit more typing. Also, I am interested to know the function of "On Error Resume Next" and the colons in your LoadDir() sub. They're not things i've used before, are they pull overs from VB6 like Len() and Mid(), or have I just not come across them? (Thanks for indulging me)

    Tuesday, April 20, 2010 3:48 PM
  • DaveB

    The stop statement causes program execution to stop as if on a Toggle BreakPoint

    In respect to the line  "If ds.Attributes = FileAttributes.Hidden then Stop", it didnt stop.  Im sure it wouldnt cause an exit.

    I, using vs 2005 on win 7 pro. All updates are current.

    What is IMO ?

    Yes "On Error Resume Next" is from VB6.  It sets an error trap which causes the next line after the error to be executed.  So, one sets the trap when there is a possibility of an error and tests to see if there was with the line "If Err.Number <> 0 then . . . .".    Point about this is that the trap remains set until it has been either sprung by an error or unset by "On Error Goto 0".  

    When I found the TreeView code and copied it into my application, I noticed "On Error Resume Next" there and particularly noticed the absence of the most important comanion "On Error Goto 0".  I incorrectly assumed the more intelligent .net accomodated this irregularity.

    Iv had a good look at the program and removed it.  Iv got around the issue by testing for the directory name with If fncAddThisDir ... then ...

    Function fncAddThisDir(ByVal dirname As String) As Boolean
            If Mid(LCase(dirname), 1, 7) = "program" Then dirname = "Program"
            Select Case LCase(dirname)
                Case ""
                Case "$avg", "$recycle.bin"
                Case "documents and settings", "windows", "system volume information"
                Case "config.msi", "boot", "msocache", "perflogs"
                Case "hp", "recovery", "swsetup", "program"
                Case "recycler", ".wd_tv"
                Case Else : fncAddThisDir = True
            End Select
        End Function

    But the issue still remains, in the code below -

               how do you identify directories that Windows Explorer does displays.

               how do you identify directories that Windows Explorer does not display.

    Public Sub LoadDir(ByVal DirPath As String, ByVal Node As Windows.Forms.TreeNode)

            Dim Dir As String, DirName As String, Index As Integer
            If Node.Nodes.Count = 0 Then
                For Each Dir In My.Computer.FileSystem.GetDirectories(DirPath)
                    Index = Dir.LastIndexOf("\")
                    DirName = Dir.Substring(Index + 1, Dir.Length - Index - 1)
                    If fncAddThisDir(DirName) Then
                        Node.Nodes.Add(DirName)
                        Node.LastNode.Tag = Dir
                        Node.LastNode.ImageIndex = 0
                    End If
                Next

            End If
        End Sub

    This code picks up $Recycle.bin. How does one stop it doing that ?

    And, may I say, you are the one indulging me.  I am a retired accountant who learned a bit about programing from having to do it in the days when cobol was king and the then called IBM compatable PC was unknown. I watched as the many, many crashes were fixed and refixed, and put up with them until I paddled in the puddle myself.

    I am greatful for comments.

    Have a great day !

    Fred.

    ps Iv since learned how to put code in this forum.

    pps Mus be time for a glass of red or three.

     

    Wednesday, April 21, 2010 5:49 AM
  • Cobol? My parents have told me of their days with cobol :P

    Ah, seeing as you're on windows 7 and I'm running XP, i KNOW there are differences in how my code works. I will have to play with a windows 7 machine to help you out. Like I said above, it does let things through like 'Documents and Settings' which just should not be there on win7.

    I actually came across the whole "on error goto..." thing yesterday, where the article i was reading said that in VB.net the preferred method of exception handling was to use (quote) "the superior" try...catch... block.

    Good to know about the stop, sounds like this is the same as setting a conditional breakpoint, are there benefits to one over the other?

    PS. for reference:

    IMO = In my opinion

    IMHO = in my honest/humble opinion

    (usually used on the internet by people who have a lot of opinions, so I try to minimize use, occasionally it slips in though)

    Wednesday, April 21, 2010 1:40 PM