强制删除正在被其他进程使用的文件

5
我正在开发一个应用程序,需要删除一个文件,无论它是否被其他进程使用。
考虑以下代码片段。
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();
        }
    }
}

我正在删除被同一进程使用的文件。是否可能删除该文件?

谢谢, Amit Shah


但是文件正在使用中,为什么要删除它呢? - Mitch Wheat
2
重复 - https://dev59.com/RHVD5IYBdhLWcg3wXaid? - Petar Minchev
从你的问题中并不清楚你是否想要关闭一个已经打开的文件。如果是这种情况,可以使用Ed Swangren的建议。 - Petar Minchev
删除流关闭之前的文件有什么目的?如果你找到了在关闭流之前删除文件的方法,那么在文件被删除后,流对你有什么用处呢? - Chris Taylor
以上代码仅用于显示错误。我有一个托管的swf文件,它使用wav文件。我有一个后端应用程序,可以修改与swf使用的相同的波形文件。我希望更新后的波形在swf中呈现。唯一的方法是替换现有文件。 - Amit Shah
3个回答

8
是的,这是一个已知的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() 也会执行完全相同的操作。 - Mo Patel

0
我正在删除被同一进程使用的文件。 先关闭文件就可以了...

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接