Commercial: Are those old Dialogs and Files in your cupboard collecting dust? Are you tired of having to take them out, trying to use them, only to spill code all over your beautiful new sweater? Are your kids crying and telling you that you need to move those files to another part of the house so that they can play with their toys in a safe and healthy environment? Well then Martyr2’s Programming Underground Inc. has the solution for you! Move files from those unsightly areas of your file system to new greener pastures with just the use of a dialog and a loop!
Little Toby: “Mr Martyr2, are you just jerking my chain on this?”
Martyr2: No Toby, it is true! With a simple dialog we can select and move those gruesome files from one location to another quickly and easily!
Little Toby: Does that mean Spot and I can live normal lives free of pollution, global warming, and child molesters?
Martyr2: No Toby, but it does mean that you can show your wicked coding skills to your friends and they will think you are swell!
Little Toby: Good enough for me!
Martyr2: With just an FileBrowserDialog and a few functions you can copy files in a breeze using VB.NET… Martyr2 will show you how right here on the Programming Underground!
The goal of our project is going to show off a few different things. One is showing how to list files from a given folder using the Directory object in VB.NET. There have been a few questions regarding this type of behavior lately, so I thought this would be the perfect time to show it off. We will use this mechanism to list some files in our test directory into a listbox. We could make it so that another FileBrowserDialog allows the user to select the folder, but I will leave that up to you guys to explore. Here we will just list all the *.csv or “Comma delimited files” in C:\Test and load them into the listbox for the user then to select.
Just below that we will have a textbox to show the user the destination path of where to copy these files too. We can allow the user to type in a path directly or select a path using the browse button on the right. This button is where we are going to use our FileBrowserDialog to select a quick destination path.
So once the user has selected some files from the listbox and selected a destination path by typing it in or selecting it from the FileBrowserDialog, we can then click the copy button to copy the files from the source directory to the destination directory. Each time a file is copied we will let the user know via a messagebox (for example sake). You wouldn’t want to provide this mechanism if you intended to create your own application for distribution or copying large amounts of files because then the user would be forced to click ok several times.
So below is an image of what the dialog is going to look like…
From this screenshot you can see we have selected two files from our C:\Test directory and we are going to copy them to C:\. Again we are using simple paths here for demonstration purposes. So now lets see how we can do this in VB.NET code.
Public Class Form1 ' First of all lets load up the file listbox with some files from C:\Test that have the .csv extension. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load ' Return an array of file names that match our *.csv pattern. Dim files() As String files = Directory.GetFiles("C:\Test", "*.csv") ' Now we will loop through these files, adding ONLY the filename portion of the file found. ' Directory.GetFiles returns whole paths. Dim file As String For Each file In files lstFiles.Items.Add(Path.GetFileName(file)) Next End Sub ' This sub procedure handles the clicking of our "Browse" button for selecting a path. ' By default we have made it open to our C:\ root drive and gave it a nice description telling the user what to do. Private Sub btnSelectPath_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSelectPath.Click FolderBrowserDialog1.SelectedPath = "C:\" FolderBrowserDialog1.Description = "Select A Destination Folder" ' Show the dialog and if the user chose OK, then the dialog will return a DialogResult of OK ' We can then set our textbox for the Path to the path they selected. If FolderBrowserDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then txtPath.Text = FolderBrowserDialog1.SelectedPath End If End Sub ' Simple button to cancel the application Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCancel.Click Application.Exit() End Sub ' This click event is where a bulk of the work is done. It deterines first if there is a destination path ' specified, that the path then exists, gets the selected files from the listbox and determines if they exist ' then copies only those files found and specified from the multiple selection listbox. Private Sub btnCopy_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCopy.Click If Not String.IsNullOrEmpty(txtPath.Text) Then ' Here we test if the path they chose actually exists. This will return false on drives ' not readable or not accessible (like if you chose a DVD drive for instance). If Directory.Exists(txtPath.Text) Then Dim theSelectedFile As String ' Here is where we loop through the selected items in the listbox. For Each theSelectedFile In lstFiles.SelectedItems ' We need to formulate the full path again to test if it exists and to copy the file. If File.Exists("c:\Test\" & theSelectedFile) Then ' Here we do a simple file.copy call where we specify the file we want and then ' specify the destination where we want to go. We let the user know each file that was ' copied as well. File.Copy("c:\Test\" & theSelectedFile, txtPath.Text & "\" & theSelectedFile) MessageBox.Show("Copied: " & theSelectedFile) End If Next Else MessageBox.Show("Ok, that path doesn't exist or inacccessible, quit trying to trick me!") End If Else MessageBox.Show("Please select a destination path before copying files") End If End Sub End Class
I have put in code comments that help show each step as we go along. The first step we do is in our form load. Here we get an array of file names that match having an extension of CSV using the GetFiles() method of the Directory object. To use this object you must make sure to import the namespace System.IO. This class is a static object which encompasses various methods related to handling directories. As you will see, we will use another function called Exists() later to determine if the path chosen actually exists. Once we get a list of files matching the extension, we simply loop through each one and add only the filename itself to the listbox. GetFiles() actually returns the entire path, filenames and all (eg c:\Test\test.csv). Using the function GetFileName() we take only the filename portion of the path and add that to the listbox.So now we have it loading up file names when the application first starts. Fantastic.
The next part we will want to handle is the browse button. We have added a FileBrowserDialog control (Located under the Dialogs section of the toolbox… if it isn’t there you will have to add it by right clicking the toolbox and selecting “Choose Items..”) to our project. In our browse button’s click event, we configure the FileBrowserDialog control with the path to start out with (Here we use C:\) and a nice description letting the user know what they need to do… select a destination folder. If they press OK, the dialog returns back to the browse button click event where we compare its result it to a dialog result of OK. If these match it means the user is ready to proceed and had hit the ok button. We then set the textbox to the path they selected in the dialog.
Now for the meat and potatoes of this project, the copy button. This button has to run a few checks first before we can get the green light for the file copy.
First it must verify if the destination path has been specified in the txtPath textbox. We then have to make sure this path is one that actually exists and that we are able to access it. Once we verify that the destination is good, we then have to loop through the selected items in the listbox using the selectedItems collection. To make sure this works for you, you have to set the listbox’s selectionmode property to “MultiSimple” or “MultiExtended”. Here we are using “MultiSimple”. This will allow the user to be able to select more than one item to copy.
We loop through the selected items and build the original path (because we had only filenames in the listbox remember?). We then check to make sure that this file and path exists using another object located in the System.IO namespace… the File object. Just like the Directory class, it too is static and contains methods for handling files. If we know the file exists then we can do a file copy using the File object’s copy method. The first parameter to this function is the source file (path and filename) and then the destination (our selected path plus the files name to form paths like C:\test3.csv).
Now during this loop if none of the files have been found to exist, like they were deleted before the copy was being done, then it will never do the copy since it would fail. Otherwise it will go through each name and copy the file one by one. We also put in the little messagebox to let them know a file was copied.
If you follow along with the code and read the comments you will see that all this functionality was done with not that much code at all. What you see in this demo is pretty much the entire application and, besides setting and configuring your controls, it can be a great little utility to help you learn how to use a dialog, the Directory and File objects, and a little bit of “For each” looping.
It would also be easy to port over to a language like a C# console application if you are looking to do it a bit quicker and more streamlined. Feel free to use the code for your own purposes. Just keep in mind that it is a demo and may show a few hiccups when dealing with network drives or drives that are not easily accessible like DVD or CD drives.
I hope you had fun with this little project and learned something from it. Thanks again for reading!
Little Toby: I sure did Mr Martyr2! I am going to run home right now and tell my mom to order three copies! That way I can take one to school and show my friends!
Martyr2: That sounds great Toby. Just let everyone know that it is 19.95 and that we accept all major credit cards, checks and money orders, and even food stamps.
Little Toby: Wow! My mom has tons of food stamps! I am sure she will get me one right away! Thanks!
Martyr2: No thank you Toby and remember, if those nasty files get you down, call 1-800-MAR-TYR2! 😉