views:

93

answers:

3

Case and point: I need to open an Excel file via Interop and it would help a lot to avoid ugly COM errors if I knew that the file was in use.

Other than trying to open the file and catching the exception, is there a programmatic way to determine whether the file is in use?

+2  A: 

You will need to use the Win32 API fileopen (CreateFile or lopen) for exclusive access and check the return value.

Mitch Wheat
I wonder will the overhead of processing the Win32 error codes negate the benefit of not using the try/catch method?
David Relihan
A: 

Whatever method you use, Nothing garanties that between your call and actually opening the File that another process hasn't opened the file.

Some pseudo code:

internal File OpenExcelFile(String fileName)
{
    File file = null;
    var fileOpened = SomeLibrary.IsFileOpened(fileName);

    if (!fileOpened)
    {
       // Nothing garanties that another process didnt grabbed the file between call and that the file is still closed!!!
       file = ExcelLibrary.OpenFile(fileName);
    }

    return file;
}
davidwatercamp
A: 

Its worse then that. Not only do you need to catch an exception, you have to use reflection to disambiguate it from other errors. At least, thats the only solution I found.

        try
        {
            using (StreamWriter sw = new StreamWriter(filepath, false))
            {
                sw.Write(contents);
            }
        }
        catch (System.IO.IOException exception)
        {
            if (!FileUtil.IsExceptionSharingViolation(exception))
                throw;
        }

...

    public static bool IsExceptionSharingViolation(IOException exception)
    {
        Type type = typeof(Exception);

        PropertyInfo pinfo = type.GetProperty("HResult", BindingFlags.NonPublic | BindingFlags.Instance);

        uint hresult = (uint)(int)pinfo.GetValue(exception, null);

        //ERROR_SHARING_VIOLATION = 32
        //being an HRESULT adds the 0x8007

        return hresult == 0x80070020;
    }
Frank Schwieterman