user1537004
user1537004

Reputation:

Effectively detect if a file is being used by an application

I did this question yesterday but at the moment I didn't get any answer.

Anyway, my new approach is to create an small program to run all the time in background and periodically check if there are temp files not being used by an application.

This time I will create a folder inside the system temp folder to store the opened files.

This is the code:

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();
        }
    }
}

But there are an issue with this:

It's working fine with docx and pdf (with Foxit Reader) files.

txt files are deleted even if they are still being used by Notepad but I can live with this because the content of the files is still visible in Notepad.

The real problem is with applications like Windows Photo Viewer. The images are deleted even if they are still being used by WPV but this time the images disappear from WPV and on its screen appears the message Loading...

I need a way to really detect if a file is still being used by an application.

Upvotes: 1

Views: 647

Answers (2)

ken2k
ken2k

Reputation: 48975

You just can't.

There is no black magic with the "file is used by another program". This simply means that the other program has opened a handle to the file.

Some applications keep handles opened the whole time, others (such as notepad) don't: when you open the file, notepad opens a handle to the file, reads the whole file thanks to the opened handle, closes the handle, and displays the read bytes to the user.

If you delete the file, fine, there is no opened handle and notepad won't every noticed you deleted the file.

Upvotes: 1

Philip Gullick
Philip Gullick

Reputation: 995

Please take a look into this SO question

Here you can check the application by the application name(easier way):

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

Upvotes: 0

Related Questions