调用 SHEmptyRecycleBin 前必须提权,需关闭 ClickOnce、添加 app.manifest 并设 requestedExecutionLevel 为 requireAdministrator;dwFlags 应用位标志组合而非布尔值;仅支持 shell 接口操作,不可直接删 $Recycle.Bin;x64 系统需匹配平台架构与字符串编码。

调用 SHEmptyRecycleBin 前必须提权
Windows 默认禁止普通权限进程清空回收站,直接调用会静默失败或返回 E_ACCESSDENIED。这不是 C# 代码写错了,是 UAC 拦住了——哪怕你用管理员身份运行程序,也得显式声明需要提升权限。
实操建议:
- 在项目属性 → 应用程序 → “启用 ClickOnce 安全设置”必须关闭;否则无法触发提权
- 添加
app.manifest文件,并把requestedExecutionLevel改成requireAdministrator - 不要试图用
Process.Start("cmd", "/c echo. > ...")绕过——回收站路径受用户 SID 隔离,跨用户无效
SHEmptyRecycleBin 的参数含义和常见误传
这个 API 是 shell32.dll 导出函数,C# 中需用 [DllImport] 声明。最容易错的是第二个参数 dwFlags:它不是布尔值,而是位标志组合,比如清空所有驱动器要传 0x00000001(SHERB_NOCONFIRMATION)+ 0x00000004(SHERB_NOPROGRESSUI),而不是简单传 true。
常见错误现象:传了 1 却只清了 C: 盘,因为没加 SHERB_NOSOUND 或其他标志导致行为被截断。
实操建议:
- 用命名常量代替裸数字,例如定义
const uint SHERB_NOCONFIRMATION = 0x00000001; - 如果只要清当前用户回收站,第一个参数
pszRootPath可传null;若指定盘符(如"C:\\"),末尾双反斜杠不能少 - 返回值为
HRESULT,检查是否等于0才算成功,别只看有没有抛异常
为什么 Microsoft.VisualBasic.FileIO.FileSystem 不行
有人试过用 VB.NET 的 FileSystem.DeleteDirectory 或 Recycle 方法去“删回收站目录”,结果发现根本删不掉,或者删了又自动恢复——因为回收站不是普通文件夹,它是 shell namespace 的虚拟视图,底层由 $Recycle.Bin 和元数据文件共同维护,直接操作磁盘路径会破坏一致性。
实操建议:
- 别碰
C:\$Recycle.Bin\<sid></sid>这类路径,即使有权限也不该手动删 - 不要用
Directory.Delete或File.Delete去处理回收站里的文件路径(它们显示的是原始路径,不是实际存储位置) - 如果你只是想“清空前确认有哪些文件”,得用
SHGetKnownFolderIDList+IEnumIDList枚举,不是靠遍历目录
64 位系统下调用失败的隐蔽原因
在 x64 系统上,如果 C# 项目目标平台设为 x86,调用 SHEmptyRecycleBin 可能返回 E_INVALIDARG 或直接崩溃。这不是 API 本身问题,而是 shell32.dll 在 WoW64 下对某些标志的校验更严格,尤其当传入的字符串编码或指针长度不匹配时。
实操建议:
- 项目属性 → 生成 → “目标平台”优先选
AnyCPU并勾选 “首选 32 位”(仅限 .NET Framework);.NET Core/5+ 则建议明确设为x64或x86,避免混合 - 确保
pszRootPath是 UTF-16 字符串,且用MarshalAs(UnmanagedType.LPWStr)标记 - 调用前后不要切换线程上下文(比如从 UI 线程跳进 Task.Run),shell API 对 COM 上下文敏感
真正麻烦的不是调用那行代码,而是权限声明、标志组合、平台匹配这三处稍一松动就失效。很多人卡在“明明写了 DllImport 却没反应”,其实早就挂在 manifest 或平台设置上了。


















