VB - cannot copy file due to "being used by another process" error - vb.net

I haven't been able to pinpoint exactly what is causing this error. All im trying to do is copy files (pdfs) that were created on the current day from 1 directory to another after a certain amount of time with the ticker. Here is my code:
Private Sub Timer2_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer2.Tick
Dim file As String
Dim now As String = DateTime.Today.ToShortDateString
Dim dir As String = "C:\PDFs\"
Dim bupdir As String = "C:\PDFs\copied\"
Dim Files() As String = Directory.GetFiles(dir)
For Each file In Files
Dim dt As String = IO.File.GetLastWriteTime(file).ToShortDateString
If dt = now Then
IO.File.Copy(Path.Combine(dir, file), Path.Combine(bupdir, file), True)
End If
Next
End Sub

Your problem lies in the fact that Directory.GetFiles() returns the full path name of the files in the source directory.
Then, when you try to build the destination file name, the Path.Combine sees that your file variable is an absolute path and doesn't add the path bupdir.
This gives back the value of the variable file and you end up with something like this
IO.File.Copy("C:\PDFs\file.pdf", "C:\PDFs\file.pdf", True)
To fix the problem
IO.File.Copy(file, Path.Combine(bupdir, Path.GetFileName(file)), True)
FROM MSDN
If one of the specified paths is a zero-length string, this method
returns the other path. If path2 contains an absolute path, this
method returns path2.

Related

How to fix copied folder name

I have a vb application which copies folders and its subfolder that is working properly. My problem is that it is not copying the correct folder name of the folder being copied.
Like if I copy the folder with this location: C:\Users\Documents\Sample_Folder
The output copied folder name would be "Documents".
C:\Users\Documents\Sample_Folder\Sample_Folder_2
The output copied folder name would be "Sample_Folder".
Private Sub btnCopy_Click(sender As Object, e As EventArgs) Handles btnCopy.Click
Dim SourcePath As String = txtBrowse.Text
Dim DestinationPath As String = "C:\Users\1000258123\Desktop\NEW"
Dim newDirectory As String =
System.IO.Path.Combine(DestinationPath,
Path.GetFileName(Path.GetDirectoryName(SourcePath)))
If Not (Directory.Exists(newDirectory)) Then
Directory.CreateDirectory(newDirectory)
End If
Microsoft.VisualBasic.FileIO.FileSystem.CopyDirectory(SourcePath, newDirectory)
MsgBox("Copy Successful")
End Sub

"Character is not valid" VB.NET

So what this does is copy a report from the resources onto the computer and run it. The code is:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim dir As String = My.Computer.FileSystem.SpecialDirectories.Temp
Dim filename As String = dir + +"Report.exe"
IO.File.WriteAllBytes(filename, My.Resources.Report)
Process.Start(filename)
End Sub
It gives me an error for Process.Start saying
"Character is not valid"
I made another form and wrote the Process.Start part and gave me no errors. I tried removing all the previous code and replacing "filename" in Process.Start with an actual directory but nothing helps. I really need to some help on this, thanks.
What is likely occurring is that the temp folder is returning an invalid character. Instead, try using the IO.Path.GetTempPath method and also build the path by using the IO.Path.Combine method. Here is an example of building the String:
Dim dir As String = IO.Path.GetTempPath
Dim filename As String = IO.Path.Combine(dir, "report.exe")

CopyFile isn't copying my file with the same extension?

I am trying to make it so my user can copy files from one folder to another folder, their playlist folder, so that they can use it throughout my program. So I tried this:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim result As DialogResult = MessageBox.Show("Are you sure you want to finish the playlist?", "Finish Playlist- WikiFinder", MessageBoxButtons.YesNo)
If (result = DialogResult.Yes) Then
For Each Item In ListBox1.Items
Dim str As String = IO.Path.Combine(MusicMenu.FolderBrowserDialog2.SelectedPath, "DONUTS")
My.Computer.FileSystem.CopyFile(Item.ToString(), str)
Next
Else
End If
End Sub
This works and makes the file, but the issue is I told it to copy an MP3 file and it just gave me a "File". Is there any way I can copy the file AND keep the original file's extension?
Since you pass only the directory to the CopyFile function, it creates a FILE.
Pass filename with Extension.
For Each Item In ListBox1.Items
Dim str As String = IO.Path.Combine(MusicMenu.FolderBrowserDialog2.SelectedPath, "DONUTS")
str = IO.Path.Combine(str,IO.Path.GetFileName(Item.ToString()))
My.Computer.FileSystem.CopyFile(Item.ToString(), str)
Next
Now the files will be copied to your DONUTS folder.

Error copying from resources

While copying from resources to a folder under appdata folder: i get an error, but I'm not finding any mistake in code..
Private Sub Help_Load(sender As Object, e As EventArgs) Handles MyBase.Load
File.WriteAllBytes(MainPath & "\Help.rtf", My.Resources.HelpRTF)
Dim HelpRTF = (MainPath & "\Help.rtf")
Helpbox.LoadFile(HelpRTF)
End Sub
HelpRTF is a .rtf file, MainPath is a directory under %appdata% folder
Error: Value of type 'String' cannot be converted to 'Byte()'.
Error at: My.Resources.HelpRTF
The reason why you get that error is because the second parameter of the File.WriteAllBytes() method takes a Byte(), not a String. If you want to write text (String) to a file, you can use the File.WriteAllText() method.
Since RTF's can contain images, text, etc. treating it as text can corrupt it and needless to say, encoding issues might occur. So, instead of using the File.WriteAllText() method, change the FileType of the HelpRTF resource to Binary instead of Text like this:
After that, you can use your code as it was:
Private Sub Help_Load(sender As Object, e As EventArgs) Handles MyBase.Load
File.WriteAllBytes(MainPath & "\Help.rtf", My.Resources.HelpRTF)
Dim HelpRTF = (SWinPath & "\Help.rtf")
Helpbox.LoadFile(HelpRTF)
End Sub
References:
File.WriteAllText - MSDN
File.WriteAllBytes - MSDN

Creating an application that moves a collection files from one place to another using VB

So this is an application I have to create that moves files from one directory to another, both directories being specified by the user. It seems easy enough, but the problem is that there are millions of files that have to be searched through. These files are all named with 8 digits for example, "98938495.crt". The directory where all these files are has multiple folders. These folders within the main one are named with the first two digits of all the files that are in the folder. And then in that folder there are roughly ten zipped folders that contain 100,000 files each. The name of those folders are the minimum and maximum names of the files. For example, I go into the main folder, then click on the "90xx" folder. In that one there are 10 zipped folders which are named with the minimum and maximum names of the files, like "90000000_90099999.zip". That zip folder contains 100000 files. Now, this app is supposed to find all the files that the user inputs and then move them to a folder specified by the user. I have posted my code so far below, any help at all is greatly appreciate!!
FYI: The STID is the name of the file.
GUI for the app
Edit: I realized there is no way to answer this question because there really isn't a question, just a broken app. Basically, how do i search for the items in the directory and then copy them into a new directory?
Imports System
Imports System.IO
Public Class CertFinder
Private Sub SourceDirectoryTB_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SourceDirectoryTB.TextChanged
End Sub
Private Sub DestinationDirectoryTB_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DestinationDirectoryTB.TextChanged
End Sub
Private Sub SearchTB_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SearchTB.TextChanged
End Sub
Private Sub SourceButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SourceButton.Click
Dim fbd As New FolderBrowserDialog
fbd.RootFolder = Environment.SpecialFolder.MyComputer
If fbd.ShowDialog = DialogResult.OK Then
SourceDirectoryTB.Text = fbd.SelectedPath
End If
End Sub
Private Sub DestinationButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DestinationButton.Click
Dim fbd As New FolderBrowserDialog
fbd.RootFolder = Environment.SpecialFolder.MyComputer
If fbd.ShowDialog = DialogResult.OK Then
DestinationDirectoryTB.Text = fbd.SelectedPath
End If
End Sub
Private Sub SearchButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SearchButton.Click
'Array of stids
Dim stidsToFind As String()
'get text in the searchTB textbox
Dim searchTBText As String = Me.SearchTB.Text.Trim()
'splits stids into seperate lines
stidsToFind = searchTBText.Split(vbCrLf)
'gets text from source directory text box
Dim sourceDirectory As String = Me.SourceDirectoryTB.Text.Trim()
'gets text from destination directory text box
Dim destinationDirectory As String = Me.DestinationDirectoryTB.Text.Trim()
Dim fullPathToFile As String = sourceDirectory
'Go through each stid in the search text box and continue if nothing
For Each stidToFind As String In stidsToFind
If String.IsNullOrWhiteSpace(stidToFind) Then
Continue For
End If
'Find the first two digits of the stid
Dim firstTwoDigitsOfSTID As String = stidToFind.Substring(0, 2)
'In the specified directory, find the folder with the first two digits and "xx"
fullPathToFile = fullPathToFile & "\" & firstTwoDigitsOfSTID & "xx"
Dim allFileNames As String() = Nothing
allFileNames = Directory.GetFiles(sourceDirectory, "*.crt*", SearchOption.AllDirectories)
Next
'-------------------------------------------------------------------------------
Try
If File.Exists(fullPathToFile) = False Then
Dim FS As FileStream = File.Create(fullPathToFile)
FS.Close()
End If
File.Move(fullPathToFile, destinationDirectory)
Console.WriteLine("{0} moved to {1}", fullPathToFile, destinationDirectory)
Catch ex As Exception
MessageBox.Show("File does not exist")
End Try
Dim sc As New Shell32.Shell()
'Declare the folder where the files will be extracted
Dim output As Shell32.Folder = sc.NameSpace(destinationDirectory)
'Declare your input zip file as folder .
Dim input As Shell32.Folder = sc.NameSpace(stidsToFind)
'Extract the files from the zip file using the CopyHere command .
output.CopyHere(input.Items, 4)
'-------------------------------------------------------------------------------
' 1. Get the names of each .zip file in the folder.
' 2. Assume that the .zip files are named as such <minimum STID>_<maximum STID>.zip
' 3. For each .zip file name, get the Minimum STID and Maximum STID values.
' 4. Check the range of 'stidToFind' against the STID ranges of each .zip file.
' 5. Once the .zip file is located,
' a. Copy the .zip file to the local computer OR
' b. Just leave it where it is.
' 6. Unzip the file.
' 7. Create the full file name path. ../<stidToFind>.crt
' 8. Copy the file to the destination directory.
' 9. Delete the unzipped folder
' 10. Delete the .zip file (IF you've copied it to your local computer).
End Sub
End Class
In answer to the .ZIP unpacking, use the System.IO.Packaging (more can be found at CodeProject - Zip Files Easy)
Don't you think using a database would be easier to store that data?