有效地检测应用程序是否正在使用文件

本文关键字:文件 检测 应用程序 是否 有效地 | 更新日期: 2023-09-27 18:19:36

我昨天做了这个问题,但目前没有得到任何答案。

无论如何,我的新方法是创建一个小程序,让它一直在后台运行,并定期检查是否有临时文件没有被应用程序使用。

这次我将在系统临时文件夹中创建一个文件夹来存储打开的文件。

这是代码:

private const uint GENERIC_WRITE = 0x40000000;
private const uint OPEN_EXISTING = 3;
private static void Main()
{
    while (true)
    {
        CleanFiles(Path.GetTempPath() + "MyTempFolder//");
        Thread.Sleep(10000);
    }
}
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern SafeFileHandle CreateFile(string lpFileName, UInt32 dwDesiredAccess, UInt32 dwShareMode,
                                                IntPtr pSecurityAttributes, UInt32 dwCreationDisposition,
                                                UInt32 dwFlagsAndAttributes, IntPtr hTemplateFile);
private static void CleanFiles(string folder)
{
    if (Directory.Exists(folder))
    {
        var directory = new DirectoryInfo(folder);
        try
        {
            foreach (var file in directory.GetFiles())
                if (!IsFileInUse(file.FullName))
                {
                    Thread.Sleep(5000);
                    file.Delete();
                }
        }
        catch (IOException)
        {
        }
    }
}

private static bool IsFileInUse(string filePath)
{
    if (!File.Exists(filePath))
        return false;
    SafeHandle handleValue = null;
    try
    {
        handleValue = CreateFile(filePath, GENERIC_WRITE, 0, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
        return handleValue.IsInvalid;
    }
    finally
    {
        if (handleValue != null)
        {
            handleValue.Close();
            handleValue.Dispose();
        }
    }
}

但这有一个问题:

它可以很好地处理docx和pdf(与Foxit阅读器)文件。

txt文件被删除,即使它们仍然被记事本使用,但我可以接受这一点,因为文件的内容在记事本中仍然可见。

真正的问题是像Windows照片查看器这样的应用程序。即使WPV仍在使用图像,图像也会被删除,但这一次图像从WPV中消失,屏幕上显示消息Loading。。。

我需要一种方法来真正检测应用程序是否仍在使用文件。

有效地检测应用程序是否正在使用文件

你就是做不到。

"文件被另一个程序使用"并没有什么黑魔法。这只是意味着其他程序已经打开了文件的句柄

有些应用程序会一直打开句柄,而其他应用程序(如记事本)则不会:当您打开文件时,记事本会打开文件的句柄,通过打开的句柄读取整个文件,关闭句柄,并向用户显示读取的字节。

如果你删除了文件,好吧,没有打开的句柄,记事本也不会注意到你删除了这个文件。

请看看这个SO问题

在这里,您可以通过应用程序名称检查应用程序(更简单的方法):

 Process[] pname = Process.GetProcessesByName("notepad");
 if (pname.Length == 0)
    MessageBox.Show("nothing");
 else
    MessageBox.Show("run");