Hey, Scripting Guy! For various reasons, we don’t want our users storing “loose” files on their desktop. How can I write a script that will take all the files on the user’s desktop and, based on the file extension, move those files to the appropriate desktop folder? For example, if I have a file with a .doc file extension I’d like to move it to a folder named Doc. If I have a file with a .xls file extension I’d like to move it to a folder named XLS. And so on.
— GA
Hey, GA. You know, this is a great time to be alive, at least for those of us in the Seattle area. For example, on Saturday our very own Washington Huskies – oh, never mind: after leading Ohio State 7-3 at the half, the Huskies fell completely apart in the final two quarters and ended up losing their first game of the year. However, our very own Seattle Seahawks – well, the less said about our very own Seattle Seahawks the better. (And people thought it was impossible to lose to the Arizona Cardinals.) Fortunately, though, we still have our very own Seattle Mariners, who are right in the thick of the baseball pennant race.
Or at least they were, until they lost 17 out of their past 22 games.
Note. On the bright side, the Mariners became the first team in baseball history to be more than 20 games over .500 going into late August and then lose 13 out of 14 games (and, in the process, fall hopelessly out of the race). So at least we got to see history being made. |
Yet another note. Did it help that Scripting Guy Dean Tsaltas, who’s moved back to Halifax, Nova Scotia, sent us a photo this morning, a photo showing Nova Scotians frolicking at the beach over the weekend? Oh, sure, that helped a lot …. |
All right, so maybe this isn’t a great time to be alive. But, then again, there are far more important things in life than sports, right? Not that we can think of any right offhand, mind you – oh, wait: we have one. What about this, what about a script that can move files off the desktop and into folders that correspond to the file extensions?
You know, a script like this one:
Const DESKTOP = &H10&Set objShell = CreateObject(“Shell.Application”)
Set objFolder = objShell.Namespace(DESKTOP) Set objFolderItem = objFolder.Self strPath = objFolderItem.Path
strComputer = “.”
Set objWMIService = GetObject(“winmgmts:\\” & strComputer & “\root\cimv2”)
Set colFiles = objWMIService.ExecQuery _ (“ASSOCIATORS OF {Win32_Directory.Name='” & strpath & “‘} Where ” _ & “ResultClass = CIM_DataFile”)
Set objFSO = CreateObject(“Scripting.FileSystemObject”)
For Each objFile in colFiles strDesktopFolder = strPath & “\” & objFile.Extension If objFSO.FolderExists(strDesktopFolder) Then strTarget = strDesktopFolder & “\” objFSO.MoveFile objFile.Name, strTarget Else Set objFolder = objFSO.CreateFolder(strDesktopFolder) strTarget = strDesktopFolder & “\” objFSO.MoveFile objFile.Name, strTarget End If Next
As you can see, we start things off by defining a constant named DESKTOP and setting the value to &H10&; we’ll need this constant when we make our connection to the user’s desktop folder. And that’s a good point: we should note that this script only moves files stored on the user’s desktop folder (e.g., C:\Documents and Settings\kenmyer\Desktop). As you know, the Windows desktop actually displays items drawn from two locations: the individual user’s desktop folder and the All Users desktop folder (C:\Documents and Settings\All Users\Desktop). What if you want to move files from the All Users desktop folder as well the user’s desktop folder? Well, in that case, the easiest thing to do is to make a duplicate copy of the script, then replace the first line of code with this:
Const ALL_USERS_DESKTOP = &H19&
And, of course, make sure you replace any instances of the constant DESKTOP with the constant ALL_USERS_DESKTOP.
If you don’t care about the All Users desktop, well, then you don’t have to do anything at all.
After defining the constant, we create an instance of the Shell.Application object, then use the following three lines of code to bind to the desktop folder, retrieve the path to that folder, and store the path (e.g., C:\Documents and Settings\kenmyer\Desktop) in a variable named strPath:
Set objFolder = objShell.Namespace(DESKTOP) Set objFolderItem = objFolder.Self strPath = objFolderItem.Path
If you’re familiar with the Shell.Application object you’re probably thinking, “Hmmm, the Shell object is designed to work with the local computer; does that mean this script is designed to work with the local computer?” The answer to that is this: yes, this script is designed to work with the local computer. There are a couple reasons for this, with the big one being the fact that it’s not always easy to identify who’s logged on to a remote machine; in turn, that makes it really hard to determine which folder happens to be that user’s desktop folder. This isn’t necessarily impossible, but it’s a bit tricky, at best. Therefore, we decided to limit this script to working on the local computer only.
Note. So does that mean you’re out of luck when it comes to managing remote computers? Of course not; just run this script as a user logon or logoff script and everything will work just fine. |
After we retrieve the path to the user’s desktop folder, we connect to the WMI service on the local computer. We then use this query to return a collection of all the files found in the desktop folder:
Set colFiles = objWMIService.ExecQuery _ (“ASSOCIATORS OF {Win32_Directory.Name='” & strpath & “‘} Where ” _ & “ResultClass = CIM_DataFile”)
As soon as we have our collection in hand we create an instance of the Scripting.FileSystemObject object (the technology of choice for moving files around). Once that object has been created we’re ready to set up a For Each loop to loop through the collection of files and – tah-dah! – start moving these files to their designated folders.
See? As the saying goes, ‘tis far better to strike a match than curse the darkness.
Although, after this past weekend, it’s probably a good thing that the Scripting Guy who writes this column doesn’t actually have any matches,
In order to move files off the desktop, the first thing we do inside the loop is execute this line of code:
strDesktopFolder = strPath & “\” & objFile.Extension
As you might recall, we want to move all the desktop files into the appropriate folder. What is the appropriate folder? That’s easy: it’s the folder that has the same name as the file extension. (For example, all .doc files need to be moved into a folder named Doc.) What we’re doing with the preceding line of code is taking a peek at the file’s Extension property (which is simply the file extension, minus the period), then using that value to construct a file path similar to this one:
C:\Documents and Settings\kenmyer\Desktop\Doc
As you can see, that’s nothing more than a folder named Doc, located in the user’s desktop folder.
Of course, we can’t move a file into a folder unless that folder exists. (Something to do with the whole space-time continuum, which is yet another thing to Scripting Guy who writes this column is depressed about.) Therefore, our next step is to call the FolderExists method and determine whether or not we already have a Doc folder on the desktop:
If objFSO.FolderExists(strDesktopFolder) Then
Let’s assume that we do. In that case, we’re going to run these two lines of code:
strTarget = strDesktopFolder & “\” objFSO.MoveFile objFile.Name, strTarget
In the first line, we’re simply tacking a \ onto the end of our Doc folder; that’s going to result in the variable strTarget being assigned this value:
C:\Documents and Settings\kenmyer\Desktop\Doc\
Why do we do that? Well, this ensures that our file gets copied into the Doc folder. If we leave the \ off, we’ll get a “File already exists error.” Why? Because, without the trailing slash, the file system object will try to rename our .doc file to the name of the folder (C:\Documents and Settings\kenmyer\Desktop\Doc). Granted, that’s a little weird (and even more irritating), but that’s also the way it works. But, hey, there’s no point in getting upset over a little thing like that; just put a \ at the end of the folder path and everything will work just fine.
Note. Save your disgruntlement for something important. Like football games. |
In line 2, we call the MoveFile method and actually move the file off the desktop and into the designated folder. And then we simply loop around and repeat the process with the next file in the collection.
That’s nice, but what if the folder Doc doesn’t exist? Once again, no problem; in that case we run this block of code instead:
Set objFolder = objFSO.CreateFolder(strDesktopFolder) strTarget = strDesktopFolder & “\” objFSO.MoveFile objFile.Name, strTarget
As you can see, we really only do one thing different here: in the first line we call the CreateFolder method to create the new desktop folder. (Remember? C:\Documents and Settings\kenmyer\Desktop\Doc?) As soon as the folder is created we can assign the folder path (plus the trailing \) the variable strTarget, then call the MoveFile method to move the file into the folder.
And then it’s back to the top of the loop where we repeat the process with the next file in the collection.
We hope that answers your question, GA. And we hope that things are going better for you than they are for the Scripting Guys. But, then again, we have to admit that, other than a few lost football games and baseball games, things are going pretty good for the Scripting Guys. Take the weather, for example. Yesterday it – well, OK, yesterday it rained. And it’s raining today. And it’s supposed to rain again tomorrow. But that’s all right: even in Seattle it can’t rain forever, can it?
Really? We were afraid you were going to say that.
If anyone needs us, we’ll be in the corner of our office.
Feeling sorry for ourselves.
0 comments