Ok I shall do a write-a-file version... tomorrow.
Don't forget it should be usable from within VB6.
Printable View
Ok I shall do a write-a-file version... tomorrow.
Don't forget it should be usable from within VB6.
That won't work. You'll HAVE to download Powershell, and run the script on your folder to get true timing. I can do it, and post my findings of the VB6 folder again. That takes about 10 seconds to run, on the new system. When I wrote it, it took about 3 minutes to trundle thru.
Upgraded a few things since then, though. I didn't do the PS script either, other than the basic one I showed. I think it will be an order of magnitude faster than the VB6 version.
Hmm, although running it 10 times in a loop might show the differences better.
Just remember that the original intent was to use this in VB so creating a file outside of VB is not a true test one must call the script from VB and get that data into VB for processing as part of the test as well.
The time should reflect all 3 processes to be accurate.
Yeah, DataMiser, that's what I thought, too. If you do a powershell schript, you'd have to shell to it and wait for it to terminate and have the file written.
I mean, what's the use and comparison elsewhile. If I say, hey, I have to scan for a file in Vb6, the answer: power shell can do it, is not an option, except I can use the power shell result in VB again.
Also a loop of 10 times through will not give accurate results as in a real world senario it will be ran only once, Most of the time will be on the first run after that everything is in memory and runs much faster.
If I do a search on a directory here maybe the first time will take 7 seconds but if I run it again and again and again each time ofter the first may only take 2 seconds or less so if we ran it 10 times we would come up with an average times that is far faster than it would be in actual use.
I was going to run some tests with powershell but it appears I do not have it on any of my machines. I guess referring to it as the new dos is a bit of an exageration seeing as how windows 7 does not install it nor does VS2010.
From what I have saw online it does appear to have a lot more overhead than Dos however.
I have it on Windows 7. It's built into Windows 2008, though. I'm talking about the 2.0 CTP version, at least. It's available for download.
http://www.microsoft.com/technet/scr...introctp2.mspx
I tried a couple of more tests.
The dos Dir method redirected to file took about 2.8 seconds to generate the file from the command line of course by the time we shell to it and then parse the results it would take as long or longer than the tests above done in VB6.
I also ran a test in VB 2005 using the directory.getdirectories() and directory.getfiles() and adding them to an invisible listbox.
time varied a bit 12 seconds to 13.5 seconds.
ETA: sorry the time was actually pretty steady at 12 seconds. The 13.5 was before I hid the listbox.
Tried another .net test that I thought might be faster but turned out to be a couple of seconds slower.
This code steps through each directory in the tree and grabs the filenames from each of them adding the file name to the listbox.
Takes 12 seconds on my test machine
This test grabs all the directories first then grabs all the filenames.Code:Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
ListBox1.Items.Clear()
Dim x As DateTime = Now()
ListBox1.Visible = False
For Each strFolder As String In Directory.GetDirectories("c:\program files", "*.*", SearchOption.AllDirectories)
For Each strFile As String In Directory.GetFiles(strFolder, "*.*", SearchOption.TopDirectoryOnly)
ListBox1.Items.Add(strFile)
Next
Next
ListBox1.Visible = True
MsgBox(DateDiff(DateInterval.Second, x, Now()))
End Sub
Takes 14 seconds on the test machine.
Code:Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
ListBox1.Items.Clear()
Dim x As DateTime = Now()
ListBox1.Visible = False
For Each strFolder As String In Directory.GetDirectories("c:\program files", "*.*", SearchOption.AllDirectories)
ListBox1.Items.Add(strFolder)
Next
For Each strFile As String In Directory.GetFiles("c:\program files", "*.*", SearchOption.AllDirectories)
ListBox1.Items.Add(strFile)
Next
ListBox1.Visible = True
MsgBox(DateDiff(DateInterval.Second, x, Now()))
End Sub
One more test using the VB6 methods in VB2005 result about 7.5 seconds to parse out the same folder on the same machine.
VB.Net tests and VB6 tests all ran in debug mode
And yet another test this time with the VB project posted by WoF compiled to Native code optimized for fast code.
Dir Method pumping out steady in the 3,0xx MS range
API Method steady in the 3,2xx range
What folder? That was my point...
If you read the messages I posted I indicated which folder in at least one of them. All tests were done on the same folder, same machine.
Anyway I fail to see how which folder makes a difference so long as it is the same folder in all tests.
I have to admit that I never compiled the code. I always ran it in the IDE.
I have tried to make all routines nearly equal, either using a recursive call or disposing from the collection within the procedure (no recursive calling).
The FSO procedure is a little different, but is out of range anyway.
I think Dir is the closest to the API call you can get. Also using Dir you don't have to do fancy string picking because it delivers a clean VB string.
An advantage of the API call is, it delivers the file attributes and time stamps in one go.
So there is one thing we could make API go a little faster by not making a GetAttributes() cal, but using the attributes long delivered by the WIN32_FIND_DATA structure.
I was afraid the VB.NET comparisons would be slower for all this wrapping and encapsulating.
To all who are still interested in that topic:
I have worked out another fancy directory scanner which seems to be even faster than API, at least under the testing environment as described before, which was a set of about 47000 files held in 6 different folders.
To use it you have to add a reference to the 'Microsoft Shell Controls and Automation'
This makes available several shell objects like NameSpace and FolderItem, which allow browsing also through Non-FileSystem Objects like Nethood, Network Computers, Desktop, etc.
I have broken this in two small subs.
The first simply finds the shell32.folder object for the given StartingPath, to call the second one.
The second calls itself recursively for every subfolder found during scanning.
I was surprised to find it even faster than the API call. Under the given conditions the fastest API version was 4.7 seconds. This shell version is 3.2 seconds. :)Code:Private Sub ListFilesShell(StartingPath As String)
Dim SHL As New Shell
Dim dsk As Shell32.Folder
Dim fit As Shell32.FolderItem
Set dsk = SHL.NameSpace(ssfDESKTOP)
Set fit = dsk.ParseName(StartingPath)
If Not fit Is Nothing Then
If fit.IsFolder Then ListAllFilesShell fit.GetFolder
End If
End Sub
Private Sub ListAllFilesShell(StartingFolder As Shell32.Folder)
Dim fit As Shell32.FolderItem
For Each fit In StartingFolder.Items
lstFiles.AddItem fit.Name
If fit.IsFolder Then ListAllFilesShell fit.GetFolder
Next
End Sub
Could be this is along the mechanisms PowerShell will also make profit off. It is very close to the explorer's structures. You even can get access to the verbs (right-click-commands) associated with a certain item (file/folder)
I'm not familiar with that object but it looks real good (code size wise) but...and there is always a but... I don't see where it can recurse/explore sub-sub folders. I see where it gets the given folder (GF) and from that it gets the first level of sub folders (SF1) but after that...
On another note, I bet that this could also be converted to a getobject/late binding method on certain OS's so one would not have to include another dependency...
Really nice work WoF
Good observation!
I have found that instead of loading all dirs and then loading all files takes quite long indeed. what I have done ( if you look into the VB.NET FAQ's for a Windows Explorer app ), I have loaded the tree first, then, as soon as the person expands a node, then only load the files only for that folder.
that seems to work the fastest.
i hope you get what I'm trying to say :)
I have not looked into it but windows has the indexing service which allows files to be searched rapidly. There should be objects or apis that take advantage of this service that would search files very quickly assuming one has the service enabled on the system in question. I do not use this service as I seldom have the need to search for files and would rather the search take a little longer rather than use resources for indexing in the background while I am doing other things.
Might be something worth looking into.
Two modules from the Scripting Guys (part of a Backup cmd)
http://gallery.technet.microsoft.com...a-89aaf4927bb9Code:foreach($objDstFile In $colDstFiles)
{
$strDstFile = $objDstFile.Path
$strSrcFile = $strSrcFolder + "\" + $objDstFile.Name
if( -not $FSO.FileExists($strSrcFile))
{
$FSO.DeleteFile($strDstFile)
Write-Host "Deleted file $strDstFile"
$script:iDestDeletedCount++
}
}
DoSubFolders $objSrcFolder $objDstFolder
}
function DoSubFolders
{
param([object] $objSrcFolder, [object] $objDstFolder)
$colSrcSubFolders = $objSrcFolder.SubFolders
foreach($objSrcSubFolder in $colSrcSubFolders)
{
$strSrcSubFolder = $objSrcSubFolder.Path
$strDstSubFolder = $strSrcSubFolder.Replace($strSourceFolder, $strDestinationFolder)
if( -not $FSO.FolderExists($strDstSubFolder))
{
$FSO.CreateFolder($strDstSubFolder)
Write-Host "Created folder $strDstSubFolder"
}
$objDstSubFolder = $FSO.GetFolder($strDstSubFolder)
BackupFolder $objSrcSubFolder $objDstSubFolder
DoSubFolders $objSrcSubFolder $objDstSubFolder
}
}
Using fso uugh, earlier tests showed that was far slower than any other method tried. just over 6x slower than vbs dir or windows api functions
Part of a bigger backup program, that works recursively, with one command.
Those modules are part of it.
Could be useful but my first step would be to get rid of the fso if possible. I use it in VBscript because there is no othe roption and I used it in Embedded VB again because there was no other option. Native VB file routines have much much less overhead and are much much faster.
@vb5prgrmr: You might not have noticed that the second function ListAllFilesShell calls itself with a subfolder item as soon as encounters one. So if the subfolder has other subfolders in it it will again recursively call itself with this subfolders and so on. It will walk through all nested subfolders if there are any, like a good recursion will do. That's what the recursive call is for.
The first part only retrieves the folder object from the starting path.
The shell32 objects Folder and FolderItem allow also to walk non-file-system namespaces.
They provide much more data than the FSO structures.
And what surprised me most is a) the simplicity of code reqired, and b) the execution speed which is even better than API call.
All objects are defined in shell32.dll, so I'm sure a late bound concept could be worked out, also it is better to have the reference in when programming, so as intellisense gives you all the names of the object's properties. This would possibly allow the use in VBScript, too.
Okay, I see it now. Must not have had enough caffine :)
Still really nice work though
Thank you. :)
I got a like of the shell32 objects meanwhile. They are rather flexible and shell32.shell is a fast executing thing with everything concerning folder and folderitems (also files).
Unfortunately I was not able to get CreateObject() produce any of the shell32 objects, so it seems late binding and use in VBScript is out of scope. Except I did something wrong.
Anyway I don't understand it fully:
I can use CreateObject("WScript.Shell") to get a scripting shell.
I get an FSO by using CreateObject("Scripting.FileSystemObject")
both objects are provided by "scrrun.dll"
I can make a Recordset with CreateObject("ADODB.Recordset") anytime. It is from an "msadoxx.dll".
I cannot, however CreateObject("Shell32.FolderItem"). The object is defined in "shell32.dll", but seems not to be registered under this name.
Maybe I only don't know the right name to precede, like ADODB for objects from the msado15.dll...
Making a reference to shell32.dll ('Microsoft Shell Controls and Automation), however, suffices all needs and gives you intellisense and F2 object browser to learn more about the provided objects.
Well I can get this to not fail in creating an object...
But it returns a never ending tree of application and parent references, meaning, if you looked in the locals window you would see...Code:Dim O As Object
Set O = CreateObject("Shell.Application")
So it is pretty much worthless. I also tried with create object...Code:-Application
-Application
-Application
+Application
-Parent
-Parent
-Parent
+Parent
shellfolderitem/view
shell.shellfolderitem/view
shell32.shellfolderitem/view
ishell.shellfolderitem/view
ishell32.shellfolderitem/view
shell.folderitem/view
ishell.folderitem/view
shell32.folderitem/view
ishell32.folderitem/view
/ = (folderitem and folderview)
also shell.parent does not work...
So we are definitly missing something or since it is the shell32.dll and we see it a lot in API's, it may not be fully com compliant...
Just a guess...
Have you tried anything like this...
http://msdn.microsoft.com/en-us/libr...90(VS.85).aspxCode:function fnCreateFolder()
dim oShell
dim oFolder
dim sDir
sDir = "C:\SomePath"
set oShell = CreateObject("shell.Shell_Application")
set oFolder = oShell.NameSpace(sDir)
end function
WoF, I think the miser of data has it in that link... :)
This looks very promising.
Only the statement
set oShell = CreateObject("shell.Shell_Application")
gives an error on my system. It cannot create the object.
Anybody actually tried it?
Now that you mention this problem I gave it a try on vista home and I get an error on that line also. I'm guessing this quote should be more explanatory...
[quote]
You can also instantiate many of the Shell objects with late binding. This approach works in Visual Basic applications and in script. The following example shows how to instantiate the Shell object in JScript.
Which by exclusion means one cannot do it via VB6.0... I guess???
No. I tried it in a vbs script file. Put this into a file texst.vbs
and duble click to run it.Code:dim shl
set shl=CreateObject("shell.Shell_Application")
It shows the same automation error as if you'd use it in VB6.
As for COM compliance, if the objects in shell32.dll were not COM conform, you wouldn't be able to add a reference to the dll and get objects descriptions in the object browser.
That's odd. You would think the info on MSDN would be accurate, maybe it only works under IIS?
Yes.
Saying: ActiveX component cannot create object: 'shell.Shell_Application'
I read all the MSDN article about this and should think it would work...
That's wierd I copied the html code from the MSDN site that shows the usage of several of the shell objects and every one of them generates an error on my system XP Sp3, IE 8. I wonder if it could be related to internet settings?
Well I do know that Shell.Application works...
Code:Dim O As Object
Dim Ds As Object
Dim D As Object
Dim I As Integer
Set O = CreateObject("shell.application")
Set Ds = O.namespace("c:\") 'I wonder if ssfDesktop constant value would work here...
MsgBox Ds.Title
'the above works but below does not... see locals window...
Set D = Ds.self.getfolder("C:\")
Good finding vb5. :) How did you come by that? Is that somewhere in MSDN
In opposite to "shell.Shell_Application" the string "shell.application" works and a shell32 shell object is created.
As soon as you have a shell, the .Namespace method will return a shell32 Folder object, and there we are.
All ready for the late binding scan-all-your-folders-as-fast-as-you-can.
BTW.: The special folder constants are not known automatically when a shell is late bound, but if you know that ssdDesktop is 0 you can as well: Set Ds=O.Namespace(0)
Concerning the Set D = Ds.self.getfolder("C:\") I found this:
The Namespace() method does not return a FolderItem object, but a Folder3 object which has no GetFolder method, so the statement fails.
Instead, this object IS already a Folder structure. It will contain a collection of FolderItems which you can scan like
The GetFolder property is only available on the FolderItem object.Code:For Each fit in DS.Items
If fit.IsFolder then use fit.GetFolder for recursive scanning
Next
No, that is from my earlier post in playing around with the create object if you remember the listing of things I tried that failed and then rereading the other code posted by you to get that far. However, in this thread from another forum, we have more information... http://www.vbforums.com/showthread.php?p=3815897 and from what you implied WoF, we might have a solution but presently I'm getting stuck when passing a variable to be used in the namespace(arguement)...
So I am obviously doing something wrong which I don't see at the moment or something else is up. I don't know??? I'll play around with it some more but some fresh eyes would not hurt either...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(DirToScan) 'this fails but when i hard code "c:\a\" it works???
For Each SingleFolder In FolderCollection.items
If SingleFolder.isfolder Then
'ScanDir SingleFolder.Name 'which means I cannot do this for the recursive call
Debug.Print "Found Folder: " & SingleFolder.Name
Else
Debug.Print "Found File: " & SingleFolder.Name
End If
Next
End Sub
Okay: Have update...
'this works
Set FolderCollection = ShellObject.namespace("C:\") 'works
'these do not...
Set FolderCollection = ShellObject.namespace(PathToSearch)
Set FolderCollection = ShellObject.namespace(StrPtr(PathToSearch))
Set FolderCollection = ShellObject.namespace(VarPtr(PathToSearch))
Set FolderCollection = ShellObject.namespace("""" & PathToSearch & """")
a conundrum for me at the moment...
GUID, maybe?
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...
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...
Okay, the result of this are...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
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!)
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.
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.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
What really worries me is: the Type string and the Details info you get is literally in the local language of your operating system.
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 :)
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.
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!!!)
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?
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.
Using the last code example I gave, it would be changed to...
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...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