CoreSuite.FileManager 2.0.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package CoreSuite.FileManager --version 2.0.0
                    
NuGet\Install-Package CoreSuite.FileManager -Version 2.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="CoreSuite.FileManager" Version="2.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="CoreSuite.FileManager" Version="2.0.0" />
                    
Directory.Packages.props
<PackageReference Include="CoreSuite.FileManager" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add CoreSuite.FileManager --version 2.0.0
                    
#r "nuget: CoreSuite.FileManager, 2.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package CoreSuite.FileManager@2.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=CoreSuite.FileManager&version=2.0.0
                    
Install as a Cake Addin
#tool nuget:?package=CoreSuite.FileManager&version=2.0.0
                    
Install as a Cake Tool

CoreSuite.FileManager

Asynchronous file and directory copy and deletion with progress reporting and cancellation.

CoreSuite.FileManager is one of the libraries included in the CoreSuite solution. It targets plain .NET 8, works independently of Windows Forms and has no CoreSuite or third-party package dependencies.

Overview

CoreSuite.FileManager provides a focused service for copying and deleting files or complete directory trees without blocking the calling thread during expensive file-system work.

Operations support CancellationToken, normalize paths, validate unsafe source and destination combinations and report byte and item progress through dedicated events. Directory traversal deliberately skips reparse points, preventing the service from following symbolic links, junctions and other redirected directory structures.

The package also includes a helper for clearing a directory while preserving selected files and subdirectories.

Features

  • Copies individual files asynchronously.
  • Copies one or several directory trees asynchronously.
  • Creates missing destination directories automatically during copy operations.
  • Preserves empty directories when copying a directory tree.
  • Overwrites existing destination files.
  • Deletes individual files asynchronously.
  • Deletes one or several directory trees asynchronously.
  • Optionally preserves the root directory while deleting its contents.
  • Clears a directory while preserving selected files and subdirectories.
  • Reports progress by bytes and completed file count.
  • Captures the caller's synchronization context for progress events.
  • Supports cancellation across enumeration, copy and deletion work.
  • Removes duplicate file paths from multi-file deletion requests.
  • Rejects directory copies whose destination is equal to or inside the source.
  • Rejects overlapping directory deletion roots.
  • Skips reparse points during recursive enumeration.
  • Uses operating-system-appropriate path comparison rules.
  • Includes English XML documentation for the public API.
  • Requires no third-party packages.

Requirements

  • .NET 8 (net8.0)

Installation

Install the package from NuGet:

dotnet add package CoreSuite.FileManager

Or use the Visual Studio NuGet Package Manager and search for:

CoreSuite.FileManager

Namespace

Import the service namespace and System.IO:

Imports System.IO
Imports CoreSuite.Services

Quick start

Copy one file and receive progress updates:

Dim manager As New FileManager()

AddHandler manager.CopyFileProgressChanged,
    Sub(sender, e)
        Console.WriteLine($"{e.PercentCompleted}% - {e.CurrentPath}")
    End Sub

Dim sourceFile As New FileInfo("C:\Data\large-export.zip")
Dim destinationFile As New FileInfo("D:\Backup\large-export.zip")

Await manager.CopyFileAsync(sourceFile, destinationFile)

The destination parent directory is created when necessary. An existing destination file is overwritten.

Copy a file with cancellation

Using cancellationSource As New CancellationTokenSource()
    Try
        Await manager.CopyFileAsync(sourceFile, destinationFile, cancellationSource.Token)
    Catch ex As OperationCanceledException
        Console.WriteLine("Copy canceled.")
    End Try
End Using

Cancellation does not roll back bytes already written. If the operation is canceled, the destination may contain a partial file and your application should decide whether to keep or remove it.

Copy a directory

Create a CopyDirectoryInfo containing the source and destination:

Dim manager As New FileManager()
Dim copyRequest As New CopyDirectoryInfo(
    New DirectoryInfo("C:\ApplicationData"),
    New DirectoryInfo("D:\Backup\ApplicationData"))

AddHandler manager.CopyDirectoryProgressChanged,
    Sub(sender, e)
        Console.WriteLine($"{e.PercentCompleted}% - {e.ProcessedItems}/{e.TotalItems}")
    End Sub

Dim copiedBytes As Long = Await manager.CopyDirectoryAsync(copyRequest)

The complete source tree is planned before copying starts. This allows the service to calculate the total number of bytes and files. Empty directories are created at the destination.

Participate in a larger progress calculation

CopyDirectoryAsync accepts optional totalSize and handledSize values when its progress should be combined with other work:

Dim alreadyCopied As Long = 500000
Dim completeOperationSize As Long = 2000000
Dim copiedNow As Long = Await manager.CopyDirectoryAsync(copyRequest, completeOperationSize, alreadyCopied, cancellationToken)

The returned value is the number of bytes copied by the supplied directory request, not the accumulated handledSize.

Copy multiple directories

Dim requests As CopyDirectoryInfo() = {
    New CopyDirectoryInfo(New DirectoryInfo("C:\Data\Customers"), New DirectoryInfo("D:\Backup\Customers")),
    New CopyDirectoryInfo(New DirectoryInfo("C:\Data\Orders"), New DirectoryInfo("D:\Backup\Orders"))
}

Await manager.CopyDirectoriesAsync(requests, cancellationToken)

Progress is calculated across all planned files in all requests.

Delete files

Dim filesToDelete As FileInfo() = {
    New FileInfo("C:\Temp\result-1.tmp"),
    New FileInfo("C:\Temp\result-2.tmp")
}

AddHandler manager.DeleteFilesProgressChanged,
    Sub(sender, e)
        Console.WriteLine($"Deleted {e.ProcessedItems} of {e.TotalItems} files.")
    End Sub

Await manager.DeleteFilesAsync(filesToDelete, cancellationToken)

Duplicate normalized paths are processed only once. Every requested file must exist when the deletion plan is built; otherwise, FileNotFoundException is thrown.

Delete directories

Use DeleteDirectoryInfo.DeleteRoot to choose whether the root is removed after its contents:

Dim requests As DeleteDirectoryInfo() = {
    New DeleteDirectoryInfo(New DirectoryInfo("C:\Temp\OldImports"), True),
    New DeleteDirectoryInfo(New DirectoryInfo("C:\Temp\Working"), False)
}

AddHandler manager.DeleteDirectoriesProgressChanged,
    Sub(sender, e)
        Console.WriteLine($"{e.PercentCompleted}%")
    End Sub

Await manager.DeleteDirectoriesAsync(requests, cancellationToken)

The first request deletes OldImports and its contents. The second deletes everything inside Working but preserves the Working root directory.

Missing directory roots are ignored. Existing roots in the same request may not be equal, nested or otherwise overlap.

Clear a directory with exclusions

DeleteDirectoryContentAsync removes content without deleting the supplied root. It can preserve complete subtrees and individual files:

Dim rootDirectory As New DirectoryInfo("C:\Application\Cache")
Dim directoriesToKeep As DirectoryInfo() = {
    New DirectoryInfo("C:\Application\Cache\Pinned")
}
Dim filesToKeep As FileInfo() = {
    New FileInfo("C:\Application\Cache\settings.json")
}

Await FileManager.DeleteDirectoryContentAsync(rootDirectory, directoriesToKeep, filesToKeep, cancellationToken)

When a directory is excluded, all of its descendants are preserved. The service also preserves the required ancestors of excluded items so that those items remain reachable.

Every exclusion must be located inside the supplied root. Passing the root itself in exceptDirectories makes the method return without deleting anything.

Progress events

Each operation has its own event:

Event Raised by
CopyFileProgressChanged CopyFileAsync
CopyDirectoryProgressChanged CopyDirectoryAsync and CopyDirectoriesAsync
DeleteFilesProgressChanged DeleteFilesAsync
DeleteDirectoriesProgressChanged DeleteDirectoriesAsync

Progress notifications use ProgressEventArgs:

Property Type Description
TotalSize Long Total bytes represented by the operation.
HandledSize Long Bytes copied or deleted so far.
CurrentPath String Current file path, or Nothing when no single path applies.
ProcessedItems Long Number of files completely processed.
TotalItems Long Total number of planned files.
PercentCompleted Integer Calculated value from 0 through 100.

Byte progress is preferred when TotalSize is greater than zero. Item progress is used for zero-byte operations. An empty operation is reported as complete.

Progress is throttled during file streaming to avoid raising an event for every buffer. A final completion notification is still sent.

Windows Forms example

When an operation is started from the UI thread, the event uses the captured synchronization context, so controls can normally be updated directly:

AddHandler manager.CopyFileProgressChanged,
    Sub(sender, e)
        ProgressBar1.Value = e.PercentCompleted
        StatusLabel.Text = If(e.CurrentPath, "Preparing...")
    End Sub

Await manager.CopyFileAsync(sourceFile, destinationFile, cancellationToken)

If no synchronization context exists, notifications may run on a thread-pool thread.

Public types

Type Purpose
FileManager Executes asynchronous copy and deletion operations.
CopyDirectoryInfo Maps one source directory to one destination directory.
DeleteDirectoryInfo Describes a directory and whether its root should be deleted.
ProgressEventArgs Supplies immutable byte, item and path progress information.

FileManager API

Member Description
CopyFileAsync(source, destination, cancellationToken) Copies one file and overwrites the destination.
CopyDirectoryAsync(copyInfo, totalSize, handledSize, cancellationToken) Copies one directory and returns the copied byte count.
CopyDirectoriesAsync(directories, cancellationToken) Copies multiple directory mappings as one progress operation.
DeleteFilesAsync(files, cancellationToken) Deletes distinct files.
DeleteDirectoriesAsync(directories, cancellationToken) Deletes directory contents and optionally their roots.
DeleteDirectoryContentAsync(directory, exceptDirectories, exceptFiles, cancellationToken) Clears one root while preserving selected content.

Path and traversal behavior

  • Paths are converted to normalized absolute paths.
  • Comparisons are case-insensitive on Windows and case-sensitive on other supported operating systems.
  • A file cannot be copied onto itself.
  • A directory destination cannot equal or be located inside its own source.
  • Reparse points are skipped during recursive directory enumeration.
  • Inaccessible entries cause an exception; they are not silently ignored.
  • The service copies file content but does not explicitly preserve file attributes, timestamps or access-control entries.

Failure and cancellation behavior

Operations are not transactional. If an exception or cancellation occurs after work has started:

  • a copied destination file may be partial;
  • some destination directories may already exist;
  • some requested files or directories may already have been deleted;
  • previously completed items are not restored automatically.

Applications that require all-or-nothing behavior should create their own staging, rollback or backup strategy.

License

This package is licensed under the MIT License.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net8.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
3.0.0 89 8/8/2026
2.0.0 89 8/7/2026
1.0.0 108 8/3/2026

Changed FileManager to a fully instance-based service. All operations and internal helpers now use instance members, providing a consistent API alongside instance-scoped progress events. Suppressed CA1822 for the project to preserve the intentional instance-based design.