强制删除文件,即使它正在被其他进程使用

Posted

技术标签:

【中文标题】强制删除文件,即使它正在被其他进程使用【英文标题】:Deleting a file forcefully even though it is being used by the other process 【发布时间】:2011-03-20 10:34:06 【问题描述】:

我正在开发一个应用程序,它需要删除一个文件,无论它是否被其他进程使用

考虑下面的 sn-p 代码。

using System;
using System.IO;

namespace DotNet_Concepts.File_Operation

    class Deleting_File_Which_Is_In_Use
    
        static void Main(string[] args)
        
            StreamReader lclFileStream = null;
            string lclFileName=string.Empty;
            try
            
                lclFileName=@"E:\Visual Studio 2008 Projects\DotNet Concepts\DotNet Concepts\Local Files\Garbage.txt";
                if (File.Exists(lclFileName))
                
                    lclFileStream = new StreamReader(lclFileName);
                    if (lclFileStream != null)
                    
                        //Doing some operation
                    
                    //Deleting the file before closing the stream
                    File.Delete(lclFileName);
                
            
            catch (Exception ex)
            

                System.Diagnostics.Debug.WriteLine(ex.StackTrace);
            
            Console.ReadLine();
        
    

我正在删除同一进程使用的文件。是否可以删除文件

谢谢, 阿米特·沙阿

【问题讨论】:

但文件正在使用中。那为什么要删除呢? 重复 - ***.com/questions/1040/… ? 从你的问题中不清楚,如果你想关闭你打开的文件。如果是这种情况,请使用 Ed Swangren 的建议。 在关闭流之前删除文件的目的是什么?如果为了争论你找到了在关闭流之前删除文件的方法,那么在文件被删除之后流对你有什么用? 以上代码仅用于显示错误。我有一个使用 wav 文件的托管 swf 文件。我有一个后端应用程序,它修改了 swf 正在使用的同一个波形文件。我希望在 swf 中呈现更新后的 wave。而唯一的办法就是替换现有文件 【参考方案1】:

是的,这是一个已知的 Windows 安全问题,称为“句柄回收攻击”。技术上可以遍历未记录的内核句柄表,在拥有该句柄的进程中注入代码并调用 CloseHandle() 来关闭文件句柄。很难利用,你需要管理员权限才能做到这一点。如果你有这个权利,更好的方法来搞砸流程。

结果更像是一种拒绝服务攻击,一种随机破坏机器而无法查明它是如何发生的攻击。该进程不知道文件句柄已关闭,它没有关闭它,只是继续写入句柄。写入的数据落入比特桶。在大多数非托管程序中,忽略 WriteFile() 的返回值是相当标准的。

直到进程打开另一个句柄来写入,比如说,一个数据库。句柄被回收,它可以获得相同的句柄值。现在该进程正在写入正常的数据库数据,并与本应放入现已关闭的文件中的数据混合在一起。

当有人试图从该数据库中读回数据时,就会引起欢闹。或者任何其他资源被破坏,它是随机的。不过你有点蒙蔽了,没有人会知道是你的程序破坏了机器。

【讨论】:

【参考方案2】:
using System.Collections;
using System.Diagnostics;
using System.Management;

if (File.Exists(@"D:\New folder\Test0001.wav"))

    GC.Collect();
    GC.WaitForPendingFinalizers();
    FileInfo f = new FileInfo(@"D:\New folder\Test0001.wav");
    f.Delete();

【讨论】:

这不是“强制的”。如果文件正在使用中,代码将抛出异常。此外,OP 使用的 File.Delete(path) 将与您使用 FileInfo.Delete() 完成的操作完全相同。【参考方案3】:

我正在删除同一进程使用的文件

先关闭文件...

【讨论】:

如果您的文件被其他进程使用,您可以尝试 CreateRemoteThread() 关闭句柄。 以上代码仅用于显示错误。我有一个使用 wav 文件的托管 swf 文件。我有一个后端应用程序,它修改了 swf 正在使用的同一个波形文件。我希望在 swf 中呈现更新后的 wave。唯一的方法是替换现有文件。 你认为这是“唯一的方法”。

以上是关于强制删除文件,即使它正在被其他进程使用的主要内容,如果未能解决你的问题,请参考以下文章

我正在从视图中删除 with check 选项约束,但它没有被强制执行

强制解锁文件占用

易语言如何强制删除正在运行的程序?

谁知道怎么用bat打开一个exe并且强制删除这个被打开的exe文件啊。

winform c#删除图片提示文件被占用

如何强制删除或恢复SQLServer正在使用的数据库