SmbSharp 1.0.13

There is a newer version of this package available.
See the version list below for details.
dotnet add package SmbSharp --version 1.0.13
                    
NuGet\Install-Package SmbSharp -Version 1.0.13
                    
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="SmbSharp" Version="1.0.13" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SmbSharp" Version="1.0.13" />
                    
Directory.Packages.props
<PackageReference Include="SmbSharp" />
                    
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 SmbSharp --version 1.0.13
                    
#r "nuget: SmbSharp, 1.0.13"
                    
#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 SmbSharp@1.0.13
                    
#: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=SmbSharp&version=1.0.13
                    
Install as a Cake Addin
#tool nuget:?package=SmbSharp&version=1.0.13
                    
Install as a Cake Tool

SmbSharp

A cross-platform .NET library for SMB/CIFS file operations. Works seamlessly on Windows using native UNC paths and on Linux using smbclient.

NuGet License: MIT

Features

  • Cross-Platform: Windows (native UNC) and Linux (smbclient)
  • Dual Authentication: Kerberos and username/password authentication
  • Stream-Based API: Efficient, memory-friendly file operations
  • Async/Await: Full async support with cancellation tokens
  • Dependency Injection: Built-in ASP.NET Core DI integration
  • Health Checks: Monitor SMB share connectivity with ASP.NET Core health checks
  • Multiple .NET Versions: Supports .NET Core 3.1, .NET 6, .NET 8, and .NET 10
  • Secure: Passwords passed via environment variables, not command-line arguments
  • Well-Documented: Comprehensive XML documentation with IntelliSense support

Installation

NuGet Package Manager

Install-Package SmbSharp

.NET CLI

dotnet add package SmbSharp

Package Reference

<PackageReference Include="SmbSharp" Version="1.0.0" />

Platform Requirements

Windows

  • No additional requirements - uses native UNC path support

Linux

  • Requires smbclient to be installed:
    # Debian/Ubuntu
    sudo apt-get install smbclient
    
    # RHEL/CentOS
    sudo yum install samba-client
    
    # Alpine Linux
    apk add samba-client
    

Docker

Add smbclient to your Dockerfile:

Debian/Ubuntu-based images:

FROM mcr.microsoft.com/dotnet/aspnet:8.0
RUN apt-get update && apt-get install -y smbclient && rm -rf /var/lib/apt/lists/*

Alpine-based images:

FROM mcr.microsoft.com/dotnet/aspnet:8.0-alpine
RUN apk add --no-cache samba-client

RHEL/CentOS-based images:

FROM mcr.microsoft.com/dotnet/aspnet:8.0-rhel
RUN yum install -y samba-client && yum clean all

Quick Start

Kerberos Authentication (Default)
// Program.cs
builder.Services.AddSmbSharp();

// Usage in a controller/service
public class MyService
{
    private readonly IFileHandler _fileHandler;

    public MyService(IFileHandler fileHandler)
    {
        _fileHandler = fileHandler;
    }

    public async Task<IEnumerable<string>> GetFiles()
    {
        return await _fileHandler.EnumerateFilesAsync("//server/share/folder");
    }
}
Username/Password Authentication
// Program.cs - Direct credentials
builder.Services.AddSmbSharp("username", "password", "DOMAIN");

// Or using configuration
builder.Services.AddSmbSharp(options =>
{
    options.UseKerberos = false;
    options.Username = "username";
    options.Password = "password";
    options.Domain = "DOMAIN";
});

// Or from appsettings.json
builder.Services.AddSmbSharp(options =>
{
    builder.Configuration.GetSection("SmbSharp").Bind(options);
});

Direct Instantiation (Without Dependency Injection)

using SmbSharp.Business;

// Kerberos authentication
var handler = FileHandler.Create();

// Username/password authentication
var handler = FileHandler.Create("username", "password", "DOMAIN");

// Usage
var files = await handler.EnumerateFilesAsync("//server/share/folder");

Path Format

SmbSharp accepts SMB paths in multiple formats for flexibility:

// Forward slashes (recommended for cross-platform code)
await fileHandler.EnumerateFilesAsync("//server/share/folder");

// Backslashes (Windows UNC format)
await fileHandler.EnumerateFilesAsync("\\\\server\\share\\folder");

// Mixed (automatically normalized)
await fileHandler.EnumerateFilesAsync("//server/share\\folder");

Note: All path formats are automatically normalized internally. Forward slashes (/) are recommended for cross-platform compatibility, but backslashes (\) are fully supported for Windows-style UNC paths.

Usage Examples

List Files in a Directory

var files = await fileHandler.EnumerateFilesAsync("//server/share/folder");
foreach (var file in files)
{
    Console.WriteLine(file);
}

Read a File

await using var stream = await fileHandler.ReadFileAsync("//server/share/folder", "file.txt");
using var reader = new StreamReader(stream);
var content = await reader.ReadToEndAsync();

Write a File (String Content)

await fileHandler.WriteFileAsync("//server/share/folder/file.txt", "Hello, World!");

Write a File (Stream)

await using var fileStream = File.OpenRead("local-file.txt");
await fileHandler.WriteFileAsync("//server/share/folder/file.txt", fileStream);

Write with Different Modes

// Overwrite existing file (default)
await fileHandler.WriteFileAsync("//server/share/file.txt", stream, FileWriteMode.Overwrite);

// Create only if doesn't exist (fails if exists)
await fileHandler.WriteFileAsync("//server/share/file.txt", stream, FileWriteMode.CreateNew);

// Append to existing file
await fileHandler.WriteFileAsync("//server/share/file.txt", stream, FileWriteMode.Append);

Delete a File

await fileHandler.DeleteFileAsync("//server/share/folder/file.txt");

Move a File

await fileHandler.MoveFileAsync(
    "//server/share/folder/old.txt",
    "//server/share/folder/new.txt"
);

Note: On Linux, move operations download and re-upload the file, which can be slow for large files.

Create a Directory

await fileHandler.CreateDirectoryAsync("//server/share/newfolder");

Test Connectivity

bool canConnect = await fileHandler.CanConnectAsync("//server/share");
if (canConnect)
{
    Console.WriteLine("Successfully connected!");
}

Using Cancellation Tokens

using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30));

try
{
    var files = await fileHandler.EnumerateFilesAsync(
        "//server/share/folder",
        cts.Token
    );
}
catch (OperationCanceledException)
{
    Console.WriteLine("Operation timed out!");
}

Authentication

Kerberos Authentication

On Linux, ensure you have a valid Kerberos ticket before using the library:

kinit username@DOMAIN.COM

Verify your ticket:

klist

Username/Password Authentication

Credentials are securely passed to smbclient via environment variables, not command-line arguments, preventing exposure in process listings.

Health Checks

SmbSharp includes built-in health check support for ASP.NET Core applications to monitor SMB share connectivity.

Single Share Health Check

// Program.cs
builder.Services.AddSmbSharp();
builder.Services.AddHealthChecks()
    .AddSmbShareCheck("//server/share/folder");

Named Health Check with Options

builder.Services.AddHealthChecks()
    .AddSmbShareCheck(
        directoryPath: "//server/share/folder",
        name: "primary_smb_share",
        failureStatus: HealthStatus.Degraded,
        tags: new[] { "smb", "storage" },
        timeout: TimeSpan.FromSeconds(10)
    );

Multiple Share Health Checks

var shares = new Dictionary<string, string>
{
    { "primary", "//server1/share1" },
    { "backup", "//server2/share2" },
    { "archive", "//server3/share3" }
};

builder.Services.AddHealthChecks()
    .AddSmbShareChecks(shares, tags: new[] { "smb" });

Health Check Endpoint

// Program.cs
var app = builder.Build();

app.MapHealthChecks("/health");
// Or with detailed response
app.MapHealthChecks("/health", new HealthCheckOptions
{
    ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
});

Example Response

Healthy:

{
  "status": "Healthy",
  "results": {
    "smb_share": {
      "status": "Healthy",
      "description": "Successfully connected to SMB share: //server/share/folder"
    }
  }
}

Unhealthy:

{
  "status": "Unhealthy",
  "results": {
    "smb_share": {
      "status": "Unhealthy",
      "description": "Unable to connect to SMB share: //server/share/folder"
    }
  }
}

Health Check Logging

When health checks fail, error logs are automatically generated to help troubleshoot connectivity issues:

// Enable logging in your appsettings.json
{
  "Logging": {
    "LogLevel": {
      "SmbSharp.HealthChecks.SmbShareHealthCheck": "Error"
    }
  }
}

Example error log:

[Error] Health check failed: Unable to connect to SMB share: //server/share/folder
[Error] Health check failed for SMB share //server/share/folder: Access denied

API Reference

IFileHandler Interface

Method Description
EnumerateFilesAsync(directory, cancellationToken) Lists all files in a directory
ReadFileAsync(directory, fileName, cancellationToken) Opens a file for reading as a stream
WriteFileAsync(filePath, content, cancellationToken) Writes a string to a file
WriteFileAsync(filePath, stream, cancellationToken) Writes a stream to a file
WriteFileAsync(filePath, stream, writeMode, cancellationToken) Writes a stream with specific write mode
DeleteFileAsync(filePath, cancellationToken) Deletes a file
MoveFileAsync(sourcePath, destPath, cancellationToken) Moves a file
CreateDirectoryAsync(directoryPath, cancellationToken) Creates a directory
CanConnectAsync(directoryPath, cancellationToken) Tests connectivity to a share

FileWriteMode Enum

Value Description
Overwrite Creates a new file or overwrites existing (default)
CreateNew Creates only if file doesn't exist (throws if exists)
Append Appends to existing file or creates new

Error Handling

The library throws specific exceptions for different error scenarios:

try
{
    await fileHandler.ReadFileAsync("//server/share", "file.txt");
}
catch (FileNotFoundException ex)
{
    // File or path doesn't exist
}
catch (UnauthorizedAccessException ex)
{
    // Access denied or authentication failed
}
catch (DirectoryNotFoundException ex)
{
    // Network path not found
}
catch (IOException ex)
{
    // Other SMB/network errors
}
catch (PlatformNotSupportedException ex)
{
    // Running on unsupported platform (not Windows/Linux)
}

Debugging

To troubleshoot authentication issues or see exactly what commands are being sent to smbclient, enable debug logging:

// In Program.cs or appsettings.json
builder.Logging.SetMinimumLevel(LogLevel.Debug);

// Or configure specific loggers
builder.Logging.AddFilter("SmbSharp.Infrastructure.ProcessWrapper", LogLevel.Debug);

Example debug output:

Executing process: smbclient //server/share -U "username" -c "ls folder/*"
Environment variables set: PASSWD
Process exited with code: 0

Note: Passwords are never logged. Only environment variable names (like PASSWD) are shown, not their values.

Performance Considerations

Windows

  • Uses native UNC paths - very efficient
  • All operations are direct file system calls
  • Move operations are atomic and instant (metadata-only)

Linux

  • Uses smbclient subprocess - some overhead
  • Read operations download to temp file (auto-cleaned)
  • Write operations upload from temp file
  • Move operations = download + upload + delete (can be slow for large files)
  • For large files, consider alternative approaches or be aware of 2x disk space + network transfer

Security Features

  • ✅ Passwords passed via environment variables (not visible in process listings)
  • ✅ Command injection protection (input escaping)
  • ✅ Comprehensive input validation
  • ✅ Path traversal protection

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Support

Acknowledgments

Built with ❤️ for the .NET community.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  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 is compatible.  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. 
.NET Core netcoreapp3.1 is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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
1.1.2 87 2/10/2026
1.1.1 80 2/10/2026 1.1.1 is deprecated because it has critical bugs.
1.1.0 65 2/7/2026 1.1.0 is deprecated because it has critical bugs.
1.0.16 114 2/4/2026
1.0.15 58 2/4/2026
1.0.14 67 2/4/2026
1.0.13 54 2/4/2026
1.0.12 60 2/4/2026
1.0.11 59 2/3/2026
1.0.10 52 2/3/2026
1.0.9 54 2/3/2026
1.0.8 55 2/3/2026
1.0.7 52 2/3/2026
1.0.6 49 2/3/2026
1.0.5 60 2/3/2026
1.0.4 56 2/2/2026
1.0.3 49 2/2/2026
1.0.2 51 2/2/2026
1.0.1 59 1/30/2026
1.0.0 60 1/29/2026

v1.0.13: Add FileHandler.Create() factory methods for easy instantiation without dependency injection. Now you can use FileHandler.Create() or FileHandler.Create(username, password, domain) without setting up DI.