如何了解哪个进程删除了硬盘上的文件

Posted

技术标签:

【中文标题】如何了解哪个进程删除了硬盘上的文件【英文标题】:How is it possible to understand which process deletes a file on the hard drive 【发布时间】:2019-01-10 06:24:46 【问题描述】:

我有以下问题。我开发了一个将设置保存在首选项文件中的应用程序。在某个时间点,正在删除其中一个文件。无法从我的应用程序中删除此文件。

在Windows下如何知道是哪个进程删除了硬盘上的文件?

编辑: 问题很少出现。我正在寻找一个可以作为服务或其他东西运行的程序,这样我就可以为应用程序打一个补丁,如果有人删除文件并写入它已经完成的进程,我可以在运行时监控它。

【问题讨论】:

作为管理员,您可以启用文件访问审核并设置文件审核,或使用Process Monitor。 @eryksun 看到我的编辑。 或者,您可以通过保持文件打开而不共享删除权限来防止文件被删除。 我必须弄清楚是谁在试图删除它,这不是解决问题的方法,这是解决方法。 配置审计是侵入性最小的方法,因为内核已经被检测为支持审计事件的创建。其他选项基本上类似于 Process Monitor,使用特定过滤器运行以查找文件的访问权限。这要么需要一个挂钩到内核的驱动程序来监视给定的文件系统 I/O 请求 (IRP),要么需要某种系统范围的 API 挂钩(例如 Detours 之类的东西)。您可以查看API Monitor 的工作原理,看看是否可以集成。 【参考方案1】:

可能正在使用进程监视器,带有此参数«操作: SetDispositionInformationFile, 结果:成功,详情:“Delete:True”» 在您的路径上。

更多细节:here 和 here

【讨论】:

真正的答案! SetDispositionInformationEx & SetDispositionInformationFile 都是关于文件删除的!【参考方案2】:

如果您对 C# 解决方案没意见,您可以使用 Microsoft.Diagnostics.Tracing.TraceEvent nuget 包。它是 ETW (Event Tracing for Windows) 事件的包装器。

Windows 内核会跟踪所有内容,您可以实时获取这些跟踪信息。但有时很难将它们关联起来。

在您的情况下,您正在处理文件删除事件,但不幸的是,这些事件没有附加任何进程信息,因此我使用了另一个事件。下面是一些示例代码:

using System;
using Microsoft.Diagnostics.Tracing.Parsers;
using Microsoft.Diagnostics.Tracing.Session;

namespace TraceDeletes

    class Program
    
        static void Main(string[] args)
        
            if (TraceEventSession.IsElevated() != true)
            
                Console.WriteLine("To turn on ETW events you need to be Administrator, please run from an Admin process.");
                return;
            

            // we're watching that particular file
            string filePath = @"C:\temp\New Text Document.txt";
            ulong fileKey = 0;
            string processName = null;
            using (var session = new TraceEventSession("whatever"))
            
                // handle console CTRL+C gracefully
                Console.CancelKeyPress += (sender, e) => session.Stop();

                // we filter on events we need
                session.EnableKernelProvider(
                    KernelTraceEventParser.Keywords.DiskFileIO |
                    KernelTraceEventParser.Keywords.FileIOInit);

                // this event has no process information
                session.Source.Kernel.FileIOFileDelete += data =>
                
                    if (data.FileKey == fileKey)
                    
                        Console.WriteLine(data.FileName + " was deleted by " + processName);
                        fileKey = 0;
                        processName = null;
                    
                ;

                // this event has process information (id, name)
                // it happens before delete, of course
                // we remember the FileKey
                session.Source.Kernel.FileIOQueryInfo += data =>
                
                    if (string.Compare(data.FileName, filePath, StringComparison.OrdinalIgnoreCase) == 0)
                    
                        fileKey = data.FileKey;
                        processName = data.ProcessName;
                    
                ;

                // runs forever, press CTRL+C to stop
                session.Source.Process();
            
        
    

如果您创建“C:\temp\New Text Document.txt”文件并使用 Windows 资源管理器将其删除,您应该会看到:

C:\temp\New Text Document.txt was deleted by explorer

注意:ETW 当然可以使用其他语言,但是使用这个 .NET 库会更容易。

【讨论】:

我的应用程序是基于 Java 的。 @MBaev - 这不是问题。上面的程序将从 Windows 机器上运行的任何应用程序中捕获文件删除。你只需要适应你的文件路径。【参考方案3】:

来自 Microsoft 的 Sysinternals 应该能够为您提供帮助。

https://docs.microsoft.com/en-us/sysinternals/downloads/

查看文件和磁盘实用程序。有一些实用程序可以向您显示哪个进程访问/修改了给定文件。

【讨论】:

【参考方案4】:

您可以开发服务并使用 FileSystemWatcher 并监视已删除事件。 FileSystemWatcher.Deleted Event

【讨论】:

以上是关于如何了解哪个进程删除了硬盘上的文件的主要内容,如果未能解决你的问题,请参考以下文章

讲清楚,说明白!进程管理

监控正在删除的文件

关于硬盘数据

在虚拟机里怎么选择硬盘类型

如何恢复已删除的文件?

pm2到底是啥呢?你真的了解吗