|
|||||
<このサンプルの概要> ごみ箱の中のファイルやフォルダの一覧を取得するサンプル(VB.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) C#.NET版はこちら「ごみ箱の中のファイルやフォルダの一覧を取得するサンプル(C#.NET)」です。 関連情報: 古いごみ削除ツール(NonRccDel) スタートアップやタスクに登録してごみ箱の中の古い(指定日数を経過)ファイルやフォルダを削除 ★標準モジュール(Module1.vb) Imports System.IO Imports Shell32 Module Module1 ''' <summary> ''' ごみ箱の中のファイルやフォルダの一覧(配列)を取得 ''' </summary> ''' <returns>ごみ箱の中の一覧(配列</returns> ''' <remarks></remarks> Public Function GetRecyclerList() As String(,) Dim rtnAry As String(,) = New String(1, -1) {} Dim sr As Stream = Nothing Dim br As BinaryReader = Nothing Try ' 処理中のINFOファイルPATH Dim inf As String = "" ' INFOファイル読込用 Dim dat() As Byte = New Byte(-1) {} ' Shell32の宣言 Dim shl As New ShellClass() ' ゴミ箱フォルダの情報取得 Dim fol As Folder = shl.NameSpace(10) For Each FolderItem As FolderItem In fol.Items() ' ゴミ箱内のファイルやフォルダ毎の処理 Dim sumi As Boolean = False Dim rpt As String = FolderItem.Path Dim rfn As String = Path.GetFileNameWithoutExtension(rpt) Dim rif As String = Path.GetDirectoryName(rpt) & "\INFO2" If File.Exists(rif) = False Then rif = Path.GetDirectoryName(rpt) & "\INFO" End If ' INFOファイルが存在しなければ終了 If File.Exists(rif) = False Then Continue For End If ' 処理中のINFOチェック If inf <> rif Then ' 処理中のINFOファイルのPATH設定 inf = rif ' INFOファイル読込 sr = File.Open(inf, FileMode.Open, FileAccess.Read) br = New BinaryReader(sr) ReDim dat(sr.Length - 1) dat = br.ReadBytes(sr.Length) If br Is Nothing = False Then br.Close() If sr Is Nothing = False Then sr.Close() End If ' INFOファイルのフォーマットが不正の時は終了 If dat.Length < 20 Then Continue For End If ' INFOファイル解析(ヘッダー部分) ' バージョン(INFO=1、INFO2=4or5...) Dim p As Integer = 0 Dim version As UInteger = _ CType(dat(p + 3), UInteger) * 256 * 256 * 256 + _ CType(dat(p + 2), UInteger) * 256 * 256 + _ CType(dat(p + 1), UInteger) * 256 + _ CType(dat(p + 0), UInteger) ' ファイル数(...) p += 4 Dim pathCount As UInteger = _ CType(dat(p + 3), UInteger) * 256 * 256 * 256 + _ CType(dat(p + 2), UInteger) * 256 * 256 + _ CType(dat(p + 1), UInteger) * 256 + _ CType(dat(p + 0), UInteger) ' ファイルINDEX(...) p += 4 Dim nextIndex As UInteger = _ CType(dat(p + 3), UInteger) * 256 * 256 * 256 + _ CType(dat(p + 2), UInteger) * 256 * 256 + _ CType(dat(p + 1), UInteger) * 256 + _ CType(dat(p + 0), UInteger) ' INFOファイルのファイルやフォルダ部分のサイズ(280or800) p += 4 Dim recSize As UInteger = _ CType(dat(p + 3), UInteger) * 256 * 256 * 256 + _ CType(dat(p + 2), UInteger) * 256 * 256 + _ CType(dat(p + 1), UInteger) * 256 + _ CType(dat(p + 0), UInteger) ' ゴミ箱のディスクサイズ(...) p += 4 Dim allDiskSize As UInteger = _ CType(dat(p + 3), UInteger) * 256 * 256 * 256 + _ CType(dat(p + 2), UInteger) * 256 * 256 + _ CType(dat(p + 1), UInteger) * 256 + _ CType(dat(p + 0), UInteger) p += 4 ' INFOファイル(ファイルやフォルダ部分)解析 Dim pd As Integer = p 'For hs As Integer = pd To dat.Length - recSize Step recSize For hs As Integer = dat.Length - recSize To pd Step -recSize p = hs ' 元の場所PATH(ショート、SHIFT-JIS) Dim dat2 As Byte() = New Byte(259) {} Array.Copy(dat, p, dat2, 0, dat2.Length) Dim orgPath As String = _ System.Text.Encoding.GetEncoding("SHIFT-JIS").GetString(dat2) If orgPath.IndexOf(Chr(0)) = 0 Then orgPath = inf.Substring(0, 1) & orgPath.Substring(1) End If If orgPath.IndexOf(Chr(0)) > 0 Then orgPath = orgPath.Substring(0, orgPath.IndexOf(Chr(0))) End If p += dat2.Length ' ファイルやフォルダINDEX Dim index As UInteger = _ CType(dat(p + 3), UInteger) * 256 * 256 * 256 + _ CType(dat(p + 2), UInteger) * 256 * 256 + _ CType(dat(p + 1), UInteger) * 256 + _ CType(dat(p + 0), UInteger) p += 4 ' ドライブ番号(C=2、D=3...) Dim driveNumber As UInteger = _ CType(dat(p + 3), UInteger) * 256 * 256 * 256 + _ CType(dat(p + 2), UInteger) * 256 * 256 + _ CType(dat(p + 1), UInteger) * 256 + _ CType(dat(p + 0), UInteger) p += 4 ' 削除日時 Dim deletedDt As Long = _ CType(dat(p + 7), Long) * 256 * 256 * 256 * 256 * 256 * 256 * 256 + _ CType(dat(p + 6), Long) * 256 * 256 * 256 * 256 * 256 * 256 + _ CType(dat(p + 5), Long) * 256 * 256 * 256 * 256 * 256 + _ CType(dat(p + 4), Long) * 256 * 256 * 256 * 256 + _ CType(dat(p + 3), Long) * 256 * 256 * 256 + _ CType(dat(p + 2), Long) * 256 * 256 + _ CType(dat(p + 1), Long) * 256 + _ CType(dat(p + 0), Long) p += 8 ' ファイルやフォルダのディスクサイズ Dim pathDiskSize As UInteger = _ CType(dat(p + 3), UInteger) * 256 * 256 * 256 + _ CType(dat(p + 2), UInteger) * 256 * 256 + _ CType(dat(p + 1), UInteger) * 256 + _ CType(dat(p + 0), UInteger) p += 4 ' 元の場所PATH(ロング、UNICODE) If recSize - (p - hs) > 0 Then ReDim dat2(recSize - (p - hs) - 1) Array.Copy(dat, p, dat2, 0, dat2.Length) orgPath = System.Text.Encoding.GetEncoding("UNICODE").GetString(dat2) If orgPath.IndexOf(Chr(0)) = 0 Then orgPath = inf.Substring(0, 1) & orgPath.Substring(1) End If If orgPath.IndexOf(Chr(0)) > 0 Then orgPath = orgPath.Substring(0, orgPath.IndexOf(Chr(0))) End If End If ' INFOファイル内のINDEXとごみ箱内のファイル名が一致するかチェック Dim rfn2 As String = "D" & inf.Substring(0, 1) & index If rfn.ToLower = rfn2.ToLower Then ' 一致した場合は、元の場所PATHを取得 ReDim Preserve rtnAry(1, UBound(rtnAry, 2) + 1) rtnAry(0, UBound(rtnAry, 2)) = rpt rtnAry(1, UBound(rtnAry, 2)) = orgPath Exit For End If Next Next Catch ex As Exception Throw ex Finally If br Is Nothing = False Then br.Close() If sr Is Nothing = False Then sr.Close() End Try Return rtnAry End Function ''' <summary> ''' ごみ箱の中のファイルやフォルダの一覧(配列)を取得 ''' </summary> ''' <returns>ごみ箱の中の一覧(配列</returns> ''' <remarks>INFOファイルが無いOSの場合(WindowsVista(Win7/Win8)以降)</remarks> Public Function GetRecyclerList2() As String(,) Dim rtnAry As String(,) = New String(1, -1) {} ' Shell32の宣言 Dim shl As New ShellClass() ' ゴミ箱フォルダの情報取得 Dim fol As Folder = shl.NameSpace(10) For Each FolderItem As FolderItem In fol.Items() ' ゴミ箱内のファイルやフォルダ毎の処理 ' ごみ箱内のPATHを取得 ReDim Preserve rtnAry(1, UBound(rtnAry, 2) + 1) Dim rpt As String = FolderItem.Path ' 元の場所のPATHを取得 Dim opt As String = fol.GetDetailsOf(FolderItem, 1) If opt.Substring(opt.Length - 1, 1) <> "\" Then opt = opt & "\" opt = opt & fol.GetDetailsOf(FolderItem, 0) If Path.GetExtension(opt) <> Path.GetExtension(rpt) Then opt = opt & Path.GetExtension(rpt) End If rtnAry(0, UBound(rtnAry, 2)) = rpt rtnAry(1, UBound(rtnAry, 2)) = opt ' 名前 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)) Next Return rtnAry End Function End Module ★フォームモジュール(Form1.vb) Private Sub Button1_Click( _ ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click ' フォルダ内のファイルやフォルダの一覧(配列)取得 Dim flist As String(,) = GetRecyclerList() ' INFOファイルが無いOSの場合(WindowsVista以降(Win7/Win8))はGetRecyclerList2 'Dim flist As String(,) = GetRecyclerList2() ' ファイルやフォルダの一覧(配列)を出力 For i As Integer = 0 To UBound(flist, 2) System.Diagnostics.Debug.WriteLine(flist(0, i) & "," & flist(1, i)) Next End Sub |