Solved

Problems with recursively drilling down for sub folders using FileSystemObject

Posted on 2013-06-19
19
591 Views
Last Modified: 2013-07-08
Hello,

This is minor, and I know it's a pain.... but I have this connector code from Chazzuka.com and it worked until I moved everything over to another server.

I have a series of folders on the file system and I indeed get all the parent folders for a specific company ID, but that's where it stops. I control the server and I know that there are more than one folder per parent project folder.

I'm using Windows Server 2012 which is really not bad at all.

The code is VBScript and using CLASSIC ASP. But the base code is VBScript so ignore the CLASSIC ASP Part.

Set ObjFolder = ObjFSO.GetFolder(BaseFileDir)
        
               For Each ObjSubFolder In ObjFolder.SubFolders
               
                        i__FolderName = ObjSubFolder.name
                        Html = Html + "<li class=""first_li directory collapsed""><a href=""#"" onclick=""setFolderName('"+(i__FolderName)+"');setBaseFileDir('"+(BaseFileDir+i__FolderName)+"');"" rel="""+(BaseFileDir+i__FolderName+"/")+""">"+(i__FolderName)+"</a></li>"&VBCRLF
               Next

Cut an paste into your favorite editor for clarity.

So, I need to drill down into the parent folder and children and grandchildren, if Exists.

For example:

Parent
|--Child 1
    |--Child 2 and so on.... get me?

but all I get is PARENT.  When I click on the file tree explorer I get no errors whatsoever, using CHROME for debugging.

Please help, I need to do  a demo tomorrow and need to get this working tonight.

Thanks,

Peter
0
Comment
Question by:pborregg
  • 10
  • 6
  • 2
  • +1
19 Comments
 
LVL 51

Expert Comment

by:Bill Prew
ID: 39261228
Well, at best that code would only get the first level of folders, not second level.  Do you want to do the same thing with both sublevels?

~bp
0
 
LVL 51

Expert Comment

by:Bill Prew
ID: 39261244
This test from CSCRIPT seemed to work fine for me, got both levels now.  Not as elegant as it could be but gets the job done.

BaseFileDir = "c:\temp"
Set ObjFSO = CreateObject("Scripting.FileSystemObject")
Set ObjFolder = ObjFSO.GetFolder(BaseFileDir)
For Each ObjSubFolder In ObjFolder.SubFolders
   i__FolderName = ObjSubFolder.name
   Wscript.Echo i__FolderName
   Html = Html + "<li class=""first_li directory collapsed""><a href=""#"" onclick=""setFolderName('"+(i__FolderName)+"');setBaseFileDir('"+(BaseFileDir+i__FolderName)+"');"" rel="""+(BaseFileDir+i__FolderName+"/")+""">"+(i__FolderName)+"</a></li>"&VBCRLF
   For Each ObjSubFolder2 In ObjSubFolder.SubFolders
      i__FolderName = ObjSubFolder2.name
      Wscript.Echo "  " & i__FolderName
      Html = Html + "<li class=""first_li directory collapsed""><a href=""#"" onclick=""setFolderName('"+(i__FolderName)+"');setBaseFileDir('"+(BaseFileDir+i__FolderName)+"');"" rel="""+(BaseFileDir+i__FolderName+"/")+""">"+(i__FolderName)+"</a></li>"&VBCRLF
   Next
Next

Open in new window

~bp
0
 
LVL 52

Expert Comment

by:Scott Fell, EE MVE
ID: 39261245
This is what you need  http://www.devx.com/tips/Tip/27130
dim MyFolder
MyFolder="c:\inetpub\site\somefolder\"

  Dim fs, f, f1, fc, s
    Set fs = CreateObject("Scripting.FileSystemObject")
    Set f = fs.GetFolder(MyFolder)
    Set fc = f.SubFolders
    For Each f1 in fc
        s = s & f1.name
        s = s &  "<br>"
    Next
    response.write s
0
 

Author Comment

by:pborregg
ID: 39267830
This is what works.... but:

<%@LANGUAGE="VBSCRIPT" CODEPAGE="65001"%>
<%

      Dim fso
      Dim ObjOutFile
      Dim BaseFileDir
      
      'Creating File System Object
      Set fso = CreateObject("Scripting.FileSystemObject")
      
      'Create an output file
      'Set ObjOutFile = fso.CreateTextFile("OutputFiles.csv")
      
      'Writing CSV headers
      'ObjOutFile.WriteLine("Type,File Name,File Path")
      
      'Call the GetFile function to get all files
      'GetFiles("d:\content\" & Session("COMPANYID") & "\projects\" & Session("SV_PID") & "\")
      
      BaseFileDir = "d:\content\" & Session("COMPANYID") & "\projects\" & Session("SV_PID") & "\"
      
      'Close the output file
      'ObjOutFile.Close
      
      'Response.Write("Completed")

      Html = Html +  "<ul class=""jqueryFileTree"" style=""display:none;"">"&VBCRLF  
      
      'Function GetFiles(FolderName)

      ' if given folder is exists
      if fso.FolderExists("d:\content\" & Session("COMPANYID") & "\projects\" & Session("SV_PID")) then
      
            On Error Resume Next
             
            Dim ObjFolder
            Dim ObjSubFolders
            Dim ObjSubFolder
            Dim ObjFiles
            Dim ObjFile
            Dim Html
      
            Set ObjFolder = fso.GetFolder(BaseFileDir)
            Set ObjFiles = ObjFolder.Files
             
            'Getting all subfolders
            Set ObjSubFolders = ObjFolder.SubFolders
            
            For Each ObjFolder In ObjSubFolders
                  'Writing SubFolder Name and Path
                  'Response.Write("Folder," & ObjFolder.Name & "," & ObjFolder.Path) &vbCrLf

                        i__FolderName=ObjFolder.name
                     Html = Html + "<li class=""first_li directory collapsed""><a href=""#"" onclick=""setFolderName('"+(i__FolderName)+"');setBaseFileDir('"+(BaseFileDir+i__FolderName)+"');"" rel="""+(BaseFileDir+i__FolderName)+""">"+(i__FolderName)+"</a></li>"&VBCRLF                  


                  'Getting all Files from subfolder
                  'GetFiles(ObjFolder.Path)
            Next

            'Write all files to output files
            For Each ObjFile In ObjFiles
                  'Response.Write("File," & ObjFile.Name & "," & ObjFile.Path) &vbCrLf

               ' name
               i__FileName=ObjFile.name
               ' extension
               i__Ext = LCase(Mid(i__Name, InStrRev(i__FileName, ".", -1, 1) + 1))
               Html = Html + "<li class=""inner_li file ext_"&i__Ext&"""><a href=""#"" onclick=""setFolderName('"+(ObjFolder.Name)+"');"" rel="""+(i__FileName)+""">"+(i__FileName)+"</a></li>"&VBCRLF
                  
            Next

            Html = Html +  "</ul>"&VBCRLF

end if
      'End Function



            Response.Write Html
            
%>


What's happening is that when I click on a folder the same tree of parent folders displays under each of the 35 folders listed.  But, in reality, there are no sub folders at all!!!!

Where is my code going wrong?

Thanks.

Peter
0
 

Author Comment

by:pborregg
ID: 39267832
NOTE: If I remove the "REL" attribute, nothing is displayed.

This is from JqueryFileTree from A Beautiful Site...

http://labs.abeautifulsite.net/archived/jquery-fileTree/demo/
0
 
LVL 82

Accepted Solution

by:
hielo earned 500 total points
ID: 39287642
>>I indeed get all the parent folders for a specific company ID, but that's where it stops
That plugin initially loads only the "top-level" list of files and/or folders upon page load.  If you then click on a folder, it emits a POST ajax request, sending the path of the selected folder via a variable named "dir". On the code you posted you are not using the POSTed variable to retrieve the content of the clicked folder.  The code below is untested, but it should get you very close to achieving your goal:
<%@LANGUAGE="VBSCRIPT" CODEPAGE="65001"%>
<%
Dim fso, BaseFileDir, selectedFolder, ObjFolder, ObjSubFolder, ObjFile, Html, temp
Html=""
'Creating File System Object
Set fso = CreateObject("Scripting.FileSystemObject")
selectedFolder=CStr(Request.Form("dir"))
selectedFolder = Replace( selectedFolder, "../","")
selectedFolder = ereg_replace( selectedFolder, "(^/+|/+$)", "", True )
selectedFolder = Replace( selectedFolder, "/","\")

BaseFileDir = "D:\content\" & Session("COMPANYID") & "\projects\" & Session("SV_PID") & "\" & selectedFolder & "\"

' if given folder is exists
If fso.FolderExists(BaseFileDir) Then
		Dim i__Name,i__Ext
		Html = Html & VbTab & "<ul class=""jqueryFileTree"" style=""display: none;"">" & VbCrLf
		Set ObjFolder = ObjFSO.GetFolder(BaseFileDir)

		'Iterate THROUGH SUBFOLDER
		For Each ObjSubFolder In ObjFolder.SubFolders
			i__Name=ObjSubFolder.name
			temp = "/" & selectedFolder & "/" & i__Name & "/"
			 Html = Html & VbTab & VbTab & "<li class=""directory collapsed"">" & vbCrLf & VbTab & VbTab & VbTab & "<a href=""#"" rel=""" & temp & """>" & i__Name & "</a>"
			 Html = Html & VbTab & VbTab & "</li>" & VbCrLf
			Set ObjSubFolder = Nothing
		Next
		
		'Iterate THROUGH FILES
		For Each ObjFile In ObjFolder.Files
			' name
			i__Name=ObjFile.name

			' extension
			i__Ext = LCase(Mid(i__Name, InStrRev(i__Name, ".", -1, 1) + 1))
			temp = "/" & selectedFolder & "/" & i__Name
			Html = Html & VbTab & VbTab & "<li class=""file ext_" & i__Ext & """>" & vbCrLf & VbTab & VbTab & VbTab & "<a href=""#"" rel=""" & temp & """>" & i__Name & "</a>" & vbCrLf & VbTab & VbTab & "</li>" & VbCrLf
			Set ObjFile = Nothing
		Next
		Html = Html & VbTab & "</ul>" & VbCrLf
		Set ObjFolder = Nothing
End If
Response.Write Html

Response.End

' http://www.addedbytes.com/blog/code/vbscript-regular-expressions/
Function ereg_replace(strOriginalString, strPattern, strReplacement, varIgnoreCase)
    ' Function replaces pattern with replacement
    ' varIgnoreCase must be TRUE (match is case insensitive) or FALSE (match is case sensitive)
    dim objRegExp : set objRegExp = new RegExp
    with objRegExp
        .Pattern = strPattern
        .IgnoreCase = varIgnoreCase
        .Global = True
    end with
    ereg_replace = objRegExp.replace(strOriginalString, strReplacement)
    set objRegExp = nothing
End function
%>

Open in new window

0
 

Author Comment

by:pborregg
ID: 39292047
Thanks, this is a good start. Problem:

I ran the code and all is well, BUT:           

Response.Write(IsArray(ObjFolder.Files)) = FALSE!!!

This...

For Each ObjFile In ObjFolder.Files

.... some code

Next

Doesn't work...

So why is this not gathering the files that are physically on the server, because I checked and there are indeed two text files in the Parent Dir > Sub Directory

Something is stopping the code from executing.  Could it be my server setting? It's a 1and1.com Dedicated Server 2012 and it's running VBScript and Classic ASP nicely.  with 12 GB of RAM, yeah, it's running like a champ.
0
 
LVL 82

Expert Comment

by:hielo
ID: 39292227
There is a typo on line 18.  Change it to:
Set ObjFolder = fso.GetFolder(BaseFileDir)

Also, immediately before Response.End add the following line:
Set fso = Nothing

Open in new window

0
 

Author Comment

by:pborregg
ID: 39293544
Yeah, I caught that immediately. But still no joy.

I put a Response.Write("hello world") inside the for each loop for the documents and it's NOT even getting in there.
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 82

Expert Comment

by:hielo
ID: 39293931
>>Response.Write(IsArray(ObjFolder.Files)) = FALSE!!!
That is expected.  ObjFolder.Files should be a collection, not an array.  IsArray() returns True for an actual array, not for a collection.  What you can do is check the number of items it contains:
Response.Write ObjFolder.Files.Count

Open in new window


On line 13 add:
Response.Write BaseFileDir & "<br>"

1. What does it print?
2. Does it pass the test of the If ... Then clause in line 15?
3. Does the path in BaseFileDir exist?
4. Is the value of BaseFileDir within your server's Document_Root?
5. You stated that ObjFolder.Files gives you problems.  Is ObjFolder.SubFolders working?
0
 

Author Comment

by:pborregg
ID: 39295269
OK, This is the PRINT out of the Accomplishments directory using the Response.Write BaseFileDir above.  This is a hard-copy direct from the treeview. So this is working 100%

Answer to Question 1:

/content/1/projects/PID585628291
Accomplishments
/content/1/projects/PID585628291/Accomplishments/
John Smith
/content/1/projects/PID585628291/Accomplishments/John%20Smith/
Test
/content/1/projects/PID585628291/Accomplishments/Test/

Answer to Question 2: YES

Answer to Question 3: YES

Answer to Question 4: YES PERFECTLY!

Answer to Question 5: ObjFolder.SubFolders is working 100%

OK, I ran the code with the Response.Write(ObjFolder.File.Count) and it gave this:

0
Accomplishments
0
John Smith
Test
0

Notice, ZERO in every directory except John Smith since John indeed has two files in the directory as I checked the server.

Hope this helps you help me
0
 
LVL 82

Expert Comment

by:hielo
ID: 39295403
>> ZERO in every directory except John Smith...
If I understand you correctly all folders - Accomplishments, John Smith, and Test - have files in them, but only John Smith reports the correct  number of files correct?

If that is the case, then compare the permissions in John Smith against the permissions of the folders that are not working.  My guess is that there is a read permission for one of the user/group entries in John Smith that is missing in the other folders and/or you might be missing a user/group on the non-working folders.
0
 

Author Comment

by:pborregg
ID: 39297349
OK, so what you're telling me is that although the documents are saving to the server, I can't see them due to a permissions problem?  So how do I get around that programatically when I create the new folders?
0
 
LVL 82

Expert Comment

by:hielo
ID: 39297984
If you set the permissions correctly, then newly created items will inherit from the parent folder.  At this point you need to compare the permission of the working vs non-working folders.  Most likely the working folder has a User/Group and/or attribute that the non-working folders are lacking.  Once you identify that, you need to add the missing permission(s) to the parent folder and let the child objects inherit from it.
0
 

Author Comment

by:pborregg
ID: 39298050
OK, thanks, so I need to get on my 1and1 dedicated server and set those perms correctly, right?

But remember, folders are created dynamically through my application.  

I'll get back to you.

Thanks
0
 
LVL 82

Expert Comment

by:hielo
ID: 39298064
>>But remember, folders are created dynamically through my application
Just so you are clear, if you have:
D:\content

and your application is programatically creating:
D:\content\Folder1
D:\content\Folder2
...
D:\content\FolderN

If you set the permissions correctly in D:\content, then Folder1, Folder2,... FolderN would inherit said permissions.  If you are struggling getting the permissions right, your webhost should be able to help you with it.
0
 

Author Comment

by:pborregg
ID: 39298583
I checked and permissions are correct and I created a folder manually and through the app. I checked the perms and sure enough, they were inherited.

I just created a new folder under the second folder that contains the two files and watched the server.

SURPRISE!!!

The server displays the folder correctly and has all the parent perms, BUT!!!!!!! and this is a big BUTT....

When I refresh the treeview, that new folder, say; FolderB, doesn't show either.

AH!!!!! So it's not a perms problem but something in the code.

Here it is from yours modified and tweaked just a wee bit:


----------------------------------------------

<%@LANGUAGE="VBSCRIPT" CODEPAGE="65001"%>
<%
'
' jQuery File Tree ASP (VBS) Connector
' Copyright 2008 Chazzuka
' programmer@chazzuka.com
' http://www.chazzuka.com/
'
' retrive base directory
dim ObjFSO,BaseFile,Html, selectedFolder
dim BaseFileDir
      BaseFileDir = CStr(Request.Form("dir"))

      'Response.Write BaseFileDir & "<br>"

selectedFolder = CStr(Request.Form("dir"))
selectedFolder = Replace( selectedFolder, "../","")
selectedFolder = ereg_replace( selectedFolder, "(^/+|/+$)", "", True )
selectedFolder = Replace( selectedFolder, "/","\")

'Response.Write("DIR:: " & Request.Form("dir")) & vbCrlf

'Response.Write("SELECTED FOLDER:: " & selectedFolder) & vbCrlf


' create FSO
Set ObjFSO = Server.CreateObject("Scripting.FileSystemObject")

' if blank give default value
if len(BaseFileDir) = 0 then
      BaseFileDir = "/content/" & Session("COMPANYID") & "/projects/" & Session("SV_PID") & "/" & selectedFolder
end if

'Response.Write("BASEFILEDIR:: " & BaseFileDir)


' resolve the absolute path
BaseFile = Server.MapPath(BaseFileDir)&"\"

'Response.Write(BaseFile) & VBCRLF

'Replace the C:\..... with D:\
BaseFile = Replace(BaseFile,"C:\inetpub\wwwroot\","D:\")

'Response.Write("BASEFILE:: " & BaseFile) & VBCRLF


' if given folder is exists
if ObjFSO.FolderExists(BaseFile) then
       
         dim ObjFolder,ObjSubFolder,ObjFile,i__Name,i__Ext,temp,i__FileName
       
         Html = Html +  "<ul class=""jqueryFileTree"" style=""display: none;"">" & VBCRLF
       
         Set ObjFolder = ObjFSO.GetFolder(BaseFile)
       ' LOOP THROUGH SUBFOLDER
       
         For Each ObjSubFolder In ObjFolder.SubFolders
               i__Name=ObjSubFolder.name
               Html = Html + "<li class=""directory collapsed""><a href=""#"" onclick=""setFolderName('"+(i__Name)+"');setBaseFileDir('"+(BaseFileDir + i__Name)+"');"" rel=""" + (  Replace(BaseFileDir + "/" + i__Name + "/","//","/")  )+""">" + (i__Name) + "</a></li>" & VBCRLF
                   'Set ObjSubFolder = Nothing

         Next
       
         'Response.Write(ObjFolder.Files.Count)
        
         'LOOP THROUGH FILES
       For Each ObjFile In ObjFolder.Files
                  
               ' name
               i__FileName=ObjFile.name
               ' extension
               i__Ext = LCase(Mid(i__Name, InStrRev(i__FileName, ".", -1, 1) + 1))
                     ' selected folder
                     temp = "/" & selectedFolder & "/" & i__FileName
                    
                     'Response.Write("TEMP:: " & temp)
                    
               Html = Html + "<li class=""file ext_" + i__Ext + """><a href=""#"" onclick=""setFolderName('"+(ObjFolder.Name)+"');"" rel=""" + (temp) + """>" + (i__FileName) + "</a></li>" & VBCRLF
                   Set ObjFile = Nothing


         Next
         Html = Html +  "</ul>"&VBCRLF
         set ObjFolder = nothing
        
end if

Response.Write Html

Response.End

' http://www.addedbytes.com/blog/code/vbscript-regular-expressions/
Function ereg_replace(strOriginalString, strPattern, strReplacement, varIgnoreCase)
    ' Function replaces pattern with replacement
    ' varIgnoreCase must be TRUE (match is case insensitive) or FALSE (match is case sensitive)
    dim objRegExp : set objRegExp = new RegExp
    with objRegExp
        .Pattern = strPattern
        .IgnoreCase = varIgnoreCase
        .Global = True
    end with
    ereg_replace = objRegExp.replace(strOriginalString, strReplacement)
    set objRegExp = nothing
End function

%>
0
 

Assisted Solution

by:pborregg
pborregg earned 0 total points
ID: 39298788
Here's the ANSWER!!!!!!!!!!

BaseFile = Replace(BaseFile,"%20"," ")

The folder JOHN SMITH was being rendered: JOHN%20SMITH

D'OH!!!!!!!!
0
 

Author Closing Comment

by:pborregg
ID: 39306627
Takes a SECOND set of EYES and possibly your WIFE to smack you upside your head to get it. D'OH!
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

I recently decide that I needed a way to make my pages scream on the net.   While searching around how I can accomplish this I stumbled across a great article that stated "minimize the server requests." I got to thinking, hey, I use more than one…
Welcome, welcome!  If you are new to the series and haven't been following along, please take a brief moment to review the first three installments: Part 1 (http://www.experts-exchange.com/Programming/Languages/Visual_Basic/VB_Script/A_266-VBScri…
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…
Access reports are powerful and flexible. Learn how to create a query and then a grouped report using the wizard. Modify the report design after the wizard is done to make it look better. There will be another video to explain how to put the final p…

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now