NonSoft

ごみ箱の中のファイルやフォルダの一覧
を取得するサンプル(C#.NET)


 サンプル(ソース/コード)
<このサンプルの概要>
ごみ箱の中のファイルやフォルダの一覧を取得するサンプル(C#.NET)です。
ShellClassで一覧を取得し、INFO(またはINFO2)ファイルから削除元ファイル名や削除日時を取得します。

※WindowsVista(Windows7/Windows8)以降にはINFO(またはINFO2)ファイルが無いので、
※INFO(またはINFO2)ファイルを使用しないサンプルも用意しました。

参照設定で「Microsoft Shell Controls And Automation」というCOMを追加しています。

<INFO(またはINFO2)ファイルについての補足>
ごみ箱の中にはINFO(またはINFO2)という隠しファイルがあり、削除元のPATHを保存しています。
このファイルは「ごみ箱を空にする(B)」という操作を行なうまで拡大を続けますので、
年に1回ぐらいは「ごみ箱を空にする(B)」を実行した方が良いと思います。
INFO(またはINFO2)には以下の項目が保存してあります。
・ヘッダー部分
  (1)バージョン(INFO=1、INFO2=4or5...)
  (2)ファイル数(...)
  (3)ファイルINDEX(...)
  (4)INFOファイルのファイルやフォルダ部分のサイズ(280or800)
  (5)ゴミ箱のディスクサイズ(...)
・ファイルやフォルダごとの部分
 (1)元の場所PATH(ショート、SHIFT-JIS)
 (2)ファイルやフォルダINDEX
 (3)ドライブ番号(C=2、D=3...)
 (4)削除日時
 (5)ファイルやフォルダのディスクサイズ
 (6)元の場所PATH(ロング、UNICODE)

VB.NET版はこちら「ごみ箱の中のファイルやフォルダの一覧を取得するサンプル(VB.NET)」です。

関連情報:
古いごみ削除ツール(NonRccDel)
スタートアップやタスクに登録してごみ箱の中の古い(指定日数を経過)ファイルやフォルダを削除

★標準モジュール(Module1.cs)
using System.IO;
using Shell32;

class Class1
{
    /// <summary>
    /// ごみ箱の中のファイルやフォルダの一覧(配列)を取得
    /// </summary>
    /// <returns>ごみ箱の中の一覧(配列</returns>
    /// <remarks></remarks>
    public static List<List<String>> GetRecyclerList()
    {
        List<List<String>> rtnAry = new List<List<String>>();
        Stream sr = null;
        BinaryReader br = null;
        try
        {
            // 処理中のINFOファイルPATH
            String inf = "";

            // INFOファイル読込用
            Byte[] dat = new Byte[0] { };

            // Shell32の宣言
            ShellClass shl = new ShellClass();

            // ゴミ箱フォルダの情報取得
            Folder fol = shl.NameSpace(10);

            foreach (FolderItem FolderItem in fol.Items())
            {
                // ゴミ箱内のファイルやフォルダ毎の処理
                String rpt = FolderItem.Path;
                String rfn = Path.GetFileNameWithoutExtension(rpt);
                String rif = Path.GetDirectoryName(rpt) + @"\INFO2";
                if (File.Exists(rif) == false)
                {
                    rif = Path.GetDirectoryName(rpt) + @"\INFO";
                }
                // INFOファイルが存在しなければ終了
                if (File.Exists(rif) == false)
                {
                    continue;
                }

                // 処理中のINFOチェック
                if (inf != rif)
                {
                    // 処理中のINFOファイルのPATH設定
                    inf = rif;
                    // INFOファイル読込
                    sr = File.Open(inf, FileMode.Open, FileAccess.Read);
                    br = new BinaryReader(sr);
                    Array.Resize<Byte>(ref dat, (int)sr.Length);
                    dat = br.ReadBytes((int)sr.Length);
                    if (br != null) br.Close();
                    if (sr != null) sr.Close();
                }

                // INFOファイルのフォーマットが不正の時は終了
                if (dat.Length < 20)
                {
                    continue;
                }

                // INFOファイル解析(ヘッダー部分)
                // バージョン(INFO=1、INFO2=4or5...)
                int p = 0;
                uint version =
                    (uint)dat[p + 3] * 256 * 256 * 256 +
                    (uint)dat[p + 2] * 256 * 256 +
                    (uint)dat[p + 1] * 256 +
                    (uint)dat[p + 0];
                // ファイル数(...)
                p += 4;
                uint pathCount =
                    (uint)dat[p + 3] * 256 * 256 * 256 +
                    (uint)dat[p + 2] * 256 * 256 +
                    (uint)dat[p + 1] * 256 +
                    (uint)dat[p + 0];
                // ファイルINDEX(...)
                p += 4;
                uint nextIndex =
                    (uint)dat[p + 3] * 256 * 256 * 256 +
                    (uint)dat[p + 2] * 256 * 256 +
                    (uint)dat[p + 1] * 256 +
                    (uint)dat[p + 0];
                // INFOファイルのファイルやフォルダ部分のサイズ(280or800)
                p += 4;
                uint recSize =
                    (uint)dat[p + 3] * 256 * 256 * 256 +
                    (uint)dat[p + 2] * 256 * 256 +
                    (uint)dat[p + 1] * 256 +
                    (uint)dat[p + 0];
                // ゴミ箱のディスクサイズ(...)
                p += 4;
                uint allDiskSize =
                    (uint)dat[p + 3] * 256 * 256 * 256 +
                    (uint)dat[p + 2] * 256 * 256 +
                    (uint)dat[p + 1] * 256 +
                    (uint)dat[p + 0];
                p += 4;

                // INFOファイル(ファイルやフォルダ部分)解析
                int pd = p;
                for (int hs = (int)(dat.Length - recSize); hs >= pd; hs -= (int)recSize)
                {
                    p = hs;

                    // 元の場所PATH(ショート、SHIFT-JIS)
                    Byte[] dat2 = new Byte[260];
                    Array.Copy(dat, p, dat2, 0, dat2.Length);
                    String orgPath =
                        System.Text.Encoding.GetEncoding("SHIFT-JIS").GetString(dat2);
                    if (orgPath.IndexOf('\0') == 0)
                    {
                        orgPath = inf.Substring(0, 1) + orgPath.Substring(1);
                    }
                    if (orgPath.IndexOf('\0') > 0)
                    {
                        orgPath = orgPath.Substring(0, orgPath.IndexOf('\0'));
                    }
                    p += dat2.Length;

                    // ファイルやフォルダINDEX
                    uint index =
                        (uint)dat[p + 3] * 256 * 256 * 256 +
                        (uint)dat[p + 2] * 256 * 256 +
                        (uint)dat[p + 1] * 256 +
                        (uint)dat[p + 0];
                    p += 4;

                    // ドライブ番号(C=2、D=3...)
                    uint driveNumber =
                        (uint)dat[p + 3] * 256 * 256 * 256 +
                        (uint)dat[p + 2] * 256 * 256 +
                        (uint)dat[p + 1] * 256 +
                        (uint)dat[p + 0];
                    p += 4;

                    // 削除日時
                    long deletedDt =
                        (long)dat[p + 7] * 256 * 256 * 256 * 256 * 256 * 256 * 256 +
                        (long)dat[p + 6] * 256 * 256 * 256 * 256 * 256 * 256 +
                        (long)dat[p + 5] * 256 * 256 * 256 * 256 * 256 +
                        (long)dat[p + 4] * 256 * 256 * 256 * 256 +
                        (long)dat[p + 3] * 256 * 256 * 256 +
                        (long)dat[p + 2] * 256 * 256 +
                        (long)dat[p + 1] * 256 +
                        (long)dat[p + 0];
                    p += 8;

                    // ファイルやフォルダのディスクサイズ
                    uint pathDiskSize =
                        (uint)dat[p + 3] * 256 * 256 * 256 +
                        (uint)dat[p + 2] * 256 * 256 +
                        (uint)dat[p + 1] * 256 +
                        (uint)dat[p + 0];
                    p += 4;

                    // 元の場所PATH(ロング、UNICODE)
                    if (recSize - (p - hs) > 0)
                    {
                        Array.Resize<Byte>(ref dat2, (int)recSize - (p - hs));
                        Array.Copy(dat, p, dat2, 0, dat2.Length);
                        orgPath = System.Text.Encoding.GetEncoding("UNICODE").GetString(dat2);
                        if (orgPath.IndexOf('\0') == 0)
                        {
                            orgPath = inf.Substring(0, 1) + orgPath.Substring(1);
                        }
                        if (orgPath.IndexOf('\0') > 0)
                        {
                            orgPath = orgPath.Substring(0, orgPath.IndexOf('\0'));
                        }
                    }

                    // INFOファイル内のINDEXとごみ箱内のファイル名が一致するかチェック
                    String rfn2 = "D" + inf.Substring(0, 1) + index;
                    if (rfn.ToLower() == rfn2.ToLower())
                    {
                        // 一致した場合は、元の場所PATHを取得
                        List<String> ary = new List<String>();
                        ary.Add(rpt);
                        ary.Add(orgPath);
                        rtnAry.Add(ary);
                        break;
                    }
                }
            }

        }
        catch (Exception ex)
        {
            throw ex;
        }
        finally
        {
            if (br != null) br.Close();
            if (sr != null) sr.Close();
        }
        return rtnAry;
    }

    /// <summary>
    /// ごみ箱の中のファイルやフォルダの一覧(配列)を取得
    /// </summary>
    /// <returns>ごみ箱の中の一覧(配列</returns>
    /// <remarks>INFOファイルが無いOSの場合(WindowsVista(Win7/Win8)以降)</remarks>
    public static List<List<String>> GetRecyclerList2()
    {
        List<List<String>> rtnAry = new List<List<String>>();

        // Shell32の宣言
        ShellClass shl = new ShellClass();

        // ゴミ箱フォルダの情報取得
        Folder fol = shl.NameSpace(10);

        foreach (FolderItem FolderItem in fol.Items())
        {
            // ゴミ箱内のファイルやフォルダ毎の処理

            // ごみ箱内のPATHを取得
            String rpt = FolderItem.Path;

            // 元の場所のPATHを取得
            String opt = fol.GetDetailsOf(FolderItem, 1);
            if (opt.Substring(opt.Length - 1, 1) != "\\") opt = opt + "\\";
            opt = opt + fol.GetDetailsOf(FolderItem, 0);
            if (Path.GetExtension(opt) != Path.GetExtension(rpt))
            {
                opt = opt + Path.GetExtension(rpt);
            }
            List<String> ary = new List<String>();
            ary.Add(rpt);
            ary.Add(opt);
            rtnAry.Add(ary);

            // 名前
            System.Diagnostics.Debug.WriteLine("名前:" + fol.GetDetailsOf(FolderItem, 0));

            // 元の場所
            System.Diagnostics.Debug.WriteLine("元の場所:" + fol.GetDetailsOf(FolderItem, 1));

            // 削除した日
            System.Diagnostics.Debug.WriteLine("削除した日:" + fol.GetDetailsOf(FolderItem, 2));

            // サイズ
            System.Diagnostics.Debug.WriteLine("サイズ:" + fol.GetDetailsOf(FolderItem, 3));

            // 種類
            System.Diagnostics.Debug.WriteLine("種類:" + fol.GetDetailsOf(FolderItem, 4));

            // 更新日時
            System.Diagnostics.Debug.WriteLine("更新日時:" + fol.GetDetailsOf(FolderItem, 5));

            // 作成日時
            System.Diagnostics.Debug.WriteLine("作成日時:" + fol.GetDetailsOf(FolderItem, 6));
        }

        return rtnAry;
    }
}

★フォームモジュール(Form1.cs)
    private void button1_Click(object sender, EventArgs e)
    {
        // フォルダ内のファイルやフォルダの一覧(配列)取得
        List<List<String>> flist = Class1.GetRecyclerList();

        // INFOファイルが無いOSの場合(WindowsVista以降(Win7/Win8))はGetRecyclerList2
        //List<List<String>> flist = Class1.GetRecyclerList2();

        // ファイルやフォルダの一覧(配列)を出力
        for (int i = 0; i < flist.Count; i++)
        {
            System.Diagnostics.Debug.WriteLine(flist[i][0] + "," + flist[i][1]);
        }
    }