Directory Listing using Coldfusion 8 and .NET

On January 17, 2008, in ColdFusion, by Anuj Gakhar

After doing my first example with CF8 and .NET, I got a little excited and wanted to do more with it. I am not really a .NET guy and have very little know-how of how it works. However, I have been trying to do something rather useful with it and I thought it might be a good idea to actually try to mimick the CFDirectory functionality using .NET objects. I have done that previously in Java as well but this time around its .NET .

For those, who are not aware, the mscorlib assembly is always included by default whenever .NET objects are created using Coldfusion. Therefore, we dont need to specify explicitly the “Assembly” attribute in the CFOBJECT or CreateObject call. Because my example uses System.IO.DirectoryInfo which is a part of mscorlib, so I dont need to specify an assembly here.

I will post the UDF here, but would like to highlight parts of it before I do that.

[xml]<cftry>
<cfobject type=".NET" class= "System.IO.DirectoryInfo" name="objIO" action="connect">
<cfobject type=".NET" class= "System.IO.SearchOption" name="objSO" action="connect">
<cfcatch type="any">
<cfobject type=".NET" class= "System.IO.DirectoryInfo" name="objIO" action="create">
<cfobject type=".NET" class= "System.IO.SearchOption" name="objSO" action="create">
</cfcatch>
</cftry>[/xml]

What the above code does is, it tries to connect to an already existing Object of DirectoryInfo and SearchOption and if it fails, it creates a new Object. This is require in order to avoid multiple creations of the same Object. SearchOption object will let us apply the “recurse” functionality to our UDF. It has 2 properties, TopDirectoryOnly and AllDirectories, and based on what we tell it to do, it returns the files accordingly.

Next, based on the argument, to list dir or files, we call either the GetFiles() method or the GetDirectories() method. It really is a matter of browsing the System.IO.DirectoryInfo assembly and looking at the available methods and their returntypes and expected parameters. I wont go into all those details here as that would make the post very long but in my previous post, I did talk about how to browse a .NET assembly.

So, here is the UDF that I wrote, it takes 4 arguments.

Directory – the initial directory to start with
filter – the type of Filter to specify, e.g. *.jpg
recurse – true or false
type – dir or file

[xml]<cffunction name = "DotNetDirectory" returntype="any">
<cfargument name="directory" required="true" type="string">
<cfargument name="filter" required="false" type="string" default="*">
<cfargument name="recurse" required="false" type="boolean" default="false">
<cfargument name="type" required="false" type="string" default="all">
<cfset var responseQuery = queryNew(‘datecreated,datelastaccessed,datelastwritten,
name,size,readonly,pathname,directory’) />
<!— try to connect to the .NET object as it might already exist, otherwise create it—><cftry> <cfobject type=".NET" class= "System.IO.DirectoryInfo" name="objIO" action="connect">
<cfobject type=".NET" class= "System.IO.SearchOption" name="objSO" action="connect">
<cfcatch type="any">
<cfobject type=".NET" class= "System.IO.DirectoryInfo" name="objIO" action="create">
<cfobject type=".NET" class= "System.IO.SearchOption" name="objSO" action="create">
</cfcatch>
</cftry>

<!— load the directory specified to the DirectoryInfo Object—>
<cfset myDir = objIO.init(arguments.directory) /><!— make sure the sepcified directory exists, otherwise throw an error—>
<cfif myDir.get_Exists() >

<!— if recurse is true, tell .NET to list all directories recursively
else list the TopDirectory Only—>
<cfif arguments.recurse>
<cfset directoryDepth = objSO.AllDirectories />
<cfelse>
<cfset directoryDepth = objSO.TopDirectoryOnly />
</cfif> <!— if type is file then do GetFiles(), else do GetDirectories()—>
<cfif arguments.type EQ ‘file’>
<!— GetFiles() takes 2 parameters, searchPatterna and SearchOption Object—>
<cfset listFiles = myDir.GetFiles(arguments.filter , directoryDepth ) />
<cfloop from="1" to="#arraylen(listFiles)#" index="thisFile">
<cfset queryAddRow(responseQuery) />
<cfset querySetCell(responseQuery,"datecreated", listFiles[thisFile].Get_CreationTime() )>
<cfset querySetCell(responseQuery,"datelastaccessed", listFiles[thisFile].Get_LastAccessTime() )>
<cfset querySetCell(responseQuery,"datelastwritten", listFiles[thisFile].Get_LastWriteTime() )>
<cfset querySetCell(responseQuery,"name", listFiles[thisFile].Get_Name() )>
<cfset querySetCell(responseQuery,"size", listFiles[thisFile].Get_Length() )>
<cfset querySetCell(responseQuery,"pathname", listFiles[thisFile].Get_FullName() )>
<cfset querySetCell(responseQuery,"directory", listFiles[thisFile].Get_DirectoryName() )>
<cfset querySetCell(responseQuery,"readonly", listFiles[thisFile].Get_IsReadOnly() )>
</cfloop>
</cfif>

<!— if list directories —> <cfif arguments.type EQ ‘dir’>

<cfset listDirs = myDir.GetDirectories(arguments.filter , directoryDepth ) />
<cfloop from="1" to="#arraylen(listDirs)#" index="thisDir">
<cfset queryAddRow(responseQuery) />
<cfset querySetCell(responseQuery,"datecreated", listDirs[thisDir].Get_CreationTime() )>
<cfset querySetCell(responseQuery,"datelastaccessed", listDirs[thisDir].Get_LastAccessTime() )>
<cfset querySetCell(responseQuery,"datelastwritten", listDirs[thisDir].Get_LastWriteTime() )>
<cfset querySetCell(responseQuery,"name", listDirs[thisDir].Get_Name() )>
<cfset querySetCell(responseQuery,"size", "")>
<cfset querySetCell(responseQuery,"pathname", listDirs[thisDir].Get_FullName() )>
<cfset querySetCell(responseQuery,"directory",listDirs[thisDir].Get_Name() )>
<cfset querySetCell(responseQuery,"readonly", "" )>
</cfloop>
</cfif>
<cfelse>
<cfreturn "#arguments.directory# does not exist" /> </cfif>
<cfreturn responseQuery />
</cffunction>[/xml]

And here is an example of how to use it.

[xml]<cfscript>
stargs = structNew();
stargs.directory = "C:\ColdFusion8\wwwroot\cfide";
stargs.recurse = "yes";
stargs.filter = "*.*";
stargs.type = "dir";
dir = DotNetDirectory(argumentCollection = stargs);
</cfscript>
<cfdump var = "#dir#">[/xml]

I havent seen a lot of Coldfusion8 and .NET examples out there and given the fact that I am a novice at .NET, this code might not be the best code, but if anyone has suggestions, please give me a shout.

Tagged with:  

One Response to Directory Listing using Coldfusion 8 and .NET

  1. Paul Baylis says:

    Hi Anuj,

    Thanks for this. I’m using it for a new project.
    Our directories need authentication before access is granted. Is there a way to impersonate a user so that access can be granted to the directory structure?

    Thanks,

    Paul Baylis
    Senior Web Applications Developer, ZeroOne Ltd
    http://www.zeroone.co.nz

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

© 2011 Anuj Gakhar
%d bloggers like this: