You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#检测USB驱动器是否可移除及安全拔出方案咨询

检查USB驱动器是否正被使用或可安全拔出的可行方案

针对你遇到的USB文件写入未完成但弹窗提前提示、用户过早拔出的问题,以及对File.Open()+try-catch方案的不满,以下是几种更可靠的解决思路:

1. 强制刷新文件写入缓冲区,确保数据落地

在文件复制/写入操作完成后,必须强制将操作系统缓存中的数据刷入磁盘,避免依赖系统自动刷新导致的"写入完成"误判:

// 示例:复制文件后强制刷新到物理磁盘
using (var sourceStream = new FileStream(sourcePath, FileMode.Open, FileAccess.Read))
using (var destStream = new FileStream(destPath, FileMode.Create, FileAccess.Write))
{
    await sourceStream.CopyToAsync(destStream);
    destStream.Flush(true); // true表示跳过系统缓存,直接刷新到磁盘
}

// 额外验证:对比源文件与目标文件大小,确认写入完整
var sourceSize = new FileInfo(sourcePath).Length;
var destSize = new FileInfo(destPath).Length;
if (sourceSize != destSize)
{
    // 写入未完成,执行重试或提示逻辑
}

2. 使用Windows系统API检查设备可弹出状态

Windows提供了设备管理原生API,可直接查询USB驱动器的锁定状态,这是判断是否可安全弹出的最权威方式。核心调用CM_Request_Device_Eject函数:

[DllImport("setupapi.dll", SetLastError = true)]
private static extern bool CM_Request_Device_Eject(IntPtr hDevice, out IntPtr pRebootRequired);

// 示例:传入USB设备句柄,判断是否可安全弹出
public bool IsUsbSafeToEject(IntPtr deviceHandle)
{
    IntPtr rebootRequired;
    var result = CM_Request_Device_Eject(deviceHandle, out rebootRequired);
    // 返回true表示设备无占用,可安全弹出;返回false则设备被锁定
    return result;
}

注意:需先通过SetupDiGetClassDevs等API枚举设备,获取目标USB驱动器对应的设备句柄。

3. 监控文件系统写入稳定状态

通过FileSystemWatcher监控USB目录的文件变化,结合文件锁定状态判断写入是否真正完成:

var watcher = new FileSystemWatcher(@"D:\") // 替换为你的USB驱动器路径
{
    NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.Size,
    Filter = "*.*"
};

watcher.Changed += (sender, e) =>
{
    // 等待文件状态稳定(避免写入过程中多次触发变更)
    Task.Delay(1000).ContinueWith(_ =>
    {
        try
        {
            // 尝试独占打开文件,无异常则说明写入完成且无进程占用
            using (var stream = File.Open(e.FullPath, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
            {
                Console.WriteLine($"文件 {e.FullPath} 已完成写入");
            }
        }
        catch (IOException)
        {
            // 文件仍被占用,写入未完成
        }
    });
};

watcher.EnableRaisingEvents = true;

为什么File.Open()+try-catch不够可靠?

这种方式仅能判断文件是否被进程锁定,无法检测系统缓存中未落地的数据——即使文件能被打开,缓存中的数据可能还未写入磁盘,此时拔出U盘依然会导致文件损坏。

内容的提问来源于stack exchange,提问作者alexisL

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 02:06:27