C#を使用してアプリケーションを開発する際、ファイルの削除処理は非常に頻繁に発生する実装の一つです。

標準的な System.IO.File.Delete メソッドを使用すると、ファイルはストレージから即座に削除され、通常の手順では復元できなくなります。

ユーザーが誤って重要なデータを削除してしまうリスクを最小限に抑えるためには、直接削除するのではなく、Windowsの「ゴミ箱」に移動する仕組みを導入することが推奨されます。

本記事では、.NET環境において最も標準的かつ安全にファイルをゴミ箱へ移動させる方法である FileSystem.DeleteFile メソッドの実装手法について詳しく紹介します。

なぜ標準のFile.Deleteではなくゴミ箱を利用すべきか

プログラミングにおいて、データの削除は常に慎重に行われるべき破壊的な操作です。

System.IO.File.Delete メソッドは高速で効率的ですが、実行した瞬間にファイルシステムからエントリが削除されるため、ユーザーによる「元に戻す」操作を受け付けることができません。

一方で、ゴミ箱への移動を選択することで、ユーザーが必要に応じてファイルを自分で復元できる安全なバッファを提供できます。

デスクトップアプリケーションにおいて、ユーザーが操作するファイルを扱う場合は、この「安全な削除」がUX(ユーザーエクスペリエンス)の観点からも重要視されます。

特にビジネス向けのツールやファイル管理ソフトを開発する場合、誤操作によるデータ消失は深刻なトラブルを招く可能性があるため、ゴミ箱の活用は必須と言えるでしょう。

Microsoft.VisualBasic名前空間の活用

C#でゴミ箱への移動を実現する場合、最も一般的な方法は Microsoft.VisualBasic 名前空間に含まれる機能を利用することです。

「C#なのにVisualBasicの名前空間を使うのか」と疑問に感じる方もいるかもしれませんが、この名前空間にはWindowsプラットフォーム固有の便利なシェル機能が豊富に含まれています。

現在でも、.NETの最新バージョンにおいてWindows向けの機能を実装する際には、このライブラリを利用することが標準的なアプローチとして定着しています。

この名前空間内の Microsoft.VisualBasic.FileIO.FileSystem.DeleteFile メソッドを使用することで、複雑なWin32 APIを直接呼び出すことなくゴミ箱への移動が可能になります。

ライブラリの参照設定

最新の.NET(旧.NET Core/5以降)環境でこの機能を利用する場合、プロジェクトファイル(.csproj)の設定を確認する必要があります。

WindowsフォームアプリケーションやWPFアプリケーションであれば、デフォルトで参照が含まれていることが多いですが、コンソールアプリケーションなどの場合は明示的な追加が必要な場合があります。

具体的には、プロジェクトファイル内でWindowsプラットフォームをターゲットに指定(例: net8.0-windows)していることを確認してください。

また、コードの冒頭で名前空間をインポートすることで、簡潔な記述が可能になります。

C#
using Microsoft.VisualBasic.FileIO;

// これにより、FileSystemクラスを直接利用できるようになります

FileSystem.DeleteFileの基本的な使い方

ゴミ箱にファイルを移動させるための基本的な構文は非常にシンプルです。

FileSystem.DeleteFile メソッドには、いくつかのオーバーロードが存在しますが、ゴミ箱を利用する際には主に3つの引数を指定する形式を使用します。

第一引数には削除したいファイルのフルパスを指定し、第二引数には削除時のUI表示設定を、第三引数にはゴミ箱に送るかどうかの設定を指定します。

以下に、最も基本的な実装例を示します。

C#
string filePath = @"C:\temp\sample.txt";

// ファイルをゴミ箱に移動する
FileSystem.DeleteFile(
    filePath,
    UIOption.OnlyErrorDialogs,
    RecycleOption.SendToRecycleBin
);

このコードを実行すると、指定されたファイルは即座に削除されるのではなく、Windowsのゴミ箱へと安全に移動されます。

引数による動作の詳細設定

DeleteFile メソッドの引数を変更することで、削除時の挙動を柔軟にカスタマイズすることが可能です。

用途に応じて適切なオプションを選択できるよう、それぞれの列挙型の意味を理解しておくことが重要です。

UIOption(ユーザーインターフェースの設定)

UIOption は、削除処理中にWindows標準の進行状況ダイアログや確認メッセージを表示するかどうかを制御します。

定数名説明
UIOption.OnlyErrorDialogsエラーが発生した場合のみダイアログを表示します。通常の削除時は何も表示しません。
UIOption.AllDialogs進行状況ダイアログを表示し、ユーザーに削除の確認を求めるメッセージボックスを表示します。

サイレントにゴミ箱へ移動させたい場合は OnlyErrorDialogs を選択し、エクスプローラーのような挙動を期待する場合は AllDialogs を使用します。

RecycleOption(ゴミ箱の使用設定)

RecycleOption は、このメソッドの核となる設定であり、ファイルを完全に抹消するかゴミ箱に送るかを決定します。

定数名説明
RecycleOption.SendToRecycleBinファイルをゴミ箱に移動します。ユーザーによる復元が可能です。
RecycleOption.DeletePermanentlyゴミ箱を経由せず、完全に削除します。File.Deleteと同じ挙動になります。

本記事の目的である「安全な削除」を実現するためには、必ず RecycleOption.SendToRecycleBin を指定してください。

ディレクトリ(フォルダ)をゴミ箱に移動する方法

ファイル単位ではなく、フォルダごとゴミ箱に移動させたい場合もあるでしょう。

その場合は、DeleteFile ではなく DeleteDirectory メソッドを使用します。

引数の構成は DeleteFile とほぼ同じですが、ディレクトリ特有のオプションが追加されています。

C#
string dirPath = @"C:\temp\sample_folder";

// ディレクトリを中身ごとゴミ箱に移動する
FileSystem.DeleteDirectory(
    dirPath,
    UIOption.AllDialogs,
    RecycleOption.SendToRecycleBin,
    UICancelOption.ThrowException
);

ここで登場する UICancelOption は、ユーザーがダイアログで「キャンセル」をクリックした場合の動作を指定するものです。

ThrowException を指定すると、キャンセル時に例外が発生するため、プログラム側でその後の処理を中断するなどの制御が可能になります。

実践的な実装例とエラーハンドリング

実務で利用するコードでは、ファイルが存在しない場合や権限が不足している場合に備えて、適切なエラーハンドリングを行う必要があります。

特にファイルが他のプロセスによってロックされている場合、削除処理は失敗して例外をスローします。

以下に、より堅牢な実装例を示します。

C#
using System;
using Microsoft.VisualBasic.FileIO;

public class FileOperationHelper
{
    public static void SafeDelete(string path)
    {
        try
        {
            if (System.IO.File.Exists(path))
            {
                Console.WriteLine($"{path} をゴミ箱に移動しています...");
                
                FileSystem.DeleteFile(
                    path,
                    UIOption.OnlyErrorDialogs,
                    RecycleOption.SendToRecycleBin,
                    UICancelOption.DoNothing
                );

                Console.WriteLine("削除が完了しました。");
            }
            else
            {
                Console.WriteLine("指定されたファイルが見つかりません。");
            }
        }
        catch (OperationCanceledException)
        {
            Console.WriteLine("ユーザーによって削除がキャンセルされました。");
        }
        catch (UnauthorizedAccessException)
        {
            Console.WriteLine("アクセス権限がありません。");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"エラーが発生しました: {ex.Message}");
        }
    }
}
実行結果
C:\temp\sample.txt をゴミ箱に移動しています...
削除が完了しました。

このように例外処理を組み込むことで、予期せぬアプリケーションの強制終了を防ぎ、ユーザーに対して適切なフィードバックを提供できます。

Windows以外のプラットフォームでの注意点

今回紹介している Microsoft.VisualBasic.FileIO は、基本的にWindows OSの機能をラップしたものです。

.NETはクロスプラットフォーム(Windows, Linux, macOS)に対応していますが、ゴミ箱の仕組みはOSごとに大きく異なるため、このメソッドはWindows以外では期待通りに動作しない可能性があります。

LinuxやmacOSで同様の「ゴミ箱」機能を実現するには、それぞれのOSが定めるゴミ箱用ディレクトリ(例: ~/.local/share/Trash)へファイルを移動する独自のロジックを実装する必要があります。

ターゲットがWindowsデスクトップアプリケーションであれば問題ありませんが、マルチプラットフォーム展開を考えている場合は、OS判定処理(RuntimeInformation.IsOSPlatform)を組み合わせて実装を切り分けるのがベストプラクティスです。

パフォーマンスに関する考察

ゴミ箱への移動は、単なるファイルのリンクの書き換えだけでなく、WindowsシェルのAPIを介するため、File.Delete に比べるとわずかにオーバーヘッドが発生します。

一時ファイルを数千個単位で高速に一括削除するようなバックエンド処理では、ゴミ箱への移動は適していません。

そのようなケースでは、従来の File.Delete を使用し、ユーザーが直接目にする「ドキュメント」や「設定ファイル」などの削除に限定して FileSystem.DeleteFile を活用するのが効率的です。

用途に応じて、「スピード重視の完全削除」か「安全性重視のゴミ箱移動」かを使い分ける判断がプロフェッショナルなエンジニアには求められます。

まとめ

C#でファイルを安全に削除するためには、Microsoft.VisualBasic.FileIO.FileSystem.DeleteFile を活用してゴミ箱へ移動させる方法が非常に有効です。

このメソッドを利用することで、万が一の誤操作時にもユーザーが自力で復元できる仕組みを簡単に提供できます。

実装の際は UIOptionRecycleOption を適切に設定し、必要に応じて例外処理を組み合わせることで、より信頼性の高いアプリケーションを構築できるでしょう。

Windowsプラットフォームにおけるファイル操作の標準的な作法として、ぜひこの手法をマスターしてお役立てください。