1

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.

Community
  • 1
  • 1
  • 3
    Some programs will keep handles on the file after loading and some won't. Once the handle is gone the file is effectively not being used *at that moment*. There is no way to detect when a file will be needed again by a process that has already loaded the file. – Dustin Kingen Jun 24 '13 at 11:51
  • Thanks. I'm considering to run the cleaner only when the main application starts. But even in that case the user could have a file opened in a previous session. –  Jun 24 '13 at 11:55

2 Answers2

1

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.

ken2k
  • 48,145
  • 10
  • 116
  • 176
0

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");
Community
  • 1
  • 1
Philip Gullick
  • 995
  • 7
  • 22
  • That's a very good idea but, for example, as long as I understand, WPV is related with explorer.exe and it will be still be running. But let me try. –  Jun 24 '13 at 12:03
  • VPV uses "C:\\Program Files (x86)\\Windows Photo Viewer\\PhotoViewer.dll" –  Jun 24 '13 at 12:15
  • Now I get the message: Windows Photo Viewer can't open this picture because the picture is being edited in another program. –  Jun 24 '13 at 12:18
  • Unfortunately that is where you may hit the floor when applications conflict with this, as noted it isn't possible to work another way round. If you want to try another way then possibly look into reflection, however this is likely to bring the same outcome. The code above is the best way to go, but unfortunately if it is not suitable for your needs then you do not have many other options I'm afraid. – Philip Gullick Jun 24 '13 at 12:34
  • Thanks for your help. Your answer gave me some ideas I will try. –  Jun 24 '13 at 12:39