【问题标题】: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();
        }
    }
}

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

谢谢, 阿米特·沙阿

【问题讨论】:

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

标签: c# .net


【解决方案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。唯一的方法是替换现有文件。
    • 你认为这是“唯一的方法”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-06
    相关资源
    最近更新 更多