0

I wanted to test if a particular file is already open before trying to launch it, so I came up with this:

    public void LaunchErrorLog()
    {
        var logFile = ConfigurationManager.AppSettings["Log"];
        if (IsLogOpen(logFile))
            return; //figure out how to give focus to other app later

        var psi = new ProcessStartInfo(logFile);
        psi.WindowStyle = ProcessWindowStyle.Maximized;

        Process.Start(psi);   
    }

    private bool IsLogOpen(string p)
    {
        try
        {
            using (var s = new FileStream(p, FileMode.Open, FileAccess.Read)){}
        }
        catch (IOException)
        {
            return true;
        }
        return false;
    }

I'm testing using a .log file (just a text file) that I've got open in Baretail. The method always returns false regardless of whether or not the file is open. I tried opening it in Notepad, and it still returns false.

Basically, the end objective is to give focus to the application that has the file open, or launch the application/file if it's not already open. But this is always false so it just goes on and launches a new instance of Baretail with the file open.

Also tried the top solution found here; Is there a way to check if a file is in use?

Community
  • 1
  • 1
sab669
  • 3,984
  • 8
  • 38
  • 75

2 Answers2

3

Notepad is a bad test application because it does not hold a lock open on the file. It streams in the file and closes the lock. Use Word to do the test and you will see different results. A file is only locked if a handle is kept open by an application. Word will lock files. The same holds true for "Baretail".

In other words, if "Baretail" streams the file in and closes the lock then this test will not work. You could do something hacky such as sniff around Win32 objects...window handles and title bars to extract the information...but be warned this kind of UI hacking is tricky and I would not consider the information to be reliable. There's no stopping some other program from using similar text in their title bars per se.

P.Brian.Mackey
  • 43,228
  • 68
  • 238
  • 348
  • Hmm, very interesting. Is that why when I open a Word file I usually see a "hidden" icon pop up in the folder that goes away when I close the file? But anyways, unfortunately since my users might all have varying default applications for a .log file (Notepad, Notepad++, Baretail etc) I guess there really is no reliable way to do this. – sab669 Nov 19 '13 at 21:17
  • 1
    I *think* that is a temp file for data recovery and unrelated to the file locks. But on second thought you may be right. Anyways, I recommend re-thinking the problem. Consider why you need to lock the file in the first place? Is there a design decision that you could re-hash? – P.Brian.Mackey Nov 19 '13 at 21:20
1

I believe that that method is always returning false because you are opening for read. Even if the file is open for write elsewhere, you should be able to read that file (thus no exception is thrown).

Try using a different FileAccess opetion ie

FileAccess.ReadWrite

Or you can also try different combinations of FileMode and FileOption. (Sorry not in front of a dev machine at this point)

theMothaShip
  • 1,191
  • 1
  • 12
  • 24
  • Just edited my post to include a link on a similar topic, where a solution uses FileAccess.ReadWrite but it still behaves the same. – sab669 Nov 19 '13 at 21:03
  • @sab669 Interesting... Maybe it is best that rather than trying to see if the file is locked, that you try to identify whether the file is open in baretail? Or you could somehow get the information on who has a handle to that file and then if no handle exists open baretail? – theMothaShip Nov 19 '13 at 21:09