File Explorer is a simple, fast, and user‑friendly file management application designed to make navigating, organizing, and manipulating files intuitive for all users. It combines a clean graphical interface with a powerful built‑in Command Line Interface (CLI) for those who prefer keyboard‑driven workflows.
The application is built around clarity, predictability, and emotional safety. Whether you prefer clicking, typing, or shortcut‑driven workflows, File Explorer adapts to your style.
• Browse directories using a tree view and list view.
• Perform file operations such as copy, move, delete, and rename.
• Use cut, copy, and paste for file and folder management.
• Access context menus for quick actions.
• Navigate backward and forward through history.
• View file type icons and real‑time status updates.
• Open the Help Drawer, a panel with beginner‑friendly documentation.
• Fast directory navigation (cd).
• File operations (copy, move, delete, rename).
• Create text files (text, txt).
• Search and cycle results (find, findnext).
• Type a path to open it directly.
• Supports quoted paths with spaces.
• Helpful usage messages and error feedback.
• Built‑in help system with full documentation in the Help Drawer.
The GUI and CLI work together seamlessly, giving users the freedom to choose the workflow that suits them best.
I set out to build my own File Explorer because I wanted to understand, from the ground up, how a core part of every operating system actually works. We all use file managers every day, but it’s easy to overlook how much is happening behind the scenes: navigation history, sorting, file type detection, context menus, clipboard operations, lazy loading of folder trees, and many other details. Recreating these features myself has been a practical way to explore system I/O, UI design, event handling, and performance considerations in a hands-on, exploratory way.
This project is not meant to replace the built-in Windows Explorer. Instead, it serves as a learning environment, a place where I can experiment, break things, fix them, and understand why they work the way they do. By rebuilding something familiar, I get to uncover the subtle engineering decisions that make everyday tools feel intuitive, similar to how art students copy the masters to study technique and intention.
This project is designed for anyone who wants to understand how real applications work, from beginners taking their first steps, to experienced developers exploring deeper architectural ideas. My hope is that you come away with:
By looking at the code behind navigation, file operations, and directory structures, you can see how your operating system performs these tasks under the hood.
The project demonstrates UI layout, event‑driven programming, keyboard shortcuts, tooltips, context menus, and the small design decisions that make an interface feel intuitive and predictable.
You’ll find subsystems for navigation history, sorting logic, search functionality, and file-type mapping-all working together in a cohesive, maintainable way.
Everything is open-source under the MIT License, so you’re free to explore, customize, or reuse any part of the codebase in your own applications.
Re-creating something familiar is one of the most effective ways to deepen your understanding. Much like how art students copy the masters to study technique, rebuilding a tool like File Explorer reveals the subtle decisions and hidden complexity behind everyday software.
One of the core ideas behind this project is the value of deliberate practice, breaking a complex system into understandable pieces, studying them closely, and rebuilding them with intention. File Explorer is a perfect playground for that kind of learning. It’s small enough to grasp, but rich enough to teach real engineering habits: decomposition, naming, event flow, UI state management, and the discipline of making things predictable for users. My hope is that this project becomes a starting point for students who want to build their own great applications. By exploring the code, modifying features, or adding entirely new ones, learners can practice the same skills professional developers use every day. This isn’t just a tool to look at, it’s a foundation you can extend, reshape, and eventually outgrow as you build projects of your own.
If you’re curious, the GitHub repository includes the full source code and documentation. I’d love to hear your thoughts, suggestions, or ideas for future features. This project is as much about learning as it is about building something functional, and I’m excited to share that journey with you.
The Command Line Interface (CLI) is an integrated text‑based command system inside the File Explorer application. It allows users to navigate folders, manage files, and perform common operations quickly using typed commands.
The CLI is designed to be:
- Fast - no menus, no dialogs
- Predictable - clear rules and consistent behavior
- Beginner‑friendly - helpful messages and examples
- Powerful - supports navigation, search, file operations, and more
- Change directories
- Open files directly
- Navigate to folders by typing their path
- Supports paths with spaces using quotes
- Create, copy, move, rename, and delete
- Works with both files and directories
- Handles quoted paths safely
- Search the current folder
- Cycle through results with
findnext - Highlights and selects results in the UI
If a command doesn’t match a known keyword, the CLI checks:
- Is it a folder? → Navigate to it
- Is it a file? → Open it
- Otherwise → “Unknown command”
This makes the CLI feel natural and forgiving.
cdcopy cpdelete rmdfdrivesexit quit closefind searchfindnext searchnext nexthelp commands ?man manual appmanualmkdir make mdmove mvopenpinrename rnshortcuts keystext txt
Below is the complete list of supported commands, including syntax, descriptions, and examples.
Usage
mkdir [directory_path]
Description
Create a new folder at the specified path.
Examples
mkdir C:\newfolder
make "C:\My New Folder"
md C:\anotherfolder
Usage
pin [folder_path]
Description
Pin or unpin a folder.
If no path is provided, the current folder is used when valid.
Examples
pin C:\Projects
pin "C:\My Documents"
pin
Usage
copy [source] [destination]
Description
Copy a file or folder to the specified destination.
Examples
copy C:\folderA\file.doc C:\folderB
copy "C:\folder A" "C:\folder B"
Usage
move [source] [destination]
Description
Move a file or folder to a new location.
Examples
move C:\folderA\file.doc C:\folderB\file.doc
move "C:\folder A\file.doc" "C:\folder B\renamed.doc"
Usage
rename [source_path] [new_name]
Description
Rename a file or folder.
Examples
rename "C:\folder\oldname.txt" "newname.txt"
Usage
delete [file_or_directory]
Description
Delete the specified file or folder.
Examples
delete C:\file.txt
delete "C:\My Folder"
Usage
find [search_term]
Description
Search the current directory for items whose names contain the given term.
Examples
find document
Usage
findnext
Description
Show the next result from the previous search.
Usage
cd [directory]
Description
Change the current working directory.
Examples
cd C:\
cd "C:\My Folder"
Usage
open [file_or_directory]
Description
Open a file or navigate into a folder.
Examples
open C:\folder\file.txt
open "C:\My Folder"
Usage
text [file_path]
Description
Create a new text file at the specified path.
Examples
text "C:\folder\example.txt"
Usage
df <drive_letter>:
Description
Display free and total space for the specified drive.
Examples
df C:
df D:
df E:
Usage
drives
Description
Show all available drives along with their free‑space information.
Examples
drives
Usage
help [search_term]
Description
Show the full list of commands or display help for a specific command.
Examples
help
help cd
help copy
Usage
man [section]
Description
Show the full application manual or jump to a specific section.
Examples
man
man help
man commands
manual
appmanual
Usage
shortcuts
Description
Show all available keyboard shortcuts.
Examples
shortcuts
keys
Usage
exit
Description
Close the application.
Paths containing spaces must be enclosed in quotes:
"C:\My Folder"
"C:\Users\Joe\My File.txt"
This applies to:
cdcopymoverenamedeletetext
The CLI will warn the user when quotes are required.
If the user enters something that is not a command:
- If it’s a folder path, the CLI navigates to it
- If it’s a file path, the CLI opens it
- Otherwise, the CLI shows an “Unknown command” message
This makes the CLI feel natural and forgiving.
> cd C:\Users\Joe
Navigated To: C:\Users\Joe
> copy "C:\Users\Joe\file.txt" "C:\Users\Joe\Documents"
Copied file: file.txt to: C:\Users\Joe\Documents
> find report
Found 3 result(s). Showing result 1. Type findnext to move to the next match.
> findnext
Showing result 2 of 3
> help
(Displays full help text)
The File Explorer CLI provides:
- Fast directory navigation
- Powerful file operations
- Search with result cycling
- Intelligent path handling
- Clear feedback and usage messages
- Beginner‑friendly quoting rules
- Contextual file/folder opening
It’s a flexible, efficient alternative to the graphical interface - perfect for users who enjoy command‑driven workflows.
This application is built as a set of small, focused systems that work together.
In this walkthrough, we go line by line through the core systems that make up the app and see how each one is implemented in code.
- Directory & File Navigation System
- Command Line Interface (CLI) System
- Help & Manual System
- Keyboard Input & Routing System
- File Operation System
- Search System
- GUI Rendering System
- Pinning System
- State Management System
- Exit & Safety System
This system is responsible for where you are and what you see.
- Tracks the current directory and updates the UI when it changes
- Keeps the tree view and list view in sync
- Manages history (Back/Forward) and selection state
- Resolves paths (absolute, relative, quoted)
In the code walkthrough, we look at:
- How the current path is stored
- How directory changes trigger UI refreshes
- How selection is read and used by commands like
open,delete, andrename
This system turns user input into actions.
- Parses commands and arguments
- Resolves aliases using the
CommandHelpdictionary - Handles quoted paths and spacing rules
- Routes each command to the correct handler method
- Shows usage and error messages when something isn’t valid
In the walkthrough, we go through:
- The main input handler
- How the command name is matched against
CommandHelp - How arguments are split, validated, and passed to operations
This system makes the app self‑documenting.
CommandHelpdictionary with aliases, usage, descriptions, and exampleshelpcommand for command‑level helpmancommand for full manual sections- Rendering logic for help text and manual pages
- Search and fallback behavior when an exact match isn’t found
In the walkthrough, we examine:
- How
CommandHelpis built - How
BuildHelpTextconstructs the help output - How
helpandmandecide what to show
This system decides what a key press means in each context.
- Handles Enter, Escape, Tab, Shift+Tab, and shortcuts
- Routes keys differently depending on focus (CLI, list view, Help Drawer)
- Suppresses unsafe repeats and protects modal states
- Keeps behavior predictable and consistent
In the walkthrough, we look at:
- The central key handler
- How context is detected (which control is active)
- How routing tables or
Select Caseblocks map keys to actions
This system performs the actual work on the filesystem.
- Create:
mkdir,text - Copy:
copy - Move:
move - Delete:
delete - Rename:
rename - Open:
open - Pin/Unpin:
pin - Disk info:
df,drives
In the walkthrough, we step through:
- How each command validates paths
- How errors are handled and surfaced to the user
- How the UI is refreshed after an operation completes
This system finds items in the current directory.
findto start a searchfindnextto move through results- Stores the current result list and index
- Automatically selects the first match
- Wraps around when reaching the end
In the walkthrough, we cover:
- How the search term is applied to items
- How results are stored and reused
- How selection is updated as you cycle through matches
This system draws what the user sees.
- Tree view and list view population
- Status bar updates (current path, selection, search results)
- Icons and visual indicators
- Help Drawer layout and content
- Context menus and their actions
In the walkthrough, we look at:
- How the UI is initialized
- How data binding or manual population works
- How the GUI reacts to changes from the CLI
The pinning system manages the set of folders the user has marked for quick access. It provides a simple toggle‑based workflow and keeps both the internal state and the user interface consistent.
This system is responsible for:
- Tracking which folders are currently pinned
- Implementing the toggle behavior for the
pincommand - Validating paths before pinning or unpinning
- Updating any UI elements that display pinned folders
- Keeping pinned state synchronized across CLI, GUI, and internal state
In the walkthrough, we examine:
- How pinned folders are stored, whether in memory or persisted to disk
- How the
pincommand interacts with the pin list - How the toggle logic determines whether a folder should be pinned or unpinned
- How invalid or special folders are rejected safely
- How the UI is refreshed after pinning changes
- How the system integrates with contextual selection
This system keeps everything in sync.
- Current directory
- Current selection
- Search state
- Help/manual state
- Pinned folders
- History
In the walkthrough, we examine:
- Where shared state lives
- How different systems read and update it
- How we avoid inconsistent or unsafe states
This system handles closing the app safely.
exitcommand and its aliases- Confirmation prompts
- Cleanup logic before shutdown
In the walkthrough, we cover:
- How exit is triggered from CLI and GUI
- How the confirmation dialog is shown
- How the app ensures a clean shutdown
The pinning system manages the user’s Easy Access list. It stores pinned folders, validates them, updates the UI, and provides the toggle behavior used by both the GUI and CLI. This walkthrough explains each method in the system line by line so readers can understand how the feature works internally.
- RefreshPinUI
- EnsureEasyAccessFile
- LoadEasyAccessEntries
- AddToEasyAccess
- RemoveFromEasyAccess
- IsPinned
- UpdatePinButtonState
- UpdateFileListPinState
- IsTreeNodePinnable
- UpdateTreeContextMenu
- IsSpecialFolder
- PinFromFiles / UnpinFromFiles
- Pin_Click / Unpin_Click
- TogglePin
- GetPinnableTarget
This method updates every UI element that depends on pin state.
- Calls
UpdateTreeRoots()to refresh the folder tree, including pinned roots. - Calls
UpdateFileListPinState()to update the file list’s context menu. - Calls
UpdatePinButtonState()to update the toolbar pin/unpin button.
This ensures the UI always reflects the current pin state after any change.
This method guarantees that the Easy Access storage file exists.
- Extracts the directory from the Easy Access file path.
- Creates the directory if it does not exist.
- Creates an empty file if the Easy Access file does not exist.
This prevents file‑not‑found errors anywhere else in the system.
This method loads all pinned entries from disk.
- Ensures the Easy Access file exists.
- Creates a list to hold entries.
- Reads each line from the file.
- Uses
ParseEntryto convert each line into a(Name, Path)tuple. - Adds valid entries to the list, even if the folder no longer exists.
The result is the authoritative list of pinned folders.
This method adds a new pinned folder.
- Ensures the Easy Access file exists.
- Normalizes the incoming path.
- Reads all existing lines.
- Checks for duplicates by comparing normalized paths.
- If already pinned, refreshes the UI and exits.
- Otherwise, appends a new entry in
name,pathformat. - Refreshes the UI.
This prevents duplicates and keeps the UI synchronized.
This method removes a pinned folder.
- Ensures the Easy Access file exists.
- Normalizes the target path.
- Reads all lines from the file.
- Filters out any entry whose normalized path matches the target.
- Writes the updated list back to disk.
- Refreshes the UI.
This cleanly removes the folder from the pinned list.
This method checks whether a folder is currently pinned.
- Normalizes the input path.
- Reads all lines from the Easy Access file.
- Parses each line.
- Compares normalized paths.
- Returns
Trueif a match is found.
This method is used by the toggle logic and UI updates.
This method updates the toolbar pin/unpin button.
- Disables the button and sets the default pin icon.
- Calls
GetPinnableTarget()to determine the current target. - If no valid target exists, the button stays disabled.
- If a target exists:
- Enables the button.
- Sets the icon to “unpin” if the folder is pinned.
- Sets the icon to “pin” if it is not pinned.
This ensures the button always reflects the correct state.
This method updates the file list’s context menu.
- Retrieves the Pin and Unpin menu items.
- Hides both by default.
- If no item is selected, exits.
- Retrieves the selected item’s path.
- Validates that the path exists and is not a special folder.
- Shows either Pin or Unpin depending on the folder’s state.
This provides correct context menu options for each folder.
This method checks whether a tree node represents a pinnable folder.
- Ensures the node exists.
- Extracts the path from the node.
- Validates that the path exists and is not a special folder.
- Returns
Trueonly if the folder is eligible for pinning.
This is used by the tree view’s context menu logic.
This method updates the tree view’s context menu.
- Extracts the path from the selected node.
- Validates the path.
- If invalid, hides both Pin and Unpin.
- If valid, shows the appropriate option based on whether the folder is pinned.
This keeps the tree view’s context menu consistent with the file list.
This method prevents pinning system folders.
- Defines a list of known special folders (Documents, Music, Pictures, Videos, Downloads, Desktop).
- Compares the input path to each special folder path.
- Returns
Trueif the folder is special.
This protects the user from pinning system‑managed locations.
These handlers respond to context menu clicks in the file list.
- Ensure an item is selected.
- Extract the path.
- Call the toggle method.
These provide GUI‑based pin/unpin actions.
These handlers respond to context menu clicks in the tree view.
- Extract the selected node’s path.
- Call the toggle method.
This mirrors the file list behavior for the tree.
This is the core toggle method.
- Validates the path.
- Rejects special folders.
- Retrieves the display name.
- If the folder is pinned → removes it.
- If not pinned → adds it.
- Refreshes the UI.
This is the heart of the pinning system.
This method determines which folder should be pinned or unpinned based on context.
It checks in order:
-
File list
- If the last focused control was the file list and a folder is selected, return it.
-
Tree view
- If the last focused control was the tree view and a folder is selected, return it.
-
Address bar
- If the last focused control was the address bar, return the current folder.
-
Fallback
- If none of the above apply, return
Nothing.
- If none of the above apply, return
This ensures the pin button and pin command always act on the correct folder.
TogglePin is the core method that switches a folder between pinned and unpinned states. It validates the folder, determines whether it is already pinned, performs the appropriate action, and then refreshes the UI so the change is immediately visible.
Private Sub TogglePin(path As String)
If String.IsNullOrWhiteSpace(path) Then Exit Sub
If Not Directory.Exists(path) Then Exit Sub
If IsSpecialFolder(path) Then Exit Sub
Dim name As String = GetFolderDisplayName(path)
If IsPinned(path) Then
RemoveFromEasyAccess(path)
Else
AddToEasyAccess(name, path)
End If
RefreshPinUI()
End Sub- It first checks whether the provided path is empty or whitespace. If so, the method exits immediately.
- It verifies that the path points to an existing directory. If not, the operation is ignored.
- It checks whether the folder is a special folder (Documents, Desktop, etc.). Special folders cannot be pinned, so the method exits.
- It retrieves a display name for the folder using
GetFolderDisplayName(path). - It calls
IsPinned(path)to determine the current state:- If the folder is pinned, it calls
RemoveFromEasyAccess(path)to unpin it. - If the folder is not pinned, it calls
AddToEasyAccess(name, path)to pin it.
- If the folder is pinned, it calls
- Finally, it calls
RefreshPinUI()to update the tree view, file list, and pin button.
TogglePin is the heart of the pinning system. It ensures:
- The pin/unpin behavior is consistent everywhere (CLI, tree view, file list, toolbar).
- Invalid or unsafe paths are rejected early.
- The UI always reflects the correct state after any change.
- The logic for pinning is centralized, preventing duplication across the app.
This method renames either a file or a folder, following a clear set of safety rules. Each rule protects the user from mistakes and helps them understand what’s happening.
Below is the full code, then we’ll walk through it one step at a time.
Private Sub RenameFileOrDirectory(sourcePath As String, newName As String)
Dim newPath As String = Path.Combine(Path.GetDirectoryName(sourcePath), newName)
' Rule 1: Path must be absolute (start with C:\ or similar).
' Reject relative paths outright
If Not Path.IsPathRooted(sourcePath) Then
ShowStatus(IconDialog & " Rename failed: Path must be absolute. Example: C:\folder")
Exit Sub
End If
' Rule 2: Protected paths are never renamed.
' Check if the path is in the protected list
If IsProtectedPathOrFolder(sourcePath) Then
' The path is protected; prevent rename
' Show user the directory so they can see it wasn't renamed.
NavigateTo(sourcePath)
' Notify the user of the prevention so the user knows why it didn't rename.
ShowStatus(IconProtect & " Rename prevented for protected path or folder: " & sourcePath)
Exit Sub
End If
Try
' Rule 3: If it’s a folder, rename the folder and show the new folder.
' If source is a directory
If Directory.Exists(sourcePath) Then
' Rename directory
Directory.Move(sourcePath, newPath)
' Navigate to the renamed directory
NavigateTo(newPath)
ShowStatus(IconSuccess & " Renamed Folder to: " & newName)
' Rule 4: If it’s a file, rename the file and show its folder.
' If source is a file
ElseIf File.Exists(sourcePath) Then
' Rename file
File.Move(sourcePath, newPath)
' Navigate to the directory of the renamed file
NavigateTo(Path.GetDirectoryName(sourcePath))
ShowStatus(IconSuccess & " Renamed File to: " & newName)
' Rule 5: If nothing exists at that path, explain the quoting rule for spaces.
Else
' Path does not exist
ShowStatus(IconError & " Renamed failed: No path. Paths with spaces must be enclosed in quotes. Example: rename ""[source_path]"" ""[new_name]"" e.g., rename ""C:\folder\old name.txt"" ""new name.txt""")
End If
Catch ex As Exception
' Rule 6: If anything goes wrong,show a status message.
ShowStatus(IconError & " Rename failed: " & ex.Message)
Debug.WriteLine("RenameFileOrDirectory Error: " & ex.Message)
End Try
End Sub
Private Sub RenameFileOrDirectory(sourcePath As String, newName As String)- sourcePath — the full path to the file or folder you want to rename
- newName — just the new name (not a full path)
Dim newPath As String = Path.Combine(Path.GetDirectoryName(sourcePath), newName)- Extracts the folder that contains the item
- Combines it with the new name
- Example:
sourcePath = "C:\Stuff\Old.txt"newName = "New.txt"newPath = "C:\Stuff\New.txt"
If Not Path.IsPathRooted(sourcePath) Then
ShowStatus(IconDialog & " Rename failed: Path must be absolute. Example: C:\folder")
Exit Sub
End IfBeginners often type relative paths like folder\file.txt.
This rule stops the rename and explains the correct format.
If IsProtectedPathOrFolder(sourcePath) Then
NavigateTo(sourcePath)
ShowStatus(IconProtect & " Rename prevented for protected path or folder: " & sourcePath)
Exit Sub
End IfSome paths should never be renamed (system folders, app folders, etc.).
This rule:
- Prevents the rename
- Shows the user the original folder
- Explains why the rename was blocked
This is excellent for learner clarity.
Try
...
Catch ex As Exception
ShowStatus(IconError & " Rename failed: " & ex.Message)
Debug.WriteLine("RenameFileOrDirectory Error: " & ex.Message)
End TryAnything inside the Try block that fails will be caught and explained.
Beginners get a friendly message instead of a crash.
If Directory.Exists(sourcePath) Then
Directory.Move(sourcePath, newPath)
NavigateTo(newPath)
ShowStatus(IconSuccess & " Renamed Folder to: " & newName)- Checks if the path points to a directory
- Renames it
- Shows the user the newly renamed folder
This reinforces the idea that folders are “containers” and have their own identity.
ElseIf File.Exists(sourcePath) Then
File.Move(sourcePath, newPath)
NavigateTo(Path.GetDirectoryName(sourcePath))
ShowStatus(IconSuccess & " Renamed File to: " & newName)- Checks if the path points to a file
- Renames it
- Shows the user the folder containing the renamed file
This keeps the UI consistent and predictable.
Else
ShowStatus(IconError & " Renamed failed: No path. Paths with spaces must be enclosed in quotes. Example: rename ""[source_path]"" ""[new_name]"" e.g., rename ""C:\folder\old name.txt"" ""new name.txt""")
End IfBeginners often forget to quote paths with spaces.
This rule:
- Detects the missing path
- Explains the quoting rule
- Gives both a template and a real example
This is excellent pedagogy.
Catch ex As Exception
ShowStatus(IconError & " Rename failed: " & ex.Message)
Debug.WriteLine("RenameFileOrDirectory Error: " & ex.Message)
End Try- No crashes
- Clear feedback
- Debug info for you
This method teaches six important rules:
- Paths must be absolute
- Protected paths cannot be renamed
- Folders are renamed and then shown
- Files are renamed and their folder is shown
- Missing paths trigger a helpful quoting explanation
- Any error is caught and explained safely
This method copies an entire directory — including all files and all subfolders — into a new destination. It uses recursion, meaning the method calls itself to handle deeper levels of folders.
Below is the full code, then we’ll walk through it one step at a time.
Private Async Function CopyDirectory(sourceDir As String, destDir As String) As Task
Dim dirInfo As New DirectoryInfo(sourceDir)
If Not dirInfo.Exists Then
ShowStatus(IconError & " Source directory not found: " & sourceDir)
Return
End If
Try
ShowStatus(IconCopy & " Creating destination directory: " & destDir)
' Create destination directory
Try
Directory.CreateDirectory(destDir)
Catch ex As Exception
ShowStatus(IconError & " Failed to create destination directory: " & ex.Message)
Return
End Try
ShowStatus(IconCopy & " Copying files to destination directory: " & destDir)
' Copy files asynchronously
For Each file In dirInfo.GetFiles()
Try
Dim targetFilePath = Path.Combine(destDir, file.Name)
Await Task.Run(Sub() file.CopyTo(targetFilePath, overwrite:=True))
Debug.WriteLine("Copied file: " & targetFilePath) ' Log successful copy
Catch ex As UnauthorizedAccessException
Debug.WriteLine("CopyDirectory Error (Unauthorized): " & ex.Message)
ShowStatus(IconError & " Unauthorized access: " & file.FullName)
Catch ex As Exception
Debug.WriteLine("CopyDirectory Error: " & ex.Message)
ShowStatus(IconError & " Copy failed for file: " & file.FullName & " - " & ex.Message)
End Try
Next
ShowStatus(IconCopy & " Copying subdirectories.")
' Copy subdirectories recursively asynchronously
For Each subDir In dirInfo.GetDirectories()
Dim newDest = Path.Combine(destDir, subDir.Name)
Try
Await CopyDirectory(subDir.FullName, newDest)
Catch ex As Exception
Debug.WriteLine("CopyDirectory Error: " & ex.Message)
End Try
Next
' Refresh the view to show the copied directory
NavigateTo(destDir)
ShowStatus(IconSuccess & " Copied into " & destDir)
Catch ex As Exception
ShowStatus(IconError & " Copy failed: " & ex.Message)
Debug.WriteLine("CopyDirectory Error: " & ex.Message)
End Try
End Function
Here's a detailed breakdown of the updated CopyDirectory method , which now supports asynchronous file copying. This ensures that the UI remains responsive during the operation, especially when dealing with large directories.
Private Async Function CopyDirectory(sourceDir As String, destDir As String) As Task- sourceDir: The folder you want to copy.
- destDir: The location where the copy should be created.
Dim dirInfo As New DirectoryInfo(sourceDir)- This creates a
DirectoryInfoobject that provides access to the folder's files and subfolders.
If Not dirInfo.Exists Then
ShowStatus(IconError & " Source directory not found: " & sourceDir)
Return
End If- Checks if the source directory exists. If not, it shows an error message and exits the method.
Try- Initiates a block to handle exceptions that may occur during the operation.
Try
Directory.CreateDirectory(destDir)
Catch ex As Exception
ShowStatus(IconError & " Failed to create destination directory: " & ex.Message)
Return
End Try- Attempts to create the destination directory. If it fails, an error message is shown, and the method exits.
For Each file In dirInfo.GetFiles()
Try
Dim targetFilePath = Path.Combine(destDir, file.Name)
Await Task.Run(Sub() file.CopyTo(targetFilePath, overwrite:=True))
Debug.WriteLine("Copied file: " & targetFilePath) ' Log successful copy
Catch ex As UnauthorizedAccessException
Debug.WriteLine("CopyDirectory Error (Unauthorized): " & ex.Message)
ShowStatus(IconError & " Unauthorized access: " & file.FullName)
Catch ex As Exception
Debug.WriteLine("CopyDirectory Error: " & ex.Message)
ShowStatus(IconError & " Copy failed for file: " & file.FullName & " - " & ex.Message)
End Try
Next- Iterates through each file in the source directory and copies it to the destination asynchronously.
- Uses
Await Task.Run(...)to ensure the UI remains responsive during the file copy process. - Handles exceptions specifically for unauthorized access and general errors.
For Each subDir In dirInfo.GetDirectories()
Dim newDest = Path.Combine(destDir, subDir.Name)
Try
Await CopyDirectory(subDir.FullName, newDest)
Catch ex As Exception
Debug.WriteLine("CopyDirectory Error: " & ex.Message)
End Try
Next- For each subdirectory, constructs a new destination path and calls
CopyDirectoryrecursively. - Utilizes
Awaitfor asynchronous execution.
NavigateTo(destDir)- Updates the UI to reflect the new state after the copy operation is complete.
ShowStatus(IconSuccess & " Copied into " & destDir)- Displays a success message once the operation is completed.
Catch ex As Exception
ShowStatus(IconError & " Copy failed: " & ex.Message)
Debug.WriteLine("CopyDirectory Error: " & ex.Message)
End Try- If any errors occur during the overall operation, they are caught here, and an appropriate message is displayed.
- Asynchronous Support: The method now uses
AsyncandAwaitto ensure the application remains responsive during file operations. - Enhanced Error Handling: Specific handling for unauthorized access and general exceptions.
- User Feedback: Continuous feedback is provided to the user throughout the process.
This updated method demonstrates how to effectively manage file copying operations while maintaining a responsive user interface.
This diagram shows exactly how the CopyDirectory routine walks the tree.
Imagine your folder structure looks like this:
SourceDir
├── FileA.txt
├── FileB.txt
├── Sub1
│ ├── FileC.txt
│ └── Sub1A
│ └── FileD.txt
└── Sub2
└── FileE.txt
The method processes it in this exact order.
CopyDirectory(SourceDir, DestDir)
│
├── Copy files in SourceDir
│
├── For each subdirectory:
│ ├── CopyDirectory(Sub1, DestDir/Sub1)
│ │ ├── Copy files in Sub1
│ │ ├── CopyDirectory(Sub1A, DestDir/Sub1/Sub1A)
│ │ │ ├── Copy files in Sub1A
│ │ │ └── (Sub1A has no more subfolders → return)
│ │ └── (Sub1 done → return)
│ │
│ └── CopyDirectory(Sub2, DestDir/Sub2)
│ ├── Copy files in Sub2
│ └── (Sub2 has no more subfolders → return)
│
└── All subdirectories processed → return to caller
This shows how the call stack grows and shrinks as recursion happens.
Call 1: CopyDirectory(SourceDir)
├── copies files
├── enters Sub1 → Call 2
Call 2: CopyDirectory(Sub1)
├── copies files
├── enters Sub1A → Call 3
Call 3: CopyDirectory(Sub1A)
├── copies files
└── no subfolders → return to Call 2
Back to Call 2:
└── Sub1 done → return to Call 1
Back to Call 1:
├── enters Sub2 → Call 4
Call 4: CopyDirectory(Sub2)
├── copies files
└── no subfolders → return to Call 1
Back to Call 1:
└── all done → return to caller
Each level of indentation = one level deeper in recursion.
CopyDirectory(SourceDir)
CopyDirectory(Sub1)
CopyDirectory(Sub1A)
CopyDirectory(Sub2)
This is the simplest way to show the “shape” of recursion.
- Start at the root folder.
- Copy its files.
- For each subfolder:
- Step into it
- Treat it like a brand‑new root
- Copy its files
- Repeat the process for its subfolders
- When a folder has no subfolders, return to the previous level.
- Continue until you climb all the way back to the top.
This walkthrough explains how the MoveFileOrDirectory routine works inside the file‑manager project. The goal of this method is to safely move files or directories while providing clear, user‑friendly feedback and preventing dangerous or confusing operations.
MoveFileOrDirectory(source, destination) performs a safe move operation with:
- Input validation
- Protected‑path checks
- Self‑move and recursive‑move prevention
- Automatic creation of destination directories
- User‑visible navigation before and after the move
- Clear status messages for every outcome
This mirrors the project’s design philosophy:
Show → Confirm → Act → Show Result
Private Sub MoveFileOrDirectory(source As String, destination As String)
Try
' Validate parameters
If String.IsNullOrWhiteSpace(source) OrElse String.IsNullOrWhiteSpace(destination) Then
ShowStatus(IconWarning & " Source or destination path is invalid.")
Return
End If
' If source and destination are the same, do nothing
If String.Equals(source.TrimEnd("\"c), destination.TrimEnd("\"c), StringComparison.OrdinalIgnoreCase) Then
ShowStatus(IconWarning & " Source and destination paths are the same. Move operation canceled.")
Return
End If
' Is source on the protected paths list?
If IsProtectedPathOrFolder(source) Then
ShowStatus(IconProtect & " Move operation prevented for protected path: " & source)
Return
End If
' Is destination on the protected paths list?
If IsProtectedPathOrFolder(destination) Then
ShowStatus(IconProtect & " Move operation prevented for protected path: " & destination)
Return
End If
' Prevent moving a directory into itself or its subdirectory
If Directory.Exists(source) AndAlso
(String.Equals(source.TrimEnd("\"c), destination.TrimEnd("\"c), StringComparison.OrdinalIgnoreCase) OrElse
destination.StartsWith(source.TrimEnd("\"c) & "\", StringComparison.OrdinalIgnoreCase)) Then
ShowStatus(IconWarning & " Cannot move a directory into itself or its subdirectory.")
Return
End If
' Check if the source is a file
If File.Exists(source) Then
' Check if the destination file already exists
If Not File.Exists(destination) Then
' Navigate to the directory of the source file
NavigateTo(Path.GetDirectoryName(source))
ShowStatus(IconDialog & " Moving file to: " & destination)
' Ensure destination directory exists
Directory.CreateDirectory(Path.GetDirectoryName(destination))
File.Move(source, destination)
' Navigate to the destination folder
NavigateTo(Path.GetDirectoryName(destination))
ShowStatus(IconSuccess & " Moved file to: " & destination)
Else
ShowStatus(IconWarning & " Destination file already exists.")
End If
ElseIf Directory.Exists(source) Then
' Check if the destination directory already exists
If Not Directory.Exists(destination) Then
' Navigate to the directory being moved so the user can see it
NavigateTo(source)
ShowStatus(IconDialog & " Moving directory to: " & destination)
' Ensure destination parent exists
Directory.CreateDirectory(Path.GetDirectoryName(destination))
' Perform the move
Directory.Move(source, destination)
' Navigate to the new location FIRST
NavigateTo(destination)
' Now refresh the tree roots
InitTreeRoots()
ShowStatus(IconSuccess & " Moved directory to: " & destination)
Else
ShowStatus(IconWarning & " Destination directory already exists.")
End If
Else
ShowStatus(IconWarning & " Move failed: Source path not found. Paths with spaces must be enclosed in quotes. Example: move ""C:\folder A"" ""C:\folder B""")
End If
Catch ex As Exception
ShowStatus(IconError & " Move failed: " & ex.Message)
Debug.WriteLine("MoveFileOrDirectory Error: " & ex.Message)
End Try
End SubRejects empty or whitespace paths to prevent confusing errors.
If the source and destination resolve to the same location, the move is canceled.
Both source and destination are checked against a protected‑paths list.
Protected paths cannot be moved.
The method prevents moving a directory into:
- Itself
- One of its own subdirectories
This avoids catastrophic recursive behavior.
If the source is a file:
- Navigate to the file’s directory
- Ensure the destination directory exists
- Move the file
- Navigate to the destination folder
- Show success
If the source is a directory:
- Navigate into the directory being moved
- Ensure the destination parent exists
- Move the directory
- Navigate to the new location
- Refresh the tree
- Show success
Any exception results in:
- A user‑friendly status message
- A debug log entry
This method is built around clarity, safety, and emotional transparency:
- The user always sees what is about to happen
- The user always sees the result
- Dangerous operations are prevented
- All actions are narrated through status messages
- The UI updates in a way that reinforces the mental model
This makes the file manager not just functional — but guiding.
The NavigateTo method is responsible for navigating to a specified folder path.
Below is the full code, then we’ll walk through it one step at a time.
Private Sub NavigateTo(path As String, Optional recordHistory As Boolean = True)
' Navigate to the specified folder path.
' Updates the current folder, path textbox, and file list.
If String.IsNullOrWhiteSpace(path) Then Exit Sub
' Validate that the folder exists
If Not Directory.Exists(path) Then
MessageBox.Show("Folder not found: " & path, "Navigation", MessageBoxButtons.OK, MessageBoxIcon.Information)
ShowStatus(IconWarning & " Folder not found: " & path)
Exit Sub
End If
' If this method is called from a background thread, invoke it on the UI thread
If txtPath.InvokeRequired Then
txtPath.Invoke(New Action(Of String)(AddressOf NavigateTo), path, recordHistory)
Return
End If
ShowStatus(IconNavigate & " Navigated To: " & path)
currentFolder = path
txtPath.Text = path
PopulateFiles(path)
If recordHistory Then
' Trim forward history if we branch
If _historyIndex >= 0 AndAlso _historyIndex < _history.Count - 1 Then
_history.RemoveRange(_historyIndex + 1, _history.Count - (_historyIndex + 1))
End If
_history.Add(path)
_historyIndex = _history.Count - 1
UpdateNavButtons()
End If
UpdateFileButtons()
UpdateEditButtons()
UpdateEditContextMenu()
End Sub
Here's a detailed breakdown of the NavigateTo method in VB.NET, which is responsible for navigating to a specified folder path. This method updates the UI components accordingly and manages navigation history.
Private Sub NavigateTo(path As String, Optional recordHistory As Boolean = True)- path: The folder path to navigate to.
- recordHistory: An optional boolean parameter that indicates whether the navigation should be recorded in history (default is
True).
If String.IsNullOrWhiteSpace(path) Then Exit Sub- Checks if the provided path is null, empty, or consists only of whitespace. If so, the method exits early.
If Not Directory.Exists(path) Then
MessageBox.Show("Folder not found: " & path, "Navigation", MessageBoxButtons.OK, MessageBoxIcon.Information)
ShowStatus(IconWarning & " Folder not found: " & path)
Exit Sub
End If- Validates that the specified folder exists. If it does not, a message box is displayed to inform the user, and a warning status is shown. The method then exits.
If txtPath.InvokeRequired Then
txtPath.Invoke(New Action(Of String)(AddressOf NavigateTo), path, recordHistory)
Return
End If- Checks if the method is being called from a background thread (indicated by
InvokeRequired). If so, it invokes the method on the UI thread usingInvoke, ensuring that UI updates are performed on the correct thread.
ShowStatus(IconNavigate & " Navigated To: " & path)
currentFolder = path
txtPath.Text = path
PopulateFiles(path)- Updates the status to indicate the navigation action.
- Sets the
currentFoldervariable to the new path. - Updates the text box (
txtPath) with the new path. - Calls
PopulateFiles(path)to refresh the file list displayed in the UI.
If recordHistory Then
' Trim forward history if we branch
If _historyIndex >= 0 AndAlso _historyIndex < _history.Count - 1 Then
_history.RemoveRange(_historyIndex + 1, _history.Count - (_historyIndex + 1))
End If
_history.Add(path)
_historyIndex = _history.Count - 1
UpdateNavButtons()
End If- If
recordHistoryisTrue, it manages the navigation history:- Trims the forward history if the current index is not at the end of the history list.
- Adds the new path to the history list.
- Updates the
_historyIndexto point to the last entry in the history. - Calls
UpdateNavButtons()to refresh the navigation buttons (e.g., back and forward).
UpdateFileButtons()
UpdateEditButtons()
UpdateEditContextMenu()- Calls methods to update various UI elements related to file actions, editing, and context menus, ensuring they reflect the current state after navigation.
The NavigateTo method effectively handles folder navigation with the following key features:
- Input Validation: Checks for valid paths and existence of directories.
- Thread Safety: Ensures UI updates occur on the correct thread.
- User Feedback: Provides immediate feedback on navigation actions and errors.
- History Management: Maintains a history of navigated folders, allowing for backward and forward navigation.
- UI Updates: Refreshes relevant UI components to reflect the current folder state.
This method is essential for any file management application, ensuring smooth and intuitive navigation for users.
This code takes the user’s search term, finds matching files in the current folder, highlights the first match, shows how many results there are, and gives the user a clean, Explorer‑style search experience.
Think of this code as the “start a search” feature in our file explorer.
When the user types something like:
find report
this block of code runs.
Case "find", "search"
If parts.Length > 1 Then
Dim searchTerm As String = String.Join(" ", parts.Skip(1)).Trim()
If String.IsNullOrWhiteSpace(searchTerm) Then
ShowStatus(
StatusPad & IconDialog &
" Usage: find [search_term] Example: find document"
)
Return
End If
' Announce search
ShowStatus(StatusPad & IconSearch & " Searching for: " & searchTerm)
' Perform search
OnlySearchForFilesInCurrentFolder(searchTerm)
' Reset index for new search
SearchIndex = 0
RestoreBackground()
' If results exist, auto-select the first one
If SearchResults.Count > 0 Then
lvFiles.SelectedItems.Clear()
SelectListViewItemByPath(SearchResults(0))
Dim nextPath As String = SearchResults(SearchIndex)
Dim fileName As String = Path.GetFileNameWithoutExtension(nextPath)
lvFiles.Focus()
HighlightSearchMatches()
' Unified search HUD
ShowStatus(
StatusPad & IconSearch &
$" Result {SearchIndex + 1} of {SearchResults.Count} ""{fileName}"" Next F3 Open Ctrl+O Reset Esc"
)
Else
ShowStatus(
StatusPad & IconDialog &
" No results found for: " & searchTerm
)
End If
Else
ShowStatus(
StatusPad & IconDialog &
" Usage: find [search_term] Example: find document"
)
End If
Return
Let’s go through it step by step.
Make sure the user actually typed a search term
If parts.Length > 1 Thenpartsis the command split into words.- If the user typed only
findwith nothing after it, then there’s nothing to search for.
Combine everything after the command into one search term
Dim searchTerm As String = String.Join(" ", parts.Skip(1)).Trim()- This takes everything after the word
findand turns it into one string. - Example:
find my report→"my report"
If the search term is empty, show a helpful message
If String.IsNullOrWhiteSpace(searchTerm) Then
ShowStatus("Usage: find [search_term] Example: find document")
Return
End If- This protects the user from mistakes.
- It stops the command early and explains how to use it.
Tell the user that the search has started
ShowStatus("Searching for: " & searchTerm)- This updates your status bar so the user knows something is happening.
Actually perform the search
OnlySearchForFilesInCurrentFolder(searchTerm)- This is your search engine.
- It looks through the current folder and fills
SearchResultswith matching file paths.
Reset the search index
SearchIndex = 0
RestoreBackground()- Since this is a new search, you always start at the first result.
RestoreBackground()clears any old highlighting from a previous search.
If matches were found…
If SearchResults.Count > 0 ThenNow the fun part begins.
Select the first matching file
lvFiles.SelectedItems.Clear()
SelectListViewItemByPath(SearchResults(0))- Clears any previous selection.
- Highlights the first matching file in the ListView.
- Scrolls to it so the user can see it.
Get a clean file name for display
Dim nextPath As String = SearchResults(SearchIndex)
Dim fileName As String = Path.GetFileNameWithoutExtension(nextPath)- Turns something like
C:\Users\Joseph\Documents\Report1.pdf
into
"Report1"
Focus the ListView and highlight all matches
lvFiles.Focus()
HighlightSearchMatches()- Gives keyboard focus to the file list.
- Highlights all matching items.
Show the unified search HUD
ShowStatus(
$"Result {SearchIndex + 1} of {SearchResults.Count} ""{fileName}"" Next F3 Open Ctrl+O Reset Esc"
)This status message that tells the user:
- Which result they’re on
- How many results exist
- The file name
- Helpful keyboard shortcuts
If no results were found…
Else
ShowStatus("No results found for: " & searchTerm)
End If- The app gently tells the user nothing matched.
If the user typed only “find” with no term
Else
ShowStatus("Usage: find [search_term] Example: find document")
End If- Another friendly reminder about how to use the command.
This method cycles to the next search result, highlights it in the file list, scrolls to it, and updates the status bar so the user always knows where they are and what they can do next.
Below is the full code, then we’ll walk through it one step at a time.
Private Sub HandleFindNextCommand()
' No active search
If SearchResults.Count = 0 Then
ShowStatus(
StatusPad & IconDialog &
" No previous search results. Press Ctrl+F or enter: find [search_term] to start a search."
)
Return
End If
' Advance index with wraparound
SearchIndex += 1
If SearchIndex >= SearchResults.Count Then
SearchIndex = 0
End If
' Select the next result
lvFiles.SelectedItems.Clear()
Dim nextPath As String = SearchResults(SearchIndex)
SelectListViewItemByPath(nextPath)
Dim fileName As String = Path.GetFileNameWithoutExtension(nextPath)
' Status HUD
ShowStatus(
StatusPad & IconSearch &
$" Result {SearchIndex + 1} of {SearchResults.Count} ""{fileName}"" Next F3 Open Ctrl+O Reset Esc"
)
End Sub
Private Sub HandleFindNextCommand()- This defines a subroutine (a block of code) named
HandleFindNextCommand. - It runs whenever the user triggers the “Find Next” action — for example, pressing F3 or typing
findnext.
' No active search
If SearchResults.Count = 0 Then- This checks whether there are any search results stored.
SearchResultsis a list of file paths found by the last search.- If the list is empty (
Count = 0), it means the user hasn’t searched yet.
ShowStatus(
StatusPad & IconDialog &
" No previous search results. Press Ctrl+F or enter: find [search_term] to start a search."
)- This displays a friendly message in your status bar.
StatusPadandIconDialogare just decorative pieces that make the message look nice.- The message tells the user how to start a search.
Return
End IfReturnstops the subroutine immediately.- Since there are no results, there’s nothing else to do.
' Advance index with wraparound
SearchIndex += 1- This moves to the next search result.
SearchIndexkeeps track of which result is currently selected.+= 1means “add 1 to the current value.”
If SearchIndex >= SearchResults.Count Then
SearchIndex = 0
End If- This handles wraparound.
- If the index goes past the last result, it jumps back to the first one.
- This creates a loop: last → first → second → etc.
- It feels like how Explorer cycles through search results.
' Select the next result
lvFiles.SelectedItems.Clear()- Clears any previous selection in the file list.
- This ensures only the new result is highlighted.
Dim nextPath As String = SearchResults(SearchIndex)- Retrieves the file path of the next search result.
- Stores it in a variable named
nextPath.
SelectListViewItemByPath(nextPath)- This is our helper function that:
- Finds the matching item in the ListView.
- Selects the item.
- Scrolls the ListView so the item is visible.
- This is what makes the UI jump to the matching file.
Dim fileName As String = Path.GetFileNameWithoutExtension(nextPath)- Extracts just the file name (no folder, no extension).
- This is used for a cleaner status message.
' Status HUD
ShowStatus(
StatusPad & IconSearch &
$" Result {SearchIndex + 1} of {SearchResults.Count} ""{fileName}"" Next F3 Open Ctrl+O Reset Esc"
)- Updates the status bar with a compact “search HUD.”
- It shows:
- Which result you’re on
(Result 3 of 12) - The file name
("Report Q1") - Helpful keyboard shortcuts
(Next F3,Open Ctrl+O,Reset Esc)
- Which result you’re on
SearchIndex + 1is used because lists start at 0, but humans start at 1.
End Sub- Marks the end of the subroutine.
This helper is a quiet hero in our search system. It ensures that:
- The correct file is highlighted
- The UI scrolls to it
- Keyboard navigation starts from the right place
- The user feels like the app “knows where they are”
Below is the full code, then we’ll walk through it one step at a time.
Private Sub SelectListViewItemByPath(fullPath As String)
For Each item As ListViewItem In lvFiles.Items
If String.Equals(item.Tag.ToString(), fullPath, StringComparison.OrdinalIgnoreCase) Then
item.Selected = True
item.Focused = True
item.EnsureVisible()
Exit For
End If
Next
End Sub
Private Sub SelectListViewItemByPath(fullPath As String)- This defines a subroutine named
SelectListViewItemByPath. - It takes one input:
fullPath, which is the complete file or folder path you want to select in the ListView. - The goal is simple: find the matching item and highlight it.
For Each item As ListViewItem In lvFiles.Items- This starts a loop that goes through every item in the ListView (
lvFiles). itemrepresents the current ListViewItem being checked.- The loop continues until a match is found or all items have been checked.
If String.Equals(item.Tag.ToString(), fullPath, StringComparison.OrdinalIgnoreCase) Then- Each ListViewItem stores its full path inside its
.Tagproperty. - This line compares the item's stored path with the
fullPathwe’re searching for. StringComparison.OrdinalIgnoreCasemeans:- Compare the text exactly
- Ignore uppercase/lowercase differences
This matches how Windows treats file paths.
item.Selected = True- Marks the item as selected in the ListView.
- This highlights it visually.
item.Focused = True- Gives the item keyboard focus.
- This ensures:
- Arrow keys start from this item
- The dotted focus rectangle appears
- It behaves like the user clicked it
item.EnsureVisible()- Scrolls the ListView so the item is visible.
- If the item is off‑screen, the ListView automatically scrolls to bring it into view.
- This is essential for a smooth “Find Next” experience.
Exit For- Stops the loop immediately.
- No need to keep searching once the correct item is found.
End If
Next- Ends the
Ifblock and continues the loop if needed.
End Sub- Ends the subroutine.
The File Explorer supports a set of convenient keyboard shortcuts to speed up navigation and file operations. These shortcuts mirror familiar behaviors from traditional file managers, making the interface fast and intuitive.
| Shortcut | Action |
|---|---|
| Alt + ← (or Backspace) | Go back to the previous folder |
| Alt + → | Go forward to the next folder |
| Alt + ↑ | Move up one level (parent directory) |
| Ctrl + L (or Alt + D, F4) | Focus/select the address bar |
| F11 | Toggle full‑screen mode |
| Shortcut | Action |
|---|---|
| F2 | Rename the selected file or folder |
| Ctrl + Shift + N | Create a new folder |
| Ctrl + Shift + T | Create a new text file |
| Ctrl + O | Open the selected file or folder or start an open command |
| Ctrl + C | Copy selected items |
| Ctrl + V | Paste items |
| Ctrl + X | Cut selected items |
| Ctrl + A | Select all items |
| Ctrl + Shift + E | Expand the selected folder or drive |
| Ctrl + Shift + C | Collapse the selected folder or drive |
| Ctrl + D (or Delete) | Delete selected item to the Recycle Bin |
| Shortcut | Action |
|---|---|
| Ctrl + F | Start a search in the current folder |
| F3 | Select the next search result. |
| F5 | Refresh the current folder view |
This project is licensed under the MIT License. You are free to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the software, with the inclusion of the copyright notice and permission notice in all copies or substantial portions of the software.
To install and run the File Explorer application:
- Clone the repository:
git clone https://github.com/JoeLumbley/File-Explorer.git
- Open the solution in Visual Studio.
- Build the project and run it.
- Launch the application to access your file system.
- Use the tree view on the left to navigate through folders.
- The list view on the right displays the contents of the selected directory.
- Use the text box to enter commands or navigate directly to a path.
- Right-click on files or folders for additional options.
This project is inspired by traditional file explorers and aims to provide a simplified experience for managing files on Windows systems.
For more details, check the source code and documentation within the repository.