Maintaining an efficient list of excluded directories - vb.net

I am writing a program which iterates over "every" file on a computer. It excludes certain directories from its search such as the recycle bin and temporary and windows system files. There is a subroutine to search the root of each drive for files and then recursively search each sub-directory for files. There is a SortedSet(Of String) of excluded directories (for quick look-ups), when the search matches an excluded directory it skips it and removes it from the exclusion list to reduce the number of comparisons.
There is a subroutine which is used to add new directories to the exclusion set. The subroutine's function is to only add directories which are not sub-directories of other directories already contained in the set and to remove any directories already contained in the set if they are sub-directories of the directory to be added.
Below is my solution to the problem. The exact locations of the excluded directories cannot be known in advance, is there a more concise and/or efficient algorithm that could be used for this purpose?
Sub ExcludeDirectory(directoryPath As String)
'For simple case-insensitive comparison all paths are converted to lower-case prior to comparison.
directoryPath = directoryPath.ToLower
'Append the final '\' to the candidate if it is missing. This avoids issues with directories not being added to the exclusion list due to sharing an already listed directories path as a prefix but not actually being a subdirectory of that listed directory.
'For Example: C:\Program Files Compare To: C:\Program Files\
' C:\Program Files (x86) C:\Program Files (x86)\
If Not directoryPath.EndsWith("\") Then directoryPath &= "\"
'Do loop chosen since items in the exclusion list will be removed if they are subdirectories of the candidate directory.
Dim i As Integer = 0
Do Until i = ExcludedDirectories.Count
'Multiple listed directories may be subdirectories of candidate but the reverse is not the case so evaluating the first case is done first.
If ExcludedDirectories(i).StartsWith(directoryPath) Then
'If any listed directory is a subdirectory of the candidate then remove it. Do not increment 'i' because the next directory will be located at the same index.
ExcludedDirectories.Remove(ExcludedDirectories(i))
ElseIf directoryPath.StartsWith(ExcludedDirectories(i)) Then
'If the candidate is a subdirectory of any listed directory then it will not be added and does not need comparison to any other directories.
Exit Sub
Else
i += 1
End If
Loop
'Add candidate directory.
ExcludedDirectories.Add(directoryPath)
End Sub

Related

Showing the File Extensions inside the folder

Currently, I am working on a feature that will make the files inside the folder that will not hide the file extensions using this code.
Imports Microsoft.Win32
Sub SetNoDrives(value As Integer, path as string)
Dim RegPath As String = "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced]"
Using Key As RegistryKey = Registry.LocalMachine.OpenSubKey(RegPath)
Key.SetValue("HideFileExt", value, RegistryValueKind.DWord)
End Using
End Sub
the problem is, I don't know where to place the string path (folder path) on the code. the path is the specific location where you will always show the file extensions of the files inside the folder.
Any help will be much appreciated.
The reason you don't know where to put the folder path is because there is nowhere to put the folder path. This is a user-wide option, i.e. either extensions are displayed in every folder or no folder for the current user. You don't get to choose on a folder by folder basis. At least, there is no option in Windows/File Explorer to do that and I've never seen mention of it being possible, even when specifically searching for it.

Deleting Files in Subfolder and delete empty Folders

I have to write a PlugIn (in VB.NET) that deletes files after a set amount of days. I've been using this Code to "delete" all files older then DataAge:
For testing purposes I use Log(file.Name) instead of file.Delete().
Dim directory As New IO.DirectoryInfo(.PluginXML.DeleteDirectory) //.PluginXML.DeleteDirectory = FilePath
For Each file As IO.FileInfo In directory.GetFiles()
If (Now - file.CreationTime).Days > .PluginXML.DataAge Then Log(file.Name) //.PluginXML.DataAge = FileAge
Next
How do I check for old files/empty folders in Subfolders from .PluginXML.DeleteDirectory?
I tried something like this, but it would delete the folders, instead of old files.
For Each folder As IO.DirectoryInfo In directory.GetDirectories()
If (Now - folder.CreationTime).Days > .PluginXML.DataAge Then Log(folder.FullName)
Next
One option is to use the overload of GetFiles (or even better*, EnumerateFiles) that accepts a SearchOption with which you can specify that it recurses all directories. For example:
For Each file As FileInfo In directory.EnumerateFiles("*.*", SearchOption.AllDirectories)
If (Now - file.CreationTime).Days > .PluginXML.DataAge Then Log(file.Name)
Next
The alternative is to create a recursive function that walks the directory tree using EnumerateDirectories:
Public Sub ProcessDirectory(directory as DirectoryInfo, dataAge as Integer)
For Each file As FileInfo In directory.EnumerateFiles()
If (Now - file.CreationTime).Days > dataAge Then Log(file.Name)
Next
For Each subDir as DirectoryInfo In directory.EnumerateDirectories()
ProcessDirectory(subDir, dataAge)
Next
End Sub
And then call the method using your base/root path
Dim rootDir As New DirectoryInfo(.PluginXML.DeleteDirectory)
ProcessDirectory(rootDir, .PluginXML.DataAge)
Though note that you will probably need to add error handling for when a directory is inaccessible, such as when an UnauthorizedAccessException or SecurityException is thrown.
* GetFiles loads all files into memory at once whereas EnumerateFiles returns an IEnumerable<FileInfo> that streams the results. This has benefits if you are dealing with directories that contain lots of files, especially if using the AllDirectories option.

Delete directory on network shared folder

This question is bring from another forum which not having answer yet for my situation.
I have something to do on network shared folder. But when I search on Internet, it giving me a code to do in own computer only. Step that I want to do is:
Check destination (network shared folder) path is empty or not.
Delete folder content (not the main one) eg: "\USER-PC\File\"; the folder "File" no need to deleted, but the content inside is need to deleted.
Copy folder content from source to new destination.
No. 1 and 3 is OK. But No. 2 is not yet found. How to delete a content from directory on Network Shared Folder?
Delete directory code that I use but exception "Could not complete operation since directory is a root directory":
My.Computer.FileSystem.DeleteDirectory(strDestination, FileIO.DeleteDirectoryOption.DeleteAllContents)
Please assist
EDITED:
To delete all files inside the main directory:-
Dim directory As New DirectoryInfo(strDestination)
For Each file As FileInfo In directory.GetFiles()
file.Delete()
Next file
To delete all folders inside the main directory:-
For Each folder As DirectoryInfo In directory.GetDirectories()
folder.Delete(True)
Next folder
Use this instead (it's C#, you'll need to convert it to VB.NET):
DirectoryInfo directory = new DirectoryInfo("\\USER-PC\File");
foreach(FileInfo file in directory.GetFiles()) {
file.Delete();
}

Find a Directory somewhere in Subdirectories

I want to find a directory somewhere among a lot of subdirectories using VB.NET. I have the path of the parent directory (D:\) and I have the name of the subdirectory (X) and I want to find this directory in any of the subdirectories of D:\. In D:\ I have 3 subdirectories (A, B, and C) and I want to find X (the name of the directory) inside A,BorC`. Is it possible to do that with VB.NET?
You can do so using the Directory.EnumerateDirectories method, like this:
For Each i As String In Directory.EnumerateDirectories("D:\", "X", SearchOption.AllDirectories)
Console.WriteLine("Matching Directory: " & i)
Next
Please note that there may be multiple matches. Also, be aware that if the directory tree is very large, it may take a long time for the method to find all of the matches. The key to that working for you is the SearchOption.AllDirectories option. By passing AllDirectories, that causes the method to search the entire directory tree below "D:\". If you omitted that parameter, or passed TopDirectoryOnly, it would only look at the directories that are directly children of "D:\". It would not search through all of the descendants.
If you just want to get an array of all the matching directories, you can alternatively use the Directory.GetDirectories method:
Dim matches() As String = Directory.GetDirectories("D:\", "X", SearchOption.AllDirectories)
If matches.Length > 0 Then
Console.WriteLine("First match: " & matches(0))
End If
The advantage of the EnumerateDirectories method, though, is that, if you only care about the first match, you can exit the loop after processing the first match and skip searching the rest of the directory tree. From the MSDN article:
The EnumerateDirectories and GetDirectories methods differ as follows: When you use EnumerateDirectories, you can start enumerating the collection of names before the whole collection is returned; when you use GetDirectories, you must wait for the whole array of names to be returned before you can access the array. Therefore, when you are working with many files and directories, EnumerateDirectories can be more efficient.
For instance, if you really only cared about the first match, it would be more efficient to do this:
For Each i As String In Directory.EnumerateDirectories("D:\", "X", SearchOption.AllDirectories)
Console.WriteLine("First match: " & i)
Exit For
Next
Or with LINQ:
Dim firstMatch As String = Directory.EnumerateDirectories("D:\", "X", SearchOption.AllDirectories).FirstOrDefault()
If firstMatch IsNot Nothing Then
Console.WriteLine(firstMatch)
End If
Please check the below link
http://msdn.microsoft.com/en-us/library/6ff71z1w%28v=vs.110%29.aspx?cs-save-lang=1&cs-lang=vb#code-snippet-1
it will help you in getting all the directories in the specified path. Regarding the second argument that is the "pattern" try and check pattern as "" and hopefully should return and array of all directories and subdirectories
Then you can just compare/search for the file name in the returned array list using simple for loop and display the result which will show where the file is located

Drag Drop and Verify in Visual Basic (VS 2012 V11)

I have a program with two text boxes. One is for a file path the other for a folder path (directory). Right now, my drag and drop feature properly allows only files paths in one text box and folder paths (directories) in the other.
However, I'm not certain if my verification method is proper.
Here are the two parts of the code that verify if file or directory:
If e.Data.GetDataPresent(DataFormats.FileDrop) Then
Dim filePathDragDrop() As String = CType(e.Data.GetData(DataFormats.FileDrop), String())
For Each pathTemp In filePathDragDrop
' This checks if it is a file
If File.GetAttributes(pathTemp) = FileAttributes.Archive Then
TextBoxCopyFrom.Text = pathTemp
End If
Next
End If
And for checking for directory a similar set up as above only this is different
' Checks for directory
If File.GetAttributes(pathTemp) = FileAttributes.Directory Then
TextBoxCopyTo.Text = pathTemp
End If
Is this the proper way to check if the file being dropped is indeed a file,
and if the folder (directory) being dropped is indeed a folder (directory)?
Is there any item that could be dropped that would be incorrectly verified?
I am assuming the archive part of "FileAttributes.Archive" pertains to file data.
No, that's not correct. The Archive attribute doesn't have to be turned on. It will be turned off when the user has used a backup program and the file hasn't changed since it was backed-up. Not actually sure if backup programs still work that way these days, but you can't make any assumptions.
The test for a directory is not correct. You'll need to test it like this:
If (File.GetAttributes(pathTemp) And FileAttributes.Directory) = FileAttributes.Directory Then
'' It's a directory
Else
'' It's a file
End If