Avoid exiting a for/next on error - vb.net

I should know better than to not give enough information/good information when asking for help. I have another question which I need to delete/link or merge here... any comment on how to do that would be great.
So the problem is I am trying to write a simple app (yeah, right) to locate a specific file on the local HDD. There WILL be multiple instances of the file (backups etc.) and I want to find each. Issues are that I cannot know how many local hdd there are and I cannot know what directory the file might be in.
So I wanted to
iterate through all fixed HDD
search the hdd for the file (I always know the name of the file)
I search HDD like this...
For Each drive As IO.DriveInfo In IO.DriveInfo.GetDrives
If drive.DriveType.ToString = "Fixed" Then
So if the found hdd is fixed I do this...
Try
For Each filename As String In IO.Directory.GetFiles(hdd, "user.config", IO.SearchOption.AllDirectories)
The issue is that I throw an exception, I have the for block above in a try catch, the exception is caught and the code exits.
OK, so I guess this is to be expected. Any suggestions on how to avoid this? Meaning I know I will run across files/directories I do not have permission for, how do I carry on and ignore what I don't care about?
FULL CODE LISTING
Private Sub Command1_Click(sender As System.Object, e As System.EventArgs) Handles Command1.Click
'variable to hold each hdd name eg: c:\
Dim hdd As String
Dim directories As Integer = 0
Dim files As Integer = 0
Try
For Each drive As IO.DriveInfo In IO.DriveInfo.GetDrives
If drive.DriveType.ToString = "Fixed" Then
'asign the variable hdd a name for this run through
hdd = drive.Name
'assign label value for directories
directories = directories + 1
Label6.Text = directories.ToString
Me.Refresh()
'search the hdd for the file user.config
Try
For Each filename As String In IO.Directory.GetFiles(hdd, "user.config", IO.SearchOption.AllDirectories)
Me.Refresh()
' 'assign label value for files
files = files + 1
Label2.Text = files.ToString
Me.Refresh()
' 'variable to hold the path for each found file
Dim file As String = IO.Path.GetFullPath(filename)
' 'update file checking label
Label4.Text = file.ToString
' 'add each found file to the list
List1.Items.Add(file)
Next
Catch ex As Exception
End Try
End If
Next
Catch ex As Exception
MsgBox(ex.ToString)
End Try
'iterate through each found drive
End Sub

You need to write it out long-wise because you need to handle the IO security issues. And of course a recursive function.
Called by:
FindFileOnAllDrivesOfType(System.IO.DriveType.Fixed, "test.txt")
Methods:
Public Function FindFileOnAllDrivesOfType(ByVal DriveType As System.IO.DriveType, ByVal FileToFind As String) As List(Of String)
Dim AllLocations As New List(Of String)
For Each drive As IO.DriveInfo In IO.DriveInfo.GetDrives
If drive.DriveType = DriveType Then
AllLocations = FindFile(drive.ToString(), FileToFind)
End If
Next
Return AllLocations
End Function
Public Function FindFile(ByVal StartDirectory As String, ByVal FileToFind As String) As List(Of String)
Dim AllLocations As New List(Of String)
Try
For Each dirname As String In IO.Directory.GetDirectories(StartDirectory)
AllLocations.AddRange(FindFile(dirname, FileToFind))
Next
For Each filename As String In IO.Directory.GetFiles(StartDirectory, FileToFind, IO.SearchOption.TopDirectoryOnly)
AllLocations.Add(filename)
Next
Catch ex As Exception
' MessageBox.Show(ex.Message)
'Do nothing as we can't get a directory listing
End Try
Return AllLocations
End Function

Related

vb.net search directory for files containing *.G(num) but NOT *.GP(num)

I'm fairly familiar with bash, but I'm very, ***very**** new to vb.net. I'm searching for an easy way to find files in a folder that end with .G1, .G2, .G3, etc. but NOT .GP1, .GP2, .GP3, etc. Then for each file I need to copy it to another folder using a different file name but the same extension. I've managed to figure this out for the unique files, but there will be an undefined number of these depending on the project and I need to make sure that I get them all. Hard coding is possible, but very, very ugly. Any suggestions?
Here's the remnants of a failed attempt:
Public Sub FindGFiles()
FileList = IO.Directory.GetFiles(searchDir, ".G[1-99]" + , IO.SearchOption.AllDirectories)
For Each foundfile As String In FileList
If foundfile.Contains(".G#") Then
'copy file somehow and retain file extension
Else
MsgBox("No match")
End If
Next
End Sub
The GetFiles-method does only support * and ? wildcard characters.
So you have to get all files with a *.G*-extension first.
In the For Each-loop one can then use the Like-operator to check the desired pattern:
Public Sub CopyGFiles(searchDir As String, destDir As String)
Dim fileList As String() = IO.Directory.GetFiles(searchDir, "*.G*", IO.SearchOption.AllDirectories)
Dim fileName As String
Dim extension As String
For Each foundfile As String In fileList
fileName = IO.Path.GetFileNameWithoutExtension(foundfile)
extension = IO.Path.GetExtension(foundfile)
If extension Like ".G#" OrElse
extension Like ".G##" Then
'copy file to destination, append "_new" to the filename and retain file extension
IO.File.Copy(foundfile, IO.Path.Combine(destDir, fileName & "_new" & extension))
Else
'pattern not matched
End If
Next
End Sub
The method-call would then be as follows:
CopyGFiles("C:\Temp", "C:\Temp\Dest")
This should be done inside a Try/Catch as different exceptions can occur when working with files.
Try
CopyGFiles("C:\Temp", "C:\Temp\Dest")
Catch ex As Exception
MessageBox.Show("An error occured" + vbCrLf + ex.Message)
End Try

How to check if a file/folder exists in the C drive VB.NET

i'm trying to create a simple anti-cheat which detects external cheats in all the C drive, but i don't know how to check if a determinate file exists in all the C drive, any help?
Here is code that I adapted from How to: Iterate Through a Directory Tree. In the example, the FileExists() function returns True if the file bit32.txt is found anywhere on the C drive. Not all files and directories may be accessible. In that case, the function display the paths of these files and directories. You may want to adapt the code to do whatever you want in these cases.
Imports System.IO
Module Module1
Private Sub Main(ByVal args() As String)
Dim exists As Boolean = FileExists(New DriveInfo("C").RootDirectory, "bit32.txt")
End Sub
Private Function FileExists(ByVal root As DirectoryInfo, ByVal filename As String) As Boolean
Dim files() As FileInfo = Nothing
Dim subDirs() As DirectoryInfo = Nothing
' First, process all the files directly under this folder
Try
files = root.GetFiles("*.*")
Catch e As Exception
' This code just writes out the message and continues to recurse.
' You may decide to do something different here. For example, you
' can try to elevate your privileges and access the file again.
Console.WriteLine(e.Message)
End Try
If (Not (files) Is Nothing) Then
For Each fi As FileInfo In files
' In this example, we only access the existing FileInfo object. If we
' want to open, delete or modify the file, then
' a try-catch block is required here to handle the case
' where the file has been deleted since the call to TraverseTree().
'Console.WriteLine(fi.FullName);
If (fi.Name = filename) Then
Return True
End If
Next
End If
Try
' Now find all the subdirectories under this directory.
subDirs = root.GetDirectories
For Each dirInfo As DirectoryInfo In subDirs
' Resursive call for each subdirectory.
If FileExists(dirInfo, filename) Then
Return True
End If
Next
Catch e As Exception
' This code just writes out the message and continues to recurse.
' You may decide to do something different here. For example, you
' can try to elevate your privileges and access the file again.
Console.WriteLine(e.Message)
End Try
Return False
End Function
End Module
You can have an extension on DirectoryInfo that non-recursively iterates through the root directory looking for files.
<Extension()>
Public Iterator Function GetFilesDepthFirst(ByVal root As DirectoryInfo, ByVal Optional dirPattern As String = "*", ByVal Optional filePattern As String = "*.*") As IEnumerable(Of FileInfo)
Dim stack = New Stack(Of DirectoryInfo)()
stack.Push(root)
While stack.Count > 0
Dim current = stack.Pop()
Dim files = Enumerable.Empty(Of FileInfo)()
Dim dirs = Enumerable.Empty(Of DirectoryInfo)()
Try
dirs = current.EnumerateDirectories(searchPattern:=dirPattern)
files = current.EnumerateFiles(searchPattern:=filePattern)
Catch ex1 As UnauthorizedAccessException
Catch ex2 As PathTooLongException
End Try
For Each file As FileInfo In files
Yield file
Next
For Each dir As DirectoryInfo In dirs
stack.Push(dir)
Next
End While
End Function
You could then call it fairly easily like this:
Dim dInfo = New DirectoryInfo("C:\")
Dim matches = dInfo.GetFilesDepthFirst(filePattern:="somefile.dll")
Dim exists = matches.Any()
Also, the more specific you are at the starting directory, the quicker it will run. Usually searching from the root of C:\ is a very slow and bad idea.

How to check if sub-folder text file exists

I am trying to search if a text file in a sub-folder exists.
This is the code I am using:
'Checks the program's root folder to see if the root folder exists.
Dim FolderName = New DirectoryInfo(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Cake Orders\" & TextBox1.Text))
Dim McKnwoll As String = Path.Combine(FolderName.FullName, Trim(TextBox2.Text) & (" ") & Trim(TextBox3.Text) + ".RTO")
If Not McKnwoll.Exists Then
‘Message to user that file does not exist in sub-folder
Else
‘Message to user that file does exists in sub-folder
End If
I am getting an error that 'Exists' is not a member of 'String'. How can I re-work my code to check if the text file whose name is in the format of "TextBox2.Text & (" ") & TextBox3.Text + ".RTO"; exists.
I am using Visual Basic 2010 Express. Thank you.
File.Exists returns a Boolean indicating whether a file at a certain path exists:
If File.Exists(pathToFile) Then
...
End If
Be sure to include Imports System.IO at the top of your source code file.
You seem quite new in programming. Welcome.
That error message you got ('Exists' is not a member of 'String') tells you exactely what is wrong: You try to ask a string (some text) whether it exists, but what you like to do is to ask a file whether it exists.
The class that provides information about a file is called "FileInfo", and FileInfo has an "Exists" property that you can call:
Dim myFileInfo As New FileInfo(McKnwoll)
If myFileInfo.Exists Then
'do something
End If
That's the object oriented answer, Heinzi's more service oriented one but works, of course, too.
There have been several other small issues I noticed with your code, e.g.
"Cake Orders\" & TextBox1.Text
does not use Path.Combine but makes a string concatenation using fix a "\" as directory separater. Or that the DirectoryInfo is not really used here, the string to the folder is enough.
You also try to handle 3 different issues (reading the values from the user interface, constructing the fullname of the file, checking whether the file exists) in one single code block. I would split them into 3 different ones (actually 4, I would add another one for displaying error messages).
Your simple few lines of codes could be complicated like this ;-)
Imports System.IO
Imports System.Text
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
ReadFileIfPossible(TextBox1.Text, TextBox2.Text, TextBox3.Text)
End Sub
Private Sub ReadFileIfPossible(subfolder As String, part1 As String, part2 As String)
'Get the path to the RTO file
Dim myFilePath As String = Nothing
Try
myFilePath = GetRtoFilePath(subfolder, part1, part2)
Catch ex As Exception
DisplayErrorMessage("Error constructing file name! Please check the values of TextBox1, TextBox2 and TextBox3.")
Return
End Try
'Get the file info
Dim myFile As FileInfo = Nothing
Try
myFile = New FileInfo(myFilePath)
Catch ex As Exception
DisplayErrorMessage(ex.Message)
Return
End Try
'Check whether it exists
Dim myExists As Boolean = False
Try
myExists = myFile.Exists 'it's IO, everything might throw an exception...
Catch ex As Exception
DisplayErrorMessage(ex.Message)
Return
End Try
'Display message if not found
If (Not myExists) Then
DisplayErrorMessage("File ""{0}"" could not be found!", myFilePath)
Return
End If
'Read the file
Dim myLines As String() = Nothing
Try
myLines = File.ReadAllLines(myFile.FullName, New UTF8Encoding(True))
Catch ex As Exception
DisplayErrorMessage(ex.Message)
Return
End Try
'Do something with it...
End Sub
Private Shared Function GetRtoFilePath(subfolder As String, part1 As String, part2 As String) As String
'Check args
If (subfolder Is Nothing) Then Throw New ArgumentNullException("subfolder")
If (part1 Is Nothing) Then Throw New ArgumentNullException("part1")
If (part2 Is Nothing) Then Throw New ArgumentNullException("part2")
'Normalize args
part1 = part1.Trim()
part2 = part2.Trim()
'Build path
Dim myDesktopPath As String = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
Dim myFolderPath As String = Path.Combine(myDesktopPath, "Cake Orders")
myFolderPath = Path.Combine(myFolderPath, subfolder)
Dim myFileName As String = String.Format("{0} {1}.RTO", part1, part2)
Dim myResult As String = Path.Combine(myFolderPath, myFileName)
myResult = Path.GetFullPath(myResult)
'Return result
Return myResult
End Function
Private Sub DisplayErrorMessage(message As String, ParamArray args As Object())
Dim myMsg As String = String.Format(message, CType(args, Object()))
MsgBox(myMsg, MsgBoxStyle.OkOnly, "Error")
End Sub
End Class
Have fun.

ByPassing System Files Permissions VB.Net

I started making a file manager which scans a folder selected by user through folderbrowserdialog in vb.net, extract the extentions of every file in every directory or subdirectory using GetFiles() Method with SearchOption.AllDirectories. I am having an UnauthorizedAccessException when it scans the Recycle Bin Folder in logical drive whereas i have seen Softwares like WinRar or R-Studio Scanning and showing every directory without having an exception or error. Following is my code:
Public Sub WriteExtentionsToFile()
Try
Title_Window.FolderBrowserDialog.ShowDialog()
Dim Path As String = Title_Window.FolderBrowserDialog.SelectedPath
'Getting FilesNames
Dim FileNames As String() = GetFilesNames(Path)
Title_Window.LblStatusBar.Text = "File Names Saved"
Dim MaximumForProgressBar As Integer = FileNames.Length
Title_Window.ToolStripProgressBar1.Maximum = MaximumForProgressBar
Title_Window.ToolStripProgressBar1.Step = 1
'Getting Extentions
Dim ExtentionsList As New List(Of String)
For Each item In FileNames
ExtentionsList.Add(System.IO.Path.GetExtension(item))
Next
'Deleting Duplicate Extentions
Dim NoDuplicateExtentionList As New List(Of String)
Dim ExtentionReadFromFile As String() = ReadExtentionsFromFile()'Another Function in my Class Which Reads previously saved extentions in a file and store them in an array
For Each item In ExtentionReadFromFile
NoDuplicateExtentionList.Add(item)
Next
For Each E In ExtentionsList
Dim LastIndexOfDot As Integer = E.LastIndexOf(".")
E = E.Remove(0, LastIndexOfDot + 1)
If NoDuplicateExtentionList.Contains(E.ToLower) = False Then
NoDuplicateExtentionList.Add(E.ToLower)
My.Computer.FileSystem.WriteAllText("d:\ExtentionsList.txt", E.ToString & vbCrLf, True)
End If
Next
MessageBox.Show("Writing Process Completed", "Success")
Catch ex As UnauthorizedAccessException
Dim Buttons As MessageBoxButtons = MessageBoxButtons.AbortRetryIgnore
Dim result As DialogResult
MessageBox.Show(ex.ToString, "Access Denied", Buttons)
If result = Windows.Forms.DialogResult.Ignore Then
'What should be Done Here????
ElseIf result = Windows.Forms.DialogResult.Abort Then
'What should be Done Here????
Else
'What should be Done Here????
End If
Catch ex As Exception
MessageBox.Show(ex.ToString)
End Try
End Sub
What should be the solution for thsi problem? Is this about getting the permissions through FileIoPermission Class or something else??

Ignore errors when scanning for files in C:

I am trying to search the C:\ drive for all files with a certain extension. I am using the following code which is working fine, however when it encounters an error the whole process stops rather than continuing with the scan. (running in backgroundworker, hence the invoke)
Private Sub ScanFiles(ByVal rootFolder As String, ByVal fileExtension As String)
'Determine if the current folder contains any sub folders
Dim subFolders() As String = System.IO.Directory.GetDirectories(rootFolder)
For Each subFolder As String In subFolders
ScanFiles(subFolder, fileExtension)
Next
For Each file As String In System.IO.Directory.GetFiles(rootFolder, fileExtension)
lb.BeginInvoke(New AddValue(AddressOf AddItems), file)
Next
End Sub
How can I make this code continue once an error is encountered?
If you don't have access to explore C drive itself then you are out of luck. but if you are getting an exception because you don't have access to some child folder in the tree, you can avoid it by putting your code in an try-catch block.
Private Sub ScanFiles(ByVal rootFolder As String, ByVal fileExtension As String)
'Determine if the current folder contains any sub folders '
try
Dim subFolders() As String = System.IO.Directory.GetDirectories(rootFolder)
For Each subFolder As String In subFolders
ScanFiles(subFolder, fileExtension)
Next
For Each file As String In System.IO.Directory.GetFiles(rootFolder, fileExtension)
lb.BeginInvoke(New AddValue(AddressOf AddItems), file)
Next
catch (Ex As UnauthorizedAccessException)
'Ignore Access Errors '
end try
End Sub