下面是一个回收站处理的源码,但是那个获取回收站内容大小的函数没获取到值,请大虾们修改该类库,让该函数能够获取到回收站内容大小值。
QuerySizeRecycleBin(out long RBsize, out long RBNumItems)
1 using System; 2 using System.Collections.Generic; 3 using System.Text; 4 using System.IO; 5 using System.Threading; 6 using System.Runtime.InteropServices; 7 8 namespace RecycleBinMgr 9 { 10 namespace RecycleBinInfoHelper 11 { 12 [Flags] 13 public enum SHERB : uint 14 { 15 /* #define SHERB_NOCONFIRMATION 0x00000001 16 #define SHERB_NOPROGRESSUI 0x00000002 17 #define SHERB_NOSOUND 0x00000004*/ 18 19 /// <summary> 20 /// 不选择其他的三个项,不可与其他选项同时使用 21 /// </summary> 22 SHERB_GENNERAL = 0x00000000, 23 24 /// <summary> 25 /// 不显示确认删除的对话框 26 /// </summary> 27 SHERB_NOCONFIRMATION = 0x00000001, 28 /// <summary> 29 /// 不显示删除过程的进度条 30 /// </summary> 31 SHERB_NOPROGRESSUI = 0x00000002, 32 /// <summary> 33 /// 当删除完成时,不播放声音 34 /// </summary> 35 SHERB_NOSOUND = 0x00000004 36 37 }; 38 39 40 [StructLayout(LayoutKind.Explicit, Pack = 2)] 41 public struct SHQUERYRBINFO 42 { 43 //这个结构必须是用户显示编写偏移量才能准确获取数值 44 [FieldOffset(0)] 45 public int cbsize; 46 [FieldOffset(4)] 47 public long i64Size; 48 [FieldOffset(12)] 49 public long i64NumItems; 50 }; 51 52 public static class LibWarp 53 { 54 55 56 57 /// <summary> 58 /// 清空指定磁盘或目录的回收站的内容 59 /// </summary> 60 /// <param name="hwnd">对话框的句柄,通常应当设为NULL</param> 61 /// <param name="RootPath">磁盘路径,如果要清空所有磁盘,设置为null值或空值</param> 62 /// <param name="flags">SHERB枚举的值,一个或多个的组合</param> 63 /// <returns>成功返回0,S_OK值,失败为其他的OLE定义值</returns> 64 65 [DllImport("shell32.dll", CharSet = CharSet.Unicode, CallingConvention = 66 CallingConvention.StdCall)] 67 // [PreserveSig()] 68 public static extern uint 69 SHEmptyRecycleBinW( 70 IntPtr hwnd, 71 [In()] 72 [MarshalAs(UnmanagedType.LPWStr,SizeConst=260)] 73 string rootpath, 74 SHERB flags); 75 76 77 /// <summary> 78 ///API的SHQueryRecycleBinW 79 /// </summary> 80 [DllImport("shell32.dll", CharSet = CharSet.Unicode)] 81 public static extern uint SHQueryRecycleBinW( 82 [In()] 83 [MarshalAs(UnmanagedType.LPWStr,SizeConst=260)] 84 string RootPath 85 , ref SHQUERYRBINFO queyRBInfo); 86 87 }; 88 89 internal class _rbState 90 { 91 private IntPtr _hwnd; 92 private string _rootpath; 93 private SHERB _sherb; 94 private uint _rv; 95 internal _rbState(IntPtr hwnd, string rootpath, SHERB sherb) 96 { 97 this._hwnd = hwnd; 98 this._rootpath = rootpath; 99 this._sherb = sherb; 100 _rv = 0; 101 } 102 internal _rbState() 103 { 104 this._hwnd = IntPtr.Zero; 105 this._rootpath = null; 106 this._sherb = SHERB.SHERB_GENNERAL; 107 } 108 internal IntPtr Hwnd 109 { 110 get 111 { 112 return this._hwnd; 113 } 114 set 115 { 116 this._hwnd = value; 117 } 118 } 119 internal string Rootpath 120 { 121 get 122 { 123 return this._rootpath; 124 } 125 set 126 { 127 this._rootpath = value; 128 } 129 } 130 internal SHERB Sherb 131 { 132 get 133 { 134 return this._sherb; 135 } 136 set 137 { 138 this._sherb = value; 139 } 140 } 141 internal uint Revalue 142 { 143 set 144 { 145 this._rv = value; 146 } 147 get 148 { 149 return this._rv; 150 } 151 } 152 internal void 153 ReSetState(IntPtr hwnd, string rootpath, SHERB sherb) 154 { 155 this._hwnd = hwnd; 156 this._rootpath = rootpath; 157 this._sherb = sherb; 158 159 160 } 161 162 163 164 }; 165 166 //回收站相关 167 //解决不能删除的原因:调用线程必须是STA线程 168 169 /// <summary> 170 /// 查询回收站的大小和个数,以及从回收站清空文件 171 /// 这个类是对SHQueryRecycleBinW函数和SHEmptyRecycleBinW函数的封装 172 /// 调用EmptyRecycleBin方法,删除回收站的内容;调用QuerySizeRecycleBin,查询 173 /// 回收站的大小和文件的个数 174 /// </summary> 175 public class RecycleBinInfo 176 { 177 /* 178 * 注意:多个对象实例(不同引用的),如果调用EmptyRecycleBin方法的任何重载, 179 * 它们的调用是顺序的,(就好象在单个线程里的调用是一样的)*/ 180 //-------------- 181 182 /*这个类的实现是,在内部创建一个线程调用wrokThread,这样做的原因是将对象完全封装起来, 183 * 因为并不能确定用户调用SHEmptyRecycleBin函数的线程模式是否为STA模式, 184 * SHEmptyRecycleBin函数必须在STA模式下才能正确调用,这个类采用一个折衷的方法来实现。 185 * 当调用EmptyRecycleBin方法之一的重载,都在内部创建一个线程,将线程模式设置为STAThread 186 * 187 */ 188 189 190 private void wrokThread(object state) 191 { 192 //state对象转换_rbState 193 lock (state) 194 { /*同步*/ 195 _rbState temp = (_rbState)state; 196 197 temp.Revalue = LibWarp.SHEmptyRecycleBinW( 198 temp.Hwnd, 199 temp.Rootpath, 200 temp.Sherb); 201 ((_rbState)state).Revalue = temp.Revalue; 202 203 } 204 this.ewh.Set(); 205 } 206 /// <summary> 207 /// 实例化一个RecycleBinInfo对象 208 /// </summary> 209 public RecycleBinInfo() 210 { 211 /*初始化对象*/ 212 this.ewh = new EventWaitHandle( 213 false, EventResetMode.AutoReset, 214 Guid.NewGuid().ToString()); 215 } 216 /// <summary> 217 /// 清空回收站,这个方法同SHEmptyRecycleBin函数一样调用 218 /// </summary> 219 /// <param name="hwnd">在调用SHEmptyRecycleBin期间,指向用来显示的对话框的父窗体的句柄 220 /// 可为NULL值 221 /// </param> 222 /// <param name="rootpath">最大长度为260个字符的字符串,指定磁盘根目录或文件夹目录,可为null,则清空整个回收站的内容</param> 223 /// <param name="dwFlags">SHERB枚举,可组合使用</param> 224 /// <returns>成功返回0,否则为OLE定义的错误值</returns> 225 public uint EmptyRecycleBin(IntPtr hwnd, string rootpath, SHERB dwFlags) 226 { 227 228 _rbState rvs = new _rbState(hwnd, rootpath, dwFlags); 229 rvs.Revalue = 0x8000FFFF; 230 231 232 long size, items; 233 234 this.QuerySizeRecycleBin(out size, out items); 235 if (size == 0) 236 return rvs.Revalue; 237 238 lock (rvs) 239 { 240 Thread t = new Thread( 241 new ParameterizedThreadStart(this.wrokThread)); 242 t.SetApartmentState(ApartmentState.STA); 243 t.Start(rvs); 244 } 245 /* Console.WriteLine("aaa");测试了,同一个对象实例,依次调用EmptyRecycleBin 246 的任何一个重载,其顺序总是:先被调用的,总是先运行,后面的--排队等待 247 * 这样的原因是ewh是AUTO的,set之后,同样命名的对象就不会wait了 248 */ 249 this.ewh.WaitOne(); 250 this.ewh.Reset(); 251 return rvs.Revalue; 252 } 253 254 /// <summary> 255 /// 清空整个回收站的内容 256 /// </summary> 257 /// <returns>成功返回0,否则为OLE定义的错误值</returns> 258 public uint EmptyRecycleBin() 259 { 260 _rbState rvs = new _rbState(); 261 rvs.Revalue = 0x8000FFFF; 262 263 long size, items; 264 265 this.QuerySizeRecycleBin(out size, out items); 266 if (size == 0) 267 return rvs.Revalue; 268 269 lock (rvs) 270 { 271 Thread t = new Thread( 272 new ParameterizedThreadStart(this.wrokThread)); 273 t.SetApartmentState(ApartmentState.STA);//将线程设置为STA 274 t.Start(rvs); 275 276 } 277 this.ewh.WaitOne(); 278 this.ewh.Reset(); 279 return rvs.Revalue; 280 } 281 /// <summary> 282 /// 查询整个回收站的大小和被删除的文件的个数 283 /// </summary> 284 /// <param name="RBsize">大小,按字节计算</param> 285 /// <param name="RBNumItems">个数</param> 286 /// <returns>如果函数成功返回0,错误为其他OLE定义的错误值</returns> 287 public uint QuerySizeRecycleBin(out long RBsize, out long RBNumItems) 288 { 289 //整个 ,字节,两个出参都为-1表示异常 290 RBsize = -1; 291 RBNumItems = -1; 292 SHQUERYRBINFO rbinfo = new SHQUERYRBINFO(); 293 rbinfo.cbsize = Marshal.SizeOf(rbinfo); 294 295 uint rv = LibWarp.SHQueryRecycleBinW(null, ref rbinfo); 296 RBsize = rbinfo.i64Size; 297 RBNumItems = rbinfo.i64NumItems; 298 299 return rv; 300 } 301 /// <summary> 302 /// 查询指定目录或磁盘下被删除到回收站的文件的总大小和个数。 303 /// 如果设置为null,效果跟 QuerySizeRecycleBin(out long RBsize,out long RBNumItems )一样 304 /// </summary> 305 /// <param name="rootpath">指定的磁盘和目录</param> 306 /// <param name="RBsize">总大小,按字节计算</param> 307 /// <param name="RBNumItems">文件的个数</param> 308 /// <returns>如果函数成功返回0,错误为其他OLE定义的错误值</returns> 309 public uint QuerySizeRecycleBin(string rootpath, out long RBsize, out long RBNumItems) 310 { 311 312 RBsize = -1; 313 RBNumItems = -1; 314 SHQUERYRBINFO rbinfo = new SHQUERYRBINFO(); 315 rbinfo.cbsize = Marshal.SizeOf(rbinfo); 316 317 uint rv = LibWarp.SHQueryRecycleBinW(rootpath, ref rbinfo); 318 RBsize = rbinfo.i64Size; 319 RBNumItems = rbinfo.i64NumItems; 320 return rv; 321 } 322 #region 字段 323 private EventWaitHandle ewh; 324 /// <summary> 325 /// HRSULT的E_UNEXCEPTED值 326 /// </summary> 327 public static readonly uint E_UNEXCEPTED = 0x8000FFFF; 328 #endregion 字段 329 }; 330 } 331 }
为了修改给定的C#类库,并让函数QuerySizeRecycleBin能够获取回收站的内容大小,你需要确保SHQUERYRBINFO结构正确填充,并正确调用SHQueryRecycleBinW函数。以下是修改后的类库代码,以便实现这一功能:
csharp
Copy code
using System;
using System.Runtime.InteropServices;
namespace RecycleBinMgr
{
namespace RecycleBinInfoHelper
{
// ...(其余代码保持不变)
public class RecycleBinInfo
{
// ...(其余代码保持不变)
/// <summary>
/// 查询回收站的大小和文件个数。
/// </summary>
/// <param name="RBsize">总大小(以字节为单位)。</param>
/// <param name="RBNumItems">删除的项目数量。</param>
/// <returns>如果函数成功,返回0;否则返回OLE定义的错误值。</returns>
public uint QuerySizeRecycleBin(out long RBsize, out long RBNumItems)
{
// 将初始值设置为-1,以便在查询失败时表示错误。
RBsize = -1;
RBNumItems = -1;
SHQUERYRBINFO rbinfo = new SHQUERYRBINFO();
rbinfo.cbsize = Marshal.SizeOf(rbinfo);
// 使用null作为根路径调用SHQueryRecycleBinW函数,以获取回收站的信息。
uint rv = LibWarp.SHQueryRecycleBinW(null, ref rbinfo);
// 检查函数调用是否成功。
if (rv == 0)
{
// 函数调用成功,从rbinfo结构中获取大小和文件数量。
RBsize = rbinfo.i64Size;
RBNumItems = rbinfo.i64NumItems;
}
return rv;
}
// ...(其余代码保持不变)
}
}
}
通过这些修改,QuerySizeRecycleBin方法现在应该能够成功获取回收站的内容大小和文件数量。