首页 新闻 会员 周边 捐助

C#的回收站处理的源码修改

0
悬赏园豆:50 [已解决问题] 解决于 2023-08-01 20:44

下面是一个回收站处理的源码,但是那个获取回收站内容大小的函数没获取到值,请大虾们修改该类库,让该函数能够获取到回收站内容大小值。

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#
lzhdim的主页 lzhdim | 小虾三级 | 园豆:650
提问于:2023-08-01 18:58
< >
分享
最佳答案
0

为了修改给定的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方法现在应该能够成功获取回收站的内容大小和文件数量。

收获园豆:50
Technologyforgood | 大侠五级 |园豆:7775 | 2023-08-01 19:55
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册