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

|
<このサンプルの概要>
ごみ箱の中のファイルやフォルダの一覧を取得するサンプルです。
ShellClassで一覧を取得し、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)
関連情報
古いごみ削除ツール(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
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()
' ファイルやフォルダの一覧(配列)を出力
For i As Integer = 0 To UBound(flist, 2)
System.Diagnostics.Debug.WriteLine(flist(0, i) & "," & flist(1, i))
Next
End Sub