How Can I Provide a Visual Indicator When Copying Files?

How Can I Provide a Visual Indicator When Copying Files?

  • Comments 9
  • Likes
Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I provide a visual indicator of some kind when copying a large file or large set of files?

-- SK

SpacerHey, Scripting Guy! AnswerScript Center

Hey, SK. Before we do anything else we should note that the Scripting Guys – or at least the Scripting Guy who writes this column – don’t believe in moral victories. It’s nice that the University of Washington took USC – the No. 3-ranked college football team in the country – right down to the wire on Saturday, coming within 15 yards – and a few seconds – of pulling off the upset. And while it’s encouraging to see the Huskies go toe-to-toe with a team that’s won 49 of its last 51 games, well, a close, hard-fought loss is still just that: a loss. But that’s the way it goes.

Of course, now that we think about it, if we were smart then we would believe in moral victories. After all, in that case we wouldn’t have to write a script that could provide a visual indicator of some kind when copying a large file or large set of files; it would be enough to say that we tried to write a script that could provide a visual indicator of some kind when copying a large file or large set of files. Did we take the garbage out? No, we didn’t. But the important thing is that we tried to take the garbage out; we just couldn’t quite get around to it. Same for getting the oil changed or mowing the lawn. We didn’t exactly do it, but the fact that we even thought about doing it should be considered a moral victory.

But, like we said, Scripting Guys don’t believe in moral victories. With that in mind, here’s a script that displays the Copying dialog box while it copies files from one location to another:

Const FOF_CREATEPROGRESSDLG = &H0&

strTargetFolder = "D:\Scripts" 

Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.NameSpace(strTargetFolder) 

objFolder.CopyHere "C:\Scripts\*.*", FOF_CREATEPROGRESSDLG

As we noted, the Scripting Guys don’t believe in moral victories; we also don’t believe in working particularly hard. Although we could have used a combination of HTML and ActiveX controls to cobble together our own progress bar we took the easy way out: we simply used the Windows Shell object to copy the files. Why is that so easy? Because one of the options offered by the Shell object is to display the Copying dialog box while copying files or folders. Consequently, with a minimal amount of coding and with no need for HTML pages or ActiveX controls, we were able to come up with a file copying script that displays a dialog box similar to this:

Copying Files


Sudden thought. If you try really hard, yet fail, you get credit for a moral victory. So then what do you get when you don’t really try all that hard and yet succeed anyway?

Editor’s Note: That’s what’s called a real victory. Something the Scripting Guys know very little about – they’ve got the “don’t really try all that hard” part down, it’s the rest that tends to be a problem.

Let’s talk about how the script works. We start out by defining a constant named FOF_CREATEPROGRESSDLG and set the value to &H0&; in a minute or two, we’ll use this constant to tell the script that we want to display the Copying dialog box while the files are being copied. We then assign the value D:\Scripts to a variable named strTargetFolder. This is the folder that we want to copy the files to; we won’t specify the folder we want to copy files from until we actually do the copying.

With our constant and variable taken care of the next step is to create an instance of the Shell.Application object. From there, we use this line of code to create an object reference to our target folder (D:\Scripts):

Set objFolder = objShell.NameSpace(strTargetFolder)

Believe it or not, the only thing left to do is copy all the files and folders found in C:\Scripts (that is, C:\Scripts\*.*) to the target folder. (And, of course, display the Copying dialog box as we do so.) That takes just one line of code:

objFolder.CopyHere "C:\Scripts\*.*", FOF_CREATEPROGRESSDLG

As you can see, we simply call the CopyHere method, followed by the file or set of files we want to copy (in this case, C:\Scripts\*.*) and the constant FOF_CREATEPROGRESSDLG. That’s it.

Whoa, whoa, hold on; one question at a time. Let’s start with you in the back. Does the Cancel button in the dialog box actually work? Yes, it does: if you click Cancel the copy operation will terminate. (However, it won’t roll anything back: files that were copied to the target folder before the button was clicked will not be deleted from the target folder.) If you’d prefer to not give people the option of cancelling the operation you have at least two choices:

Leave off the constant FOF_CREATEPROGRESSDLG when calling the CopyHere method. The copy operation will still take place; you just won’t see the Copying dialog box while it takes place.

Take a different approach to copying files, and use a custom progress bar to serve as your visual indicator.

Who’s next? Yes, you in the blue shirt. “Can you use this technique to copy files from your local machine to a remote computer?” Yes, you can; you just need to use a UNC path when specifying the folder on the remote computer. For example, this script takes all the files found in C:\Scripts on the local computer and copies them to C:\Scripts on the remote computer atl-fs-01. Notice that, in this case, we use the administrative share C$ as part of the folder path:

Const FOF_CREATEPROGRESSDLG = &H0&

strTargetFolder = "\\atl-fs-01\C$\scripts" 

Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.NameSpace(strTargetFolder) 

objFolder.CopyHere "C:\Scripts\*.*", FOF_CREATEPROGRESSDLG

We seem to have time for one more. “Can we also flip this around and copy files from a remote machine to the local computer?” Of course you can. Again, the secret there is to use UNC paths. In this sample script we copy only the .VBS files (*.vbs) from atl-fs-01’s shared folder Public to C:\Scripts on the local computer:

Const FOF_CREATEPROGRESSDLG = &H0&

ParentFolder = "c:\scripts" 

Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.NameSpace(ParentFolder) 

objFolder.CopyHere "\\atl-fs-01\public\*.vbs", FOF_CREATEPROGRESSDLG

Sorry, that’s all the time we have for today.

We hope that helps, SK, and we hope the University of Washington gets over its disappointment and gets back on the winning track on Saturday. And now that we check the clock, it looks like we have time for one last question after all. How about the young man in the crimson and silver shirt? What’s that? “How did Washington State University do this weekend?” Washington State University? There must be some mistake; everyone knows there’s only one university of the state of Washington.

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • Thanks a lot.

    It is useful.

    Good job

  • Would this work in Windows 7? The reason I ask is, I was using an XP specific file browser dialog to select files and when I had Windows 7 installed, the file browser dialog broke and I had to find a less intuitive method to select files.

  • Your link to building a custom progress bar is broken.

    It points to http://null/technet/scriptcenter/topics/activex/progressbar.mspx

  • I have a VBScript that uses the CopyHere and it works fine in Windows XP, but not in Windows 7.  Why?

  • It works in Windows 7 also, my error.

  • Works nicely as PowerShell script too...

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

    $FOF_CREATEPROGRESSDLG = "&H0&"

    $objShell = New-Object -ComObject "Shell.Application"

    $objFolder = $objShell.NameSpace($BackUpLocation)

    $objFolder.CopyHere($srcFile, $FOF_CREATEPROGRESSDLG)

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

  • I spent hours trying to create a progress bar via IE.  My original script used an XCopy shell command and while it was running I was attempting to get and update the size of the file I was copying.  BUT, Windows was reporting back the end result size, not the actual size at that moment in time, so a complete fail.

    This solution is awesome as it leveages the system, provides exactly what I need and keeps the coding way down.  THANK YOU!!

  • Does this work with a move operation, would save me heaps of coding.

  • @jgm - Yes, it works just the same with a Move operation: use MoveHere instead of CopyHere.